splitting mmsystem and winmm
Eric Pouech
eric.pouech at wanadoo.fr
Wed Oct 9 15:38:08 CDT 2002
this patch starts splitting the 16 bit code out of the winmm DLL
it's not finished yet. most of the entry points are done, but the driver
loading & managing part remains to be splitted
A+
-------------- next part --------------
Name: mm1632
ChangeLog: started putting all 16 bit code in separate files
License: X11
GenDate: 2002/10/09 20:19:02 UTC
ModifiedFiles: dlls/winmm/Makefile.in dlls/winmm/mci.c dlls/winmm/mmsystem.c dlls/winmm/winemm.h
AddedFiles: dlls/winmm/playsound.c dlls/winmm/winmm.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/Makefile.in,v
retrieving revision 1.26
diff -u -u -r1.26 Makefile.in
--- dlls/winmm/Makefile.in 2 Oct 2002 02:34:10 -0000 1.26
+++ dlls/winmm/Makefile.in 9 Oct 2002 19:33:21 -0000
@@ -16,10 +16,12 @@
lolvldrv.c \
mci.c \
mmio.c \
- mmsystem.c \
- time.c
+ playsound.c \
+ time.c \
+ winmm.c
C_SRCS16 = \
+ mmsystem.c \
sound16.c
RC_SRCS = winmm_res.rc
Index: dlls/winmm/mci.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/mci.c,v
retrieving revision 1.32
diff -u -u -r1.32 mci.c
--- dlls/winmm/mci.c 6 Sep 2002 19:41:18 -0000 1.32
+++ dlls/winmm/mci.c 9 Oct 2002 20:18:24 -0000
@@ -2318,14 +2341,14 @@
TRACE("wDevID=%04X wDeviceID=%d dwRet=%ld\n", wmd->wDeviceID, lpParms->wDeviceID, dwRet);
if (dwParam & MCI_NOTIFY)
- mciDriverNotify16(lpParms->dwCallback, wmd->wDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ mciDriverNotify(lpParms->dwCallback, wmd->wDeviceID, MCI_NOTIFY_SUCCESSFUL);
return 0;
errCleanUp:
if (wmd) MCI_UnLoadMciDriver(iData, wmd);
if (dwParam & MCI_NOTIFY)
- mciDriverNotify16(lpParms->dwCallback, 0, MCI_NOTIFY_FAILURE);
+ mciDriverNotify(lpParms->dwCallback, 0, MCI_NOTIFY_FAILURE);
return dwRet;
}
@@ -2366,8 +2389,8 @@
MCI_UnLoadMciDriver(iData, wmd);
if (dwParam & MCI_NOTIFY)
- mciDriverNotify16(lpParms->dwCallback, wDevID,
- (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
+ mciDriverNotify(lpParms->dwCallback, wDevID,
+ (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
return dwRet;
}
@@ -2490,8 +2513,8 @@
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (dwFlags & MCI_NOTIFY)
- mciDriverNotify16(lpParms->dwCallback, wDevID,
- (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
+ mciDriverNotify(lpParms->dwCallback, wDevID,
+ (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
return dwRet;
}
Index: dlls/winmm/mmsystem.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/mmsystem.c,v
retrieving revision 1.70
diff -u -u -r1.70 mmsystem.c
--- dlls/winmm/mmsystem.c 7 Oct 2002 18:22:41 -0000 1.70
+++ dlls/winmm/mmsystem.c 9 Oct 2002 20:15:35 -0000
@@ -3,7 +3,8 @@
/*
* MMSYTEM functions
*
- * Copyright 1993 Martin Ayotte
+ * Copyright 1993 Martin Ayotte
+ * 1998-2002 Eric Pouech
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,10 +23,7 @@
/*
* Eric POUECH :
- * 98/9 added Win32 MCI support
* 99/4 added mmTask and mmThread functions support
- * added midiStream support
- * 99/9 added support for loadable low level drivers
*/
/* FIXME: I think there are some segmented vs. linear pointer weirdnesses
@@ -36,125 +34,15 @@
#include "mmsystem.h"
#include "winbase.h"
-#include "wingdi.h"
#include "wine/mmsystem16.h"
#include "wine/winuser16.h"
-#include "heap.h"
-#include "winternl.h"
#include "winemm.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(mmsys);
-static LPWINE_MM_IDATA lpFirstIData = NULL;
-
-static LPWINE_MM_IDATA MULTIMEDIA_GetIDataNoCheck(void)
-{
- DWORD pid = GetCurrentProcessId();
- LPWINE_MM_IDATA iData;
-
- for (iData = lpFirstIData; iData; iData = iData->lpNextIData) {
- if (iData->dwThisProcess == pid)
- break;
- }
- return iData;
-}
-
-/**************************************************************************
- * MULTIMEDIA_GetIData [internal]
- */
-LPWINE_MM_IDATA MULTIMEDIA_GetIData(void)
-{
- LPWINE_MM_IDATA iData = MULTIMEDIA_GetIDataNoCheck();
-
- if (!iData) {
- ERR("IData not found for pid=%08lx. Suicide !!!\n", GetCurrentProcessId());
- DbgBreakPoint();
- ExitProcess(0);
- }
- return iData;
-}
-
-/**************************************************************************
- * MULTIMEDIA_CreateIData [internal]
- */
-static BOOL MULTIMEDIA_CreateIData(HINSTANCE hInstDLL)
-{
- LPWINE_MM_IDATA iData;
-
- iData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MM_IDATA));
-
- if (!iData)
- return FALSE;
- iData->hWinMM32Instance = hInstDLL;
- iData->dwThisProcess = GetCurrentProcessId();
- iData->lpNextIData = lpFirstIData;
- lpFirstIData = iData;
- InitializeCriticalSection(&iData->cs);
- iData->cs.DebugInfo = (void*)__FILE__ ": WinMM";
- iData->psStopEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
- iData->psLastEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
- TRACE("Created IData (%p) for pid %08lx\n", iData, iData->dwThisProcess);
- return TRUE;
-}
-
-/**************************************************************************
- * MULTIMEDIA_DeleteIData [internal]
- */
-static void MULTIMEDIA_DeleteIData(void)
-{
- LPWINE_MM_IDATA iData = MULTIMEDIA_GetIDataNoCheck();
- LPWINE_MM_IDATA* ppid;
-
- if (iData) {
- TIME_MMTimeStop();
-
- for (ppid = &lpFirstIData; *ppid; ppid = &(*ppid)->lpNextIData) {
- if (*ppid == iData) {
- *ppid = iData->lpNextIData;
- break;
- }
- }
- /* FIXME: should also free content and resources allocated
- * inside iData */
- CloseHandle(iData->psStopEvent);
- CloseHandle(iData->psLastEvent);
- DeleteCriticalSection(&iData->cs);
- HeapFree(GetProcessHeap(), 0, iData);
- }
-}
-
-/**************************************************************************
- * DllEntryPoint (WINMM.init)
- *
- * WINMM DLL entry point
- *
- */
-BOOL WINAPI WINMM_LibMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
-{
- TRACE("0x%x 0x%lx %p\n", hInstDLL, fdwReason, fImpLoad);
-
- switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
- if (!MULTIMEDIA_CreateIData(hInstDLL))
- return FALSE;
- if (!MULTIMEDIA_MciInit() || !MMDRV_Init()) {
- MULTIMEDIA_DeleteIData();
- return FALSE;
- }
- break;
- case DLL_PROCESS_DETACH:
- MULTIMEDIA_DeleteIData();
- break;
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- break;
- }
- return TRUE;
-}
-
/**************************************************************************
* DllEntryPoint (MMSYSTEM.2046)
*
@@ -206,471 +94,6 @@
return TRUE;
}
-void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32)
-{
- mmt16->wType = mmt32->wType;
- /* layout of rest is the same for 32/16,
- * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
- */
- memcpy(&(mmt16->u), &(mmt32->u), sizeof(mmt16->u));
-}
-
-void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16)
-{
- mmt32->wType = mmt16->wType;
- /* layout of rest is the same for 32/16,
- * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
- */
- memcpy(&(mmt32->u), &(mmt16->u), sizeof(mmt16->u));
-}
-
-static HMMIO get_mmioFromFile(LPCWSTR lpszName)
-{
- HMMIO ret;
- WCHAR buf[256];
- LPWSTR dummy;
-
- ret = mmioOpenW((LPWSTR)lpszName, NULL,
- MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
- if (ret != 0) return ret;
- if (SearchPathW(NULL, lpszName, NULL, sizeof(buf)/sizeof(buf[0]), buf, &dummy))
- {
- return mmioOpenW(buf, NULL,
- MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
- }
- return 0;
-}
-
-static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)
-{
- WCHAR str[128];
- LPWSTR ptr;
- HMMIO hmmio;
- HKEY hRegSnd, hRegApp, hScheme, hSnd;
- DWORD err, type, count;
-
- static WCHAR wszSounds[] = {'S','o','u','n','d','s',0};
- static WCHAR wszDefault[] = {'D','e','f','a','u','l','t',0};
- static WCHAR wszKey[] = {'A','p','p','E','v','e','n','t','s','\\',
- 'S','c','h','e','m','e','s','\\',
- 'A','p','p','s',0};
- static WCHAR wszDotDefault[] = {'.','D','e','f','a','u','l','t',0};
- static WCHAR wszNull[] = {0};
-
- TRACE("searching in SystemSound list for %s\n", debugstr_w(lpszName));
- GetProfileStringW(wszSounds, (LPWSTR)lpszName, wszNull, str, sizeof(str)/sizeof(str[0]));
- if (lstrlenW(str) == 0)
- {
- if (uFlags & SND_NODEFAULT) goto next;
- GetProfileStringW(wszSounds, wszDefault, wszNull, str, sizeof(str)/sizeof(str[0]));
- if (lstrlenW(str) == 0) goto next;
- }
- for (ptr = str; *ptr && *ptr != ','; ptr++);
- if (*ptr) *ptr = 0;
- hmmio = mmioOpenW(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
- if (hmmio != 0) return hmmio;
- next:
- /* we look up the registry under
- * HKCU\AppEvents\Schemes\Apps\.Default
- * HKCU\AppEvents\Schemes\Apps\<AppName>
- */
- if (RegOpenKeyW(HKEY_CURRENT_USER, wszKey, &hRegSnd) != 0) goto none;
- if (uFlags & SND_APPLICATION)
- {
- err = 1; /* error */
- if (GetModuleFileNameW(0, str, sizeof(str)/sizeof(str[0])))
- {
- for (ptr = str + lstrlenW(str) - 1; ptr >= str; ptr--)
- {
- if (*ptr == '.') *ptr = 0;
- if (*ptr == '\\')
- {
- err = RegOpenKeyW(hRegSnd, str, &hRegApp);
- break;
- }
- }
- }
- }
- else
- {
- err = RegOpenKeyW(hRegSnd, wszDotDefault, &hRegApp);
- }
- RegCloseKey(hRegSnd);
- if (err != 0) goto none;
- err = RegOpenKeyW(hRegApp, lpszName, &hScheme);
- RegCloseKey(hRegApp);
- if (err != 0) goto none;
- err = RegOpenKeyW(hScheme, wszDotDefault, &hSnd);
- RegCloseKey(hScheme);
- if (err != 0) goto none;
- count = sizeof(str)/sizeof(str[0]);
- err = RegQueryValueExW(hSnd, NULL, 0, &type, (LPBYTE)str, &count);
- RegCloseKey(hSnd);
- if (err != 0 || !*str) goto none;
- hmmio = mmioOpenW(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
- if (hmmio) return hmmio;
- none:
- WARN("can't find SystemSound='%s' !\n", debugstr_w(lpszName));
- return 0;
-}
-
-struct playsound_data
-{
- HANDLE hEvent;
- DWORD dwEventCount;
-};
-
-static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg,
- DWORD dwInstance,
- DWORD dwParam1, DWORD dwParam2)
-{
- struct playsound_data* s = (struct playsound_data*)dwInstance;
-
- switch (uMsg) {
- case WOM_OPEN:
- case WOM_CLOSE:
- break;
- case WOM_DONE:
- InterlockedIncrement(&s->dwEventCount);
- TRACE("Returning waveHdr=%lx\n", dwParam1);
- SetEvent(s->hEvent);
- break;
- default:
- ERR("Unknown uMsg=%d\n", uMsg);
- }
-}
-
-static void PlaySound_WaitDone(struct playsound_data* s)
-{
- for (;;) {
- ResetEvent(s->hEvent);
- if (InterlockedDecrement(&s->dwEventCount) >= 0) break;
- InterlockedIncrement(&s->dwEventCount);
-
- WaitForSingleObject(s->hEvent, INFINITE);
- }
-}
-
-static BOOL PlaySound_IsString(DWORD fdwSound, const void* psz)
-{
- /* SND_RESOURCE is 0x40004 while
- * SND_MEMORY is 0x00004
- */
- switch (fdwSound & (SND_RESOURCE|SND_ALIAS|SND_FILENAME))
- {
- case SND_RESOURCE: return HIWORD(psz) != 0; /* by name or by ID ? */
- case SND_MEMORY: return FALSE;
- case SND_ALIAS: /* what about ALIAS_ID ??? */
- case SND_FILENAME:
- case 0: return TRUE;
- default: FIXME("WTF\n"); return FALSE;
- }
-}
-
-static void PlaySound_Free(WINE_PLAYSOUND* wps)
-{
- LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
- WINE_PLAYSOUND** p;
-
- EnterCriticalSection(&iData->cs);
- for (p = &iData->lpPlaySound; *p && *p != wps; p = &((*p)->lpNext));
- if (*p) *p = (*p)->lpNext;
- if (iData->lpPlaySound == NULL) SetEvent(iData->psLastEvent);
- LeaveCriticalSection(&iData->cs);
- if (wps->bAlloc) HeapFree(GetProcessHeap(), 0, (void*)wps->pszSound);
- HeapFree(GetProcessHeap(), 0, wps);
-}
-
-static WINE_PLAYSOUND* PlaySound_Alloc(const void* pszSound, HMODULE hmod,
- DWORD fdwSound, BOOL bUnicode)
-{
- WINE_PLAYSOUND* wps;
-
- wps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wps));
- if (!wps) return NULL;
-
- wps->hMod = hmod;
- wps->fdwSound = fdwSound;
- if (PlaySound_IsString(fdwSound, pszSound))
- {
- if (bUnicode)
- {
- if (fdwSound & SND_ASYNC)
- {
- wps->pszSound = HeapAlloc(GetProcessHeap(), 0,
- (lstrlenW(pszSound)+1) * sizeof(WCHAR));
- if (!wps->pszSound) goto oom_error;
- lstrcpyW((LPWSTR)wps->pszSound, pszSound);
- wps->bAlloc = TRUE;
- }
- else
- wps->pszSound = pszSound;
- }
- else
- {
- wps->pszSound = HEAP_strdupAtoW(GetProcessHeap(), 0, pszSound);
- if (!wps->pszSound) goto oom_error;
- wps->bAlloc = TRUE;
- }
- }
- else
- wps->pszSound = pszSound;
-
- return wps;
- oom_error:
- PlaySound_Free(wps);
- return NULL;
-}
-
-static DWORD WINAPI proc_PlaySound(LPVOID arg)
-{
- WINE_PLAYSOUND* wps = (WINE_PLAYSOUND*)arg;
- LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
- BOOL bRet = FALSE;
- HMMIO hmmio = 0;
- MMCKINFO ckMainRIFF;
- MMCKINFO mmckInfo;
- LPWAVEFORMATEX lpWaveFormat = NULL;
- HWAVEOUT hWave = 0;
- LPWAVEHDR waveHdr = NULL;
- INT count, bufsize, left, index;
- struct playsound_data s;
- void* data;
-
- s.hEvent = 0;
-
- TRACE("SoundName='%s' !\n", debugstr_w(wps->pszSound));
-
- /* if resource, grab it */
- if ((wps->fdwSound & SND_RESOURCE) == SND_RESOURCE) {
- static WCHAR wszWave[] = {'W','A','V','E',0};
- HRSRC hRes;
- HGLOBAL hGlob;
-
- if ((hRes = FindResourceW(wps->hMod, wps->pszSound, wszWave)) == 0 ||
- (hGlob = LoadResource(wps->hMod, hRes)) == 0)
- goto errCleanUp;
- if ((data = LockResource(hGlob)) == NULL) {
- FreeResource(hGlob);
- goto errCleanUp;
- }
- FreeResource(hGlob);
- } else
- data = (void*)wps->pszSound;
-
- /* construct an MMIO stream (either in memory, or from a file */
- if (wps->fdwSound & SND_MEMORY)
- { /* NOTE: SND_RESOURCE has the SND_MEMORY bit set */
- MMIOINFO mminfo;
-
- memset(&mminfo, 0, sizeof(mminfo));
- mminfo.fccIOProc = FOURCC_MEM;
- mminfo.pchBuffer = (LPSTR)data;
- mminfo.cchBuffer = -1; /* FIXME: when a resource, could grab real size */
- TRACE("Memory sound %p\n", data);
- hmmio = mmioOpenW(NULL, &mminfo, MMIO_READ);
- }
- else if (wps->fdwSound & SND_ALIAS)
- {
- hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
- }
- else if (wps->fdwSound & SND_FILENAME)
- {
- hmmio = get_mmioFromFile(wps->pszSound);
- }
- else
- {
- if ((hmmio = get_mmioFromProfile(wps->fdwSound | SND_NODEFAULT, wps->pszSound)) == 0)
- {
- if ((hmmio = get_mmioFromFile(wps->pszSound)) == 0)
- {
- hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
- }
- }
- }
- if (hmmio == 0) goto errCleanUp;
-
- if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0))
- goto errCleanUp;
-
- TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
- (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
-
- if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
- (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E')))
- goto errCleanUp;
-
- mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
- if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
- goto errCleanUp;
-
- TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
- (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
-
- lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
- if (mmioRead(hmmio, (HPSTR)lpWaveFormat, mmckInfo.cksize) < sizeof(WAVEFORMAT))
- goto errCleanUp;
-
- TRACE("wFormatTag=%04X !\n", lpWaveFormat->wFormatTag);
- TRACE("nChannels=%d \n", lpWaveFormat->nChannels);
- TRACE("nSamplesPerSec=%ld\n", lpWaveFormat->nSamplesPerSec);
- TRACE("nAvgBytesPerSec=%ld\n", lpWaveFormat->nAvgBytesPerSec);
- TRACE("nBlockAlign=%d \n", lpWaveFormat->nBlockAlign);
- TRACE("wBitsPerSample=%u !\n", lpWaveFormat->wBitsPerSample);
-
- /* move to end of 'fmt ' chunk */
- mmioAscend(hmmio, &mmckInfo, 0);
-
- mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
- if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
- goto errCleanUp;
-
- TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX\n",
- (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
-
- s.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
-
- if (waveOutOpen(&hWave, WAVE_MAPPER, lpWaveFormat, (DWORD)PlaySound_Callback,
- (DWORD)&s, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
- goto errCleanUp;
-
- /* make it so that 3 buffers per second are needed */
- bufsize = (((lpWaveFormat->nAvgBytesPerSec / 3) - 1) / lpWaveFormat->nBlockAlign + 1) *
- lpWaveFormat->nBlockAlign;
- waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize);
- waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
- waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
- waveHdr[0].dwUser = waveHdr[1].dwUser = 0L;
- waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
- waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
- waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
- if (waveOutPrepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
- waveOutPrepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR))) {
- goto errCleanUp;
- }
-
- s.dwEventCount = 1L; /* for first buffer */
-
- do {
- index = 0;
- left = mmckInfo.cksize;
-
- mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET);
- while (left)
- {
- if (WaitForSingleObject(iData->psStopEvent, 0) == WAIT_OBJECT_0)
- {
- wps->bLoop = FALSE;
- break;
- }
- count = mmioRead(hmmio, waveHdr[index].lpData, min(bufsize, left));
- if (count < 1) break;
- left -= count;
- waveHdr[index].dwBufferLength = count;
- waveHdr[index].dwFlags &= ~WHDR_DONE;
- if (waveOutWrite(hWave, &waveHdr[index], sizeof(WAVEHDR)) == MMSYSERR_NOERROR) {
- index ^= 1;
- PlaySound_WaitDone(&s);
- }
- else FIXME("Couldn't play header\n");
- }
- bRet = TRUE;
- } while (wps->bLoop);
-
- PlaySound_WaitDone(&s); /* for last buffer */
- waveOutReset(hWave);
-
- waveOutUnprepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR));
- waveOutUnprepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR));
-
-errCleanUp:
- TRACE("Done playing='%s' => %s!\n", debugstr_w(wps->pszSound), bRet ? "ok" : "ko");
- CloseHandle(s.hEvent);
- if (waveHdr) HeapFree(GetProcessHeap(), 0, waveHdr);
- if (lpWaveFormat) HeapFree(GetProcessHeap(), 0, lpWaveFormat);
- if (hWave) while (waveOutClose(hWave) == WAVERR_STILLPLAYING) Sleep(100);
- if (hmmio) mmioClose(hmmio, 0);
-
- PlaySound_Free(wps);
-
- return bRet;
-}
-
-static BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
-{
- WINE_PLAYSOUND* wps = NULL;
- LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
-
- TRACE("pszSound='%p' hmod=%04X fdwSound=%08lX\n",
- pszSound, hmod, fdwSound);
-
- /* FIXME? I see no difference between SND_NOWAIT and SND_NOSTOP !
- * there could be one if several sounds can be played at once...
- */
- if ((fdwSound & (SND_NOWAIT | SND_NOSTOP)) && iData->lpPlaySound != NULL)
- return FALSE;
-
- /* alloc internal structure, if we need to play something */
- if (pszSound && !(fdwSound & SND_PURGE))
- {
- if (!(wps = PlaySound_Alloc(pszSound, hmod, fdwSound, bUnicode)))
- return FALSE;
- }
-
- EnterCriticalSection(&iData->cs);
- /* since several threads can enter PlaySound in parallel, we're not
- * sure, at this point, that another thread didn't start a new playsound
- */
- while (iData->lpPlaySound != NULL)
- {
- ResetEvent(iData->psLastEvent);
- /* FIXME: doc says we have to stop all instances of pszSound if it's non
- * NULL... as of today, we stop all playing instances */
- SetEvent(iData->psStopEvent);
-
- LeaveCriticalSection(&iData->cs);
- WaitForSingleObject(iData->psLastEvent, INFINITE);
- EnterCriticalSection(&iData->cs);
-
- ResetEvent(iData->psStopEvent);
- }
-
- if (wps) wps->lpNext = iData->lpPlaySound;
- iData->lpPlaySound = wps;
- LeaveCriticalSection(&iData->cs);
-
- if (!pszSound || (fdwSound & SND_PURGE)) return TRUE;
-
- if (fdwSound & SND_ASYNC)
- {
- DWORD id;
- wps->bLoop = (fdwSound & SND_LOOP) ? TRUE : FALSE;
- if (CreateThread(NULL, 0, proc_PlaySound, wps, 0, &id) != 0)
- return TRUE;
- }
- else return proc_PlaySound(wps);
-
- /* error cases */
- PlaySound_Free(wps);
- return FALSE;
-}
-
-/**************************************************************************
- * PlaySoundA [WINMM.@]
- */
-BOOL WINAPI PlaySoundA(LPCSTR pszSoundA, HMODULE hmod, DWORD fdwSound)
-{
- return MULTIMEDIA_PlaySound(pszSoundA, hmod, fdwSound, FALSE);
-}
-
-/**************************************************************************
- * PlaySoundW [WINMM.@]
- */
-BOOL WINAPI PlaySoundW(LPCWSTR pszSoundW, HMODULE hmod, DWORD fdwSound)
-{
- return MULTIMEDIA_PlaySound(pszSoundW, hmod, fdwSound, TRUE);
-}
-
/**************************************************************************
* PlaySound [MMSYSTEM.3]
*/
@@ -687,24 +110,6 @@
}
/**************************************************************************
- * sndPlaySoundA [WINMM.@]
- */
-BOOL WINAPI sndPlaySoundA(LPCSTR pszSoundA, UINT uFlags)
-{
- uFlags &= SND_ASYNC|SND_LOOP|SND_MEMORY|SND_NODEFAULT|SND_NOSTOP|SND_SYNC;
- return MULTIMEDIA_PlaySound(pszSoundA, 0, uFlags, FALSE);
-}
-
-/**************************************************************************
- * sndPlaySoundW [WINMM.@]
- */
-BOOL WINAPI sndPlaySoundW(LPCWSTR pszSound, UINT uFlags)
-{
- uFlags &= SND_ASYNC|SND_LOOP|SND_MEMORY|SND_NODEFAULT|SND_NOSTOP|SND_SYNC;
- return MULTIMEDIA_PlaySound(pszSound, 0, uFlags, TRUE);
-}
-
-/**************************************************************************
* sndPlaySound [MMSYSTEM.2]
*/
BOOL16 WINAPI sndPlaySound16(LPCSTR lpszSoundName, UINT16 uFlags)
@@ -721,7 +126,7 @@
/**************************************************************************
* mmsystemGetVersion [MMSYSTEM.5]
- * return value borrowed from Win95 winmm.dll ;)
+ *
*/
UINT16 WINAPI mmsystemGetVersion16(void)
{
@@ -729,75 +134,6 @@
}
/**************************************************************************
- * mmsystemGetVersion [WINMM.@]
- */
-UINT WINAPI mmsystemGetVersion(void)
-{
- TRACE("3.10 (Win95?)\n");
- return 0x030a;
-}
-
-/**************************************************************************
- * DriverCallback [WINMM.@]
- */
-BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev,
- UINT wMsg, DWORD dwUser, DWORD dwParam1,
- DWORD dwParam2)
-{
- TRACE("(%08lX, %04X, %04X, %04X, %08lX, %08lX, %08lX); !\n",
- dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
-
- switch (uFlags & DCB_TYPEMASK) {
- case DCB_NULL:
- TRACE("Null !\n");
- if (dwCallBack)
- WARN("uFlags=%04X has null DCB value, but dwCallBack=%08lX is not null !\n", uFlags, dwCallBack);
- break;
- case DCB_WINDOW:
- TRACE("Window(%04lX) handle=%04X!\n", dwCallBack, hDev);
- PostMessageA((HWND)dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
- break;
- case DCB_TASK: /* aka DCB_THREAD */
- TRACE("Task(%04lx) !\n", dwCallBack);
- PostThreadMessageA(dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
- break;
- case DCB_FUNCTION:
- TRACE("Function (32 bit) !\n");
- ((LPDRVCALLBACK)dwCallBack)(hDev, wMsg, dwUser, dwParam1, dwParam2);
- break;
- case DCB_EVENT:
- TRACE("Event(%08lx) !\n", dwCallBack);
- SetEvent((HANDLE)dwCallBack);
- break;
- case 6: /* I would dub it DCB_MMTHREADSIGNAL */
- /* this is an undocumented DCB_ value used for mmThreads
- * loword of dwCallBack contains the handle of the lpMMThd block
- * which dwSignalCount has to be incremented
- */
- {
- WINE_MMTHREAD* lpMMThd = MapSL( MAKESEGPTR(LOWORD(dwCallBack), 0) );
-
- TRACE("mmThread (%04x, %p) !\n", LOWORD(dwCallBack), lpMMThd);
- /* same as mmThreadSignal16 */
- InterlockedIncrement(&lpMMThd->dwSignalCount);
- SetEvent(lpMMThd->hEvent);
- /* some other stuff on lpMMThd->hVxD */
- }
- break;
-#if 0
- case 4:
- /* this is an undocumented DCB_ value for... I don't know */
- break;
-#endif
- default:
- WARN("Unknown callback type %d\n", uFlags & DCB_TYPEMASK);
- return FALSE;
- }
- TRACE("Done\n");
- return TRUE;
-}
-
-/**************************************************************************
* DriverCallback [MMSYSTEM.31]
*/
BOOL16 WINAPI DriverCallback16(DWORD dwCallBack, UINT16 uFlags, HDRVR16 hDev,
@@ -812,62 +148,6 @@
*/
/**************************************************************************
- * find out the real mixer ID depending on hmix (depends on dwFlags)
- */
-static LPWINE_MIXER MIXER_GetDev(HMIXEROBJ hmix, DWORD dwFlags)
-{
- LPWINE_MIXER lpwm = NULL;
-
- switch (dwFlags & 0xF0000000ul) {
- case MIXER_OBJECTF_MIXER:
- lpwm = (LPWINE_MIXER)MMDRV_Get(hmix, MMDRV_MIXER, TRUE);
- break;
- case MIXER_OBJECTF_HMIXER:
- lpwm = (LPWINE_MIXER)MMDRV_Get(hmix, MMDRV_MIXER, FALSE);
- break;
- case MIXER_OBJECTF_WAVEOUT:
- lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_WAVEOUT, TRUE, MMDRV_MIXER);
- break;
- case MIXER_OBJECTF_HWAVEOUT:
- lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_WAVEOUT, FALSE, MMDRV_MIXER);
- break;
- case MIXER_OBJECTF_WAVEIN:
- lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_WAVEIN, TRUE, MMDRV_MIXER);
- break;
- case MIXER_OBJECTF_HWAVEIN:
- lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_WAVEIN, FALSE, MMDRV_MIXER);
- break;
- case MIXER_OBJECTF_MIDIOUT:
- lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_MIDIOUT, TRUE, MMDRV_MIXER);
- break;
- case MIXER_OBJECTF_HMIDIOUT:
- lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_MIDIOUT, FALSE, MMDRV_MIXER);
- break;
- case MIXER_OBJECTF_MIDIIN:
- lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_MIDIIN, TRUE, MMDRV_MIXER);
- break;
- case MIXER_OBJECTF_HMIDIIN:
- lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_MIDIIN, FALSE, MMDRV_MIXER);
- break;
- case MIXER_OBJECTF_AUX:
- lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_AUX, TRUE, MMDRV_MIXER);
- break;
- default:
- FIXME("Unsupported flag (%08lx)\n", dwFlags & 0xF0000000ul);
- break;
- }
- return lpwm;
-}
-
-/**************************************************************************
- * mixerGetNumDevs [WINMM.@]
- */
-UINT WINAPI mixerGetNumDevs(void)
-{
- return MMDRV_GetNum(MMDRV_MIXER);
-}
-
-/**************************************************************************
* mixerGetNumDevs [MMSYSTEM.800]
*/
UINT16 WINAPI mixerGetNumDevs16(void)
@@ -876,39 +156,6 @@
}
/**************************************************************************
- * mixerGetDevCapsA [WINMM.@]
- */
-UINT WINAPI mixerGetDevCapsA(UINT devid, LPMIXERCAPSA mixcaps, UINT size)
-{
- LPWINE_MLD wmld;
-
- if ((wmld = MMDRV_Get(devid, MMDRV_MIXER, TRUE)) == NULL)
- return MMSYSERR_BADDEVICEID;
-
- return MMDRV_Message(wmld, MXDM_GETDEVCAPS, (DWORD)mixcaps, size, TRUE);
-}
-
-/**************************************************************************
- * mixerGetDevCapsW [WINMM.@]
- */
-UINT WINAPI mixerGetDevCapsW(UINT devid, LPMIXERCAPSW mixcaps, UINT size)
-{
- MIXERCAPSA micA;
- UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
-
- if (ret == MMSYSERR_NOERROR) {
- mixcaps->wMid = micA.wMid;
- mixcaps->wPid = micA.wPid;
- mixcaps->vDriverVersion = micA.vDriverVersion;
- MultiByteToWideChar( CP_ACP, 0, micA.szPname, -1, mixcaps->szPname,
- sizeof(mixcaps->szPname)/sizeof(WCHAR) );
- mixcaps->fdwSupport = micA.fdwSupport;
- mixcaps->cDestinations = micA.cDestinations;
- }
- return ret;
-}
-
-/**************************************************************************
* mixerGetDevCaps [MMSYSTEM.801]
*/
UINT16 WINAPI mixerGetDevCaps16(UINT16 devid, LPMIXERCAPS16 mixcaps,
@@ -928,47 +175,6 @@
return ret;
}
-static UINT MMSYSTEM_mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD dwCallback,
- DWORD dwInstance, DWORD fdwOpen, BOOL bFrom32)
-{
- HMIXER hMix;
- LPWINE_MLD wmld;
- DWORD dwRet = 0;
- MIXEROPENDESC mod;
-
- TRACE("(%p, %d, %08lx, %08lx, %08lx)\n",
- lphMix, uDeviceID, dwCallback, dwInstance, fdwOpen);
-
- wmld = MMDRV_Alloc(sizeof(WINE_MIXER), MMDRV_MIXER, &hMix, &fdwOpen,
- &dwCallback, &dwInstance, bFrom32);
-
- wmld->uDeviceID = uDeviceID;
- mod.hmx = (HMIXEROBJ)hMix;
- mod.dwCallback = dwCallback;
- mod.dwInstance = dwInstance;
-
- dwRet = MMDRV_Open(wmld, MXDM_OPEN, (DWORD)&mod, fdwOpen);
-
- if (dwRet != MMSYSERR_NOERROR) {
- MMDRV_Free(hMix, wmld);
- hMix = 0;
- }
- if (lphMix) *lphMix = hMix;
- TRACE("=> %ld hMixer=%04x\n", dwRet, hMix);
-
- return dwRet;
-}
-
-/**************************************************************************
- * mixerOpen [WINMM.@]
- */
-UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD dwCallback,
- DWORD dwInstance, DWORD fdwOpen)
-{
- return MMSYSTEM_mixerOpen(lphMix, uDeviceID,
- dwCallback, dwInstance, fdwOpen, TRUE);
-}
-
/**************************************************************************
* mixerOpen [MMSYSTEM.802]
*/
@@ -985,24 +191,6 @@
}
/**************************************************************************
- * mixerClose [WINMM.@]
- */
-UINT WINAPI mixerClose(HMIXER hMix)
-{
- LPWINE_MLD wmld;
- DWORD dwRet;
-
- TRACE("(%04x)\n", hMix);
-
- if ((wmld = MMDRV_Get(hMix, MMDRV_MIXER, FALSE)) == NULL) return MMSYSERR_INVALHANDLE;
-
- dwRet = MMDRV_Close(wmld, MXDM_CLOSE);
- MMDRV_Free(hMix, wmld);
-
- return dwRet;
-}
-
-/**************************************************************************
* mixerClose [MMSYSTEM.803]
*/
UINT16 WINAPI mixerClose16(HMIXER16 hMix)
@@ -1011,26 +199,7 @@
}
/**************************************************************************
- * mixerGetID [WINMM.@]
- */
-UINT WINAPI mixerGetID(HMIXEROBJ hmix, LPUINT lpid, DWORD fdwID)
-{
- LPWINE_MIXER lpwm;
-
- TRACE("(%04x %p %08lx)\n", hmix, lpid, fdwID);
-
- if ((lpwm = MIXER_GetDev(hmix, fdwID)) == NULL) {
- return MMSYSERR_INVALHANDLE;
- }
-
- if (lpid)
- *lpid = lpwm->mld.uDeviceID;
-
- return MMSYSERR_NOERROR;
-}
-
-/**************************************************************************
- * mixerGetID (MMSYSTEM.806)
+ * mixerGetID (MMSYSTEM.806)
*/
UINT16 WINAPI mixerGetID16(HMIXEROBJ16 hmix, LPUINT16 lpid, DWORD fdwID)
{
@@ -1043,84 +212,6 @@
}
/**************************************************************************
- * mixerGetControlDetailsA [WINMM.@]
- */
-UINT WINAPI mixerGetControlDetailsA(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdA,
- DWORD fdwDetails)
-{
- LPWINE_MIXER lpwm;
-
- TRACE("(%04x, %p, %08lx)\n", hmix, lpmcdA, fdwDetails);
-
- if ((lpwm = MIXER_GetDev(hmix, fdwDetails)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- if (lpmcdA == NULL || lpmcdA->cbStruct != sizeof(*lpmcdA))
- return MMSYSERR_INVALPARAM;
-
- return MMDRV_Message(&lpwm->mld, MXDM_GETCONTROLDETAILS, (DWORD)lpmcdA,
- fdwDetails, TRUE);
-}
-
-/**************************************************************************
- * mixerGetControlDetailsW [WINMM.@]
- */
-UINT WINAPI mixerGetControlDetailsW(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcd, DWORD fdwDetails)
-{
- DWORD ret = MMSYSERR_NOTENABLED;
-
- TRACE("(%04x, %p, %08lx)\n", hmix, lpmcd, fdwDetails);
-
- if (lpmcd == NULL || lpmcd->cbStruct != sizeof(*lpmcd))
- return MMSYSERR_INVALPARAM;
-
- switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
- case MIXER_GETCONTROLDETAILSF_VALUE:
- /* can savely use W structure as it is, no string inside */
- ret = mixerGetControlDetailsA(hmix, lpmcd, fdwDetails);
- break;
- case MIXER_GETCONTROLDETAILSF_LISTTEXT:
- {
- MIXERCONTROLDETAILS_LISTTEXTW *pDetailsW = (MIXERCONTROLDETAILS_LISTTEXTW *)lpmcd->paDetails;
- MIXERCONTROLDETAILS_LISTTEXTA *pDetailsA;
- int size = max(1, lpmcd->cChannels) * sizeof(MIXERCONTROLDETAILS_LISTTEXTA);
- int i;
-
- if (lpmcd->u.cMultipleItems != 0) {
- size *= lpmcd->u.cMultipleItems;
- }
- pDetailsA = (MIXERCONTROLDETAILS_LISTTEXTA *)HeapAlloc(GetProcessHeap(), 0, size);
- lpmcd->paDetails = pDetailsA;
- lpmcd->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTA);
- /* set up lpmcd->paDetails */
- ret = mixerGetControlDetailsA(hmix, lpmcd, fdwDetails);
- /* copy from lpmcd->paDetails back to paDetailsW; */
- if(ret == MMSYSERR_NOERROR) {
- for(i=0;i<lpmcd->u.cMultipleItems*lpmcd->cChannels;i++) {
- pDetailsW->dwParam1 = pDetailsA->dwParam1;
- pDetailsW->dwParam2 = pDetailsA->dwParam2;
- MultiByteToWideChar( CP_ACP, 0, pDetailsA->szName, -1,
- pDetailsW->szName,
- sizeof(pDetailsW->szName)/sizeof(WCHAR) );
- pDetailsA++;
- pDetailsW++;
- }
- pDetailsA -= lpmcd->u.cMultipleItems*lpmcd->cChannels;
- pDetailsW -= lpmcd->u.cMultipleItems*lpmcd->cChannels;
- }
- HeapFree(GetProcessHeap(), 0, pDetailsA);
- lpmcd->paDetails = pDetailsW;
- lpmcd->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTW);
- }
- break;
- default:
- ERR("Unsupported fdwDetails=0x%08lx\n", fdwDetails);
- }
-
- return ret;
-}
-
-/**************************************************************************
* mixerGetControlDetails [MMSYSTEM.808]
*/
UINT16 WINAPI mixerGetControlDetails16(HMIXEROBJ16 hmix,
@@ -1145,87 +236,6 @@
}
/**************************************************************************
- * mixerGetLineControlsA [WINMM.@]
- */
-UINT WINAPI mixerGetLineControlsA(HMIXEROBJ hmix, LPMIXERLINECONTROLSA lpmlcA,
- DWORD fdwControls)
-{
- LPWINE_MIXER lpwm;
-
- TRACE("(%04x, %p, %08lx)\n", hmix, lpmlcA, fdwControls);
-
- if ((lpwm = MIXER_GetDev(hmix, fdwControls)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- if (lpmlcA == NULL || lpmlcA->cbStruct != sizeof(*lpmlcA))
- return MMSYSERR_INVALPARAM;
-
- return MMDRV_Message(&lpwm->mld, MXDM_GETLINECONTROLS, (DWORD)lpmlcA,
- fdwControls, TRUE);
-}
-
-/**************************************************************************
- * mixerGetLineControlsW [WINMM.@]
- */
-UINT WINAPI mixerGetLineControlsW(HMIXEROBJ hmix, LPMIXERLINECONTROLSW lpmlcW,
- DWORD fdwControls)
-{
- MIXERLINECONTROLSA mlcA;
- DWORD ret;
- int i;
-
- TRACE("(%04x, %p, %08lx)\n", hmix, lpmlcW, fdwControls);
-
- if (lpmlcW == NULL || lpmlcW->cbStruct != sizeof(*lpmlcW) ||
- lpmlcW->cbmxctrl != sizeof(MIXERCONTROLW))
- return MMSYSERR_INVALPARAM;
-
- mlcA.cbStruct = sizeof(mlcA);
- mlcA.dwLineID = lpmlcW->dwLineID;
- mlcA.u.dwControlID = lpmlcW->u.dwControlID;
- mlcA.u.dwControlType = lpmlcW->u.dwControlType;
- mlcA.cControls = lpmlcW->cControls;
- mlcA.cbmxctrl = sizeof(MIXERCONTROLA);
- mlcA.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
- mlcA.cControls * mlcA.cbmxctrl);
-
- ret = mixerGetLineControlsA(hmix, &mlcA, fdwControls);
-
- if (ret == MMSYSERR_NOERROR) {
- lpmlcW->dwLineID = mlcA.dwLineID;
- lpmlcW->u.dwControlID = mlcA.u.dwControlID;
- lpmlcW->u.dwControlType = mlcA.u.dwControlType;
- lpmlcW->cControls = mlcA.cControls;
-
- for (i = 0; i < mlcA.cControls; i++) {
- lpmlcW->pamxctrl[i].cbStruct = sizeof(MIXERCONTROLW);
- lpmlcW->pamxctrl[i].dwControlID = mlcA.pamxctrl[i].dwControlID;
- lpmlcW->pamxctrl[i].dwControlType = mlcA.pamxctrl[i].dwControlType;
- lpmlcW->pamxctrl[i].fdwControl = mlcA.pamxctrl[i].fdwControl;
- lpmlcW->pamxctrl[i].cMultipleItems = mlcA.pamxctrl[i].cMultipleItems;
- MultiByteToWideChar( CP_ACP, 0, mlcA.pamxctrl[i].szShortName, -1,
- lpmlcW->pamxctrl[i].szShortName,
- sizeof(lpmlcW->pamxctrl[i].szShortName)/sizeof(WCHAR) );
- MultiByteToWideChar( CP_ACP, 0, mlcA.pamxctrl[i].szName, -1,
- lpmlcW->pamxctrl[i].szName,
- sizeof(lpmlcW->pamxctrl[i].szName)/sizeof(WCHAR) );
- /* sizeof(lpmlcW->pamxctrl[i].Bounds) ==
- * sizeof(mlcA.pamxctrl[i].Bounds) */
- memcpy(&lpmlcW->pamxctrl[i].Bounds, &mlcA.pamxctrl[i].Bounds,
- sizeof(mlcA.pamxctrl[i].Bounds));
- /* sizeof(lpmlcW->pamxctrl[i].Metrics) ==
- * sizeof(mlcA.pamxctrl[i].Metrics) */
- memcpy(&lpmlcW->pamxctrl[i].Metrics, &mlcA.pamxctrl[i].Metrics,
- sizeof(mlcA.pamxctrl[i].Metrics));
- }
- }
-
- HeapFree(GetProcessHeap(), 0, mlcA.pamxctrl);
-
- return ret;
-}
-
-/**************************************************************************
* mixerGetLineControls [MMSYSTEM.807]
*/
UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,
@@ -1285,88 +295,6 @@
}
/**************************************************************************
- * mixerGetLineInfoA [WINMM.@]
- */
-UINT WINAPI mixerGetLineInfoA(HMIXEROBJ hmix, LPMIXERLINEA lpmliW, DWORD fdwInfo)
-{
- LPWINE_MIXER lpwm;
-
- TRACE("(%04x, %p, %08lx)\n", hmix, lpmliW, fdwInfo);
-
- if ((lpwm = MIXER_GetDev(hmix, fdwInfo)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(&lpwm->mld, MXDM_GETLINEINFO, (DWORD)lpmliW,
- fdwInfo, TRUE);
-}
-
-/**************************************************************************
- * mixerGetLineInfoW [WINMM.@]
- */
-UINT WINAPI mixerGetLineInfoW(HMIXEROBJ hmix, LPMIXERLINEW lpmliW,
- DWORD fdwInfo)
-{
- MIXERLINEA mliA;
- UINT ret;
-
- TRACE("(%04x, %p, %08lx)\n", hmix, lpmliW, fdwInfo);
-
- if (lpmliW == NULL || lpmliW->cbStruct != sizeof(*lpmliW))
- return MMSYSERR_INVALPARAM;
-
- mliA.cbStruct = sizeof(mliA);
- switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
- case MIXER_GETLINEINFOF_COMPONENTTYPE:
- mliA.dwComponentType = lpmliW->dwComponentType;
- break;
- case MIXER_GETLINEINFOF_DESTINATION:
- mliA.dwDestination = lpmliW->dwDestination;
- break;
- case MIXER_GETLINEINFOF_LINEID:
- mliA.dwLineID = lpmliW->dwLineID;
- break;
- case MIXER_GETLINEINFOF_SOURCE:
- mliA.dwDestination = lpmliW->dwDestination;
- mliA.dwSource = lpmliW->dwSource;
- break;
- case MIXER_GETLINEINFOF_TARGETTYPE:
- mliA.Target.dwType = lpmliW->Target.dwType;
- mliA.Target.wMid = lpmliW->Target.wMid;
- mliA.Target.wPid = lpmliW->Target.wPid;
- mliA.Target.vDriverVersion = lpmliW->Target.vDriverVersion;
- WideCharToMultiByte( CP_ACP, 0, lpmliW->Target.szPname, -1, mliA.Target.szPname, sizeof(mliA.Target.szPname), NULL, NULL);
- break;
- default:
- FIXME("Unsupported fdwControls=0x%08lx\n", fdwInfo);
- }
-
- ret = mixerGetLineInfoA(hmix, &mliA, fdwInfo);
-
- lpmliW->dwDestination = mliA.dwDestination;
- lpmliW->dwSource = mliA.dwSource;
- lpmliW->dwLineID = mliA.dwLineID;
- lpmliW->fdwLine = mliA.fdwLine;
- lpmliW->dwUser = mliA.dwUser;
- lpmliW->dwComponentType = mliA.dwComponentType;
- lpmliW->cChannels = mliA.cChannels;
- lpmliW->cConnections = mliA.cConnections;
- lpmliW->cControls = mliA.cControls;
- MultiByteToWideChar( CP_ACP, 0, mliA.szShortName, -1, lpmliW->szShortName,
- sizeof(lpmliW->szShortName)/sizeof(WCHAR) );
- MultiByteToWideChar( CP_ACP, 0, mliA.szName, -1, lpmliW->szName,
- sizeof(lpmliW->szName)/sizeof(WCHAR) );
- lpmliW->Target.dwType = mliA.Target.dwType;
- lpmliW->Target.dwDeviceID = mliA.Target.dwDeviceID;
- lpmliW->Target.wMid = mliA.Target.wMid;
- lpmliW->Target.wPid = mliA.Target.wPid;
- lpmliW->Target.vDriverVersion = mliA.Target.vDriverVersion;
- MultiByteToWideChar( CP_ACP, 0, mliA.Target.szPname, -1, lpmliW->Target.szPname,
- sizeof(lpmliW->Target.szPname)/sizeof(WCHAR) );
-
- return ret;
-}
-
-/**************************************************************************
* mixerGetLineInfo [MMSYSTEM.805]
*/
UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix, LPMIXERLINE16 lpmli16,
@@ -1430,23 +358,6 @@
}
/**************************************************************************
- * mixerSetControlDetails [WINMM.@]
- */
-UINT WINAPI mixerSetControlDetails(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdA,
- DWORD fdwDetails)
-{
- LPWINE_MIXER lpwm;
-
- TRACE("(%04x, %p, %08lx)\n", hmix, lpmcdA, fdwDetails);
-
- if ((lpwm = MIXER_GetDev(hmix, fdwDetails)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(&lpwm->mld, MXDM_SETCONTROLDETAILS, (DWORD)lpmcdA,
- fdwDetails, TRUE);
-}
-
-/**************************************************************************
* mixerSetControlDetails [MMSYSTEM.809]
*/
UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix,
@@ -1458,22 +369,6 @@
}
/**************************************************************************
- * mixerMessage [WINMM.@]
- */
-UINT WINAPI mixerMessage(HMIXER hmix, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04lx, %d, %08lx, %08lx): semi-stub?\n",
- (DWORD)hmix, uMsg, dwParam1, dwParam2);
-
- if ((wmld = MMDRV_Get(hmix, MMDRV_MIXER, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, uMsg, dwParam1, dwParam2, TRUE);
-}
-
-/**************************************************************************
* mixerMessage [MMSYSTEM.804]
*/
DWORD WINAPI mixerMessage16(HMIXER16 hmix, UINT16 uMsg, DWORD dwParam1,
@@ -1483,14 +378,6 @@
}
/**************************************************************************
- * auxGetNumDevs [WINMM.@]
- */
-UINT WINAPI auxGetNumDevs(void)
-{
- return MMDRV_GetNum(MMDRV_AUX);
-}
-
-/**************************************************************************
* auxGetNumDevs [MMSYSTEM.350]
*/
UINT16 WINAPI auxGetNumDevs16(void)
@@ -1499,38 +386,6 @@
}
/**************************************************************************
- * auxGetDevCapsW [WINMM.@]
- */
-UINT WINAPI auxGetDevCapsW(UINT uDeviceID, LPAUXCAPSW lpCaps, UINT uSize)
-{
- AUXCAPSA acA;
- UINT ret = auxGetDevCapsA(uDeviceID, &acA, sizeof(acA));
-
- lpCaps->wMid = acA.wMid;
- lpCaps->wPid = acA.wPid;
- lpCaps->vDriverVersion = acA.vDriverVersion;
- MultiByteToWideChar( CP_ACP, 0, acA.szPname, -1, lpCaps->szPname,
- sizeof(lpCaps->szPname)/sizeof(WCHAR) );
- lpCaps->wTechnology = acA.wTechnology;
- lpCaps->dwSupport = acA.dwSupport;
- return ret;
-}
-
-/**************************************************************************
- * auxGetDevCapsA [WINMM.@]
- */
-UINT WINAPI auxGetDevCapsA(UINT uDeviceID, LPAUXCAPSA lpCaps, UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %d) !\n", uDeviceID, lpCaps, uSize);
-
- if ((wmld = MMDRV_Get(uDeviceID, MMDRV_AUX, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
- return MMDRV_Message(wmld, AUXDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
-}
-
-/**************************************************************************
* auxGetDevCaps [MMSYSTEM.351]
*/
UINT16 WINAPI auxGetDevCaps16(UINT16 uDeviceID, LPAUXCAPS16 lpCaps, UINT16 uSize)
@@ -1545,20 +400,6 @@
}
/**************************************************************************
- * auxGetVolume [WINMM.@]
- */
-UINT WINAPI auxGetVolume(UINT uDeviceID, DWORD* lpdwVolume)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p) !\n", uDeviceID, lpdwVolume);
-
- if ((wmld = MMDRV_Get(uDeviceID, MMDRV_AUX, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
- return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD)lpdwVolume, 0L, TRUE);
-}
-
-/**************************************************************************
* auxGetVolume [MMSYSTEM.352]
*/
UINT16 WINAPI auxGetVolume16(UINT16 uDeviceID, LPDWORD lpdwVolume)
@@ -1573,20 +414,6 @@
}
/**************************************************************************
- * auxSetVolume [WINMM.@]
- */
-UINT WINAPI auxSetVolume(UINT uDeviceID, DWORD dwVolume)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %lu) !\n", uDeviceID, dwVolume);
-
- if ((wmld = MMDRV_Get(uDeviceID, MMDRV_AUX, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
- return MMDRV_Message(wmld, AUXDM_SETVOLUME, dwVolume, 0L, TRUE);
-}
-
-/**************************************************************************
* auxSetVolume [MMSYSTEM.353]
*/
UINT16 WINAPI auxSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
@@ -1601,19 +428,6 @@
}
/**************************************************************************
- * auxOutMessage [WINMM.@]
- */
-DWORD WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD dw1, DWORD dw2)
-{
- LPWINE_MLD wmld;
-
- if ((wmld = MMDRV_Get(uDeviceID, MMDRV_AUX, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, uMessage, dw1, dw2, TRUE);
-}
-
-/**************************************************************************
* auxOutMessage [MMSYSTEM.354]
*/
DWORD WINAPI auxOutMessage16(UINT16 uDeviceID, UINT16 uMessage, DWORD dw1, DWORD dw2)
@@ -1643,19 +457,6 @@
}
/**************************************************************************
- * mciGetErrorStringW [WINMM.@]
- */
-BOOL WINAPI mciGetErrorStringW(DWORD wError, LPWSTR lpstrBuffer, UINT uLength)
-{
- LPSTR bufstr = HeapAlloc(GetProcessHeap(), 0, uLength);
- BOOL ret = mciGetErrorStringA(wError, bufstr, uLength);
-
- MultiByteToWideChar( CP_ACP, 0, bufstr, -1, lpstrBuffer, uLength );
- HeapFree(GetProcessHeap(), 0, bufstr);
- return ret;
-}
-
-/**************************************************************************
* mciGetErrorString [MMSYSTEM.706]
*/
BOOL16 WINAPI mciGetErrorString16(DWORD wError, LPSTR lpstrBuffer, UINT16 uLength)
@@ -1664,24 +465,6 @@
}
/**************************************************************************
- * mciGetErrorStringA [WINMM.@]
- */
-BOOL WINAPI mciGetErrorStringA(DWORD dwError, LPSTR lpstrBuffer, UINT uLength)
-{
- BOOL16 ret = FALSE;
-
- if (lpstrBuffer != NULL && uLength > 0 &&
- dwError >= MCIERR_BASE && dwError <= MCIERR_CUSTOM_DRIVER_BASE) {
-
- if (LoadStringA(MULTIMEDIA_GetIData()->hWinMM32Instance,
- dwError, lpstrBuffer, uLength) > 0) {
- ret = TRUE;
- }
- }
- return ret;
-}
-
-/**************************************************************************
* mciDriverNotify [MMSYSTEM.711]
*/
BOOL16 WINAPI mciDriverNotify16(HWND16 hWndCallBack, UINT16 wDevID, UINT16 wStatus)
@@ -1692,176 +475,55 @@
}
/**************************************************************************
- * mciDriverNotify [WINMM.@]
+ * mciGetDriverData [MMSYSTEM.708]
*/
-BOOL WINAPI mciDriverNotify(HWND hWndCallBack, UINT wDevID, UINT wStatus)
+DWORD WINAPI mciGetDriverData16(UINT16 uDeviceID)
{
-
- TRACE("(%08X, %04x, %04X)\n", hWndCallBack, wDevID, wStatus);
-
- return PostMessageA(hWndCallBack, MM_MCINOTIFY, wStatus, wDevID);
+ return mciGetDriverData(uDeviceID);
}
/**************************************************************************
- * mciGetDriverData [MMSYSTEM.708]
+ * mciSetDriverData [MMSYSTEM.707]
*/
-DWORD WINAPI mciGetDriverData16(UINT16 uDeviceID)
+BOOL16 WINAPI mciSetDriverData16(UINT16 uDeviceID, DWORD data)
{
- return mciGetDriverData(uDeviceID);
+ return mciSetDriverData(uDeviceID, data);
}
/**************************************************************************
- * mciGetDriverData [WINMM.@]
+ * mciSendCommand [MMSYSTEM.701]
*/
-DWORD WINAPI mciGetDriverData(UINT uDeviceID)
+DWORD WINAPI mciSendCommand16(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
{
- LPWINE_MCIDRIVER wmd;
-
- TRACE("(%04x)\n", uDeviceID);
-
- wmd = MCI_GetDriver(uDeviceID);
+ DWORD dwRet;
- if (!wmd) {
- WARN("Bad uDeviceID\n");
- return 0L;
- }
+ TRACE("(%04X, %s, %08lX, %08lX)\n",
+ wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
- return wmd->dwPrivate;
+ dwRet = MCI_SendCommand(wDevID, wMsg, dwParam1, dwParam2, FALSE);
+ dwRet = MCI_CleanUp(dwRet, wMsg, dwParam2, FALSE);
+ TRACE("=> %ld\n", dwRet);
+ return dwRet;
}
/**************************************************************************
- * mciSetDriverData [MMSYSTEM.707]
+ * mciGetDeviceID [MMSYSTEM.703]
*/
-BOOL16 WINAPI mciSetDriverData16(UINT16 uDeviceID, DWORD data)
+UINT16 WINAPI mciGetDeviceID16(LPCSTR lpstrName)
{
- return mciSetDriverData(uDeviceID, data);
+ TRACE("(\"%s\")\n", lpstrName);
+
+ return MCI_GetDriverFromString(lpstrName);
}
/**************************************************************************
- * mciSetDriverData [WINMM.@]
+ * mciSetYieldProc [MMSYSTEM.714]
*/
-BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD data)
+BOOL16 WINAPI mciSetYieldProc16(UINT16 uDeviceID, YIELDPROC16 fpYieldProc, DWORD dwYieldData)
{
LPWINE_MCIDRIVER wmd;
- TRACE("(%04x, %08lx)\n", uDeviceID, data);
-
- wmd = MCI_GetDriver(uDeviceID);
-
- if (!wmd) {
- WARN("Bad uDeviceID\n");
- return FALSE;
- }
-
- wmd->dwPrivate = data;
- return TRUE;
-}
-
-/**************************************************************************
- * mciSendCommandA [WINMM.@]
- */
-DWORD WINAPI mciSendCommandA(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
-{
- DWORD dwRet;
-
- TRACE("(%08x, %s, %08lx, %08lx)\n",
- wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
-
- dwRet = MCI_SendCommand(wDevID, wMsg, dwParam1, dwParam2, TRUE);
- dwRet = MCI_CleanUp(dwRet, wMsg, dwParam2, TRUE);
- TRACE("=> %08lx\n", dwRet);
- return dwRet;
-}
-
-/**************************************************************************
- * mciSendCommandW [WINMM.@]
- */
-DWORD WINAPI mciSendCommandW(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
-{
- FIXME("(%08x, %s, %08lx, %08lx): stub\n",
- wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
- return MCIERR_UNSUPPORTED_FUNCTION;
-}
-
-/**************************************************************************
- * mciSendCommand [MMSYSTEM.701]
- */
-DWORD WINAPI mciSendCommand16(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
-{
- DWORD dwRet;
-
- TRACE("(%04X, %s, %08lX, %08lX)\n",
- wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
-
- dwRet = MCI_SendCommand(wDevID, wMsg, dwParam1, dwParam2, FALSE);
- dwRet = MCI_CleanUp(dwRet, wMsg, dwParam2, FALSE);
- TRACE("=> %ld\n", dwRet);
- return dwRet;
-}
-
-/**************************************************************************
- * mciGetDeviceID [MMSYSTEM.703]
- */
-UINT16 WINAPI mciGetDeviceID16(LPCSTR lpstrName)
-{
- TRACE("(\"%s\")\n", lpstrName);
-
- return MCI_GetDriverFromString(lpstrName);
-}
-
-/**************************************************************************
- * mciGetDeviceIDA [WINMM.@]
- */
-UINT WINAPI mciGetDeviceIDA(LPCSTR lpstrName)
-{
- return MCI_GetDriverFromString(lpstrName);
-}
-
-/**************************************************************************
- * mciGetDeviceIDW [WINMM.@]
- */
-UINT WINAPI mciGetDeviceIDW(LPCWSTR lpwstrName)
-{
- LPSTR lpstrName;
- UINT ret;
-
- lpstrName = HEAP_strdupWtoA(GetProcessHeap(), 0, lpwstrName);
- ret = MCI_GetDriverFromString(lpstrName);
- HeapFree(GetProcessHeap(), 0, lpstrName);
- return ret;
-}
-
-/**************************************************************************
- * MCI_DefYieldProc [internal]
- */
-UINT WINAPI MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data)
-{
- INT16 ret;
-
- TRACE("(0x%04x, 0x%08lx)\n", wDevID, data);
-
- if ((HIWORD(data) != 0 && HWND_16(GetActiveWindow()) != HIWORD(data)) ||
- (GetAsyncKeyState(LOWORD(data)) & 1) == 0) {
- UserYield16();
- ret = 0;
- } else {
- MSG msg;
-
- msg.hwnd = HWND_32(HIWORD(data));
- while (!PeekMessageA(&msg, msg.hwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE));
- ret = -1;
- }
- return ret;
-}
-
-/**************************************************************************
- * mciSetYieldProc [MMSYSTEM.714]
- */
-BOOL16 WINAPI mciSetYieldProc16(UINT16 uDeviceID, YIELDPROC16 fpYieldProc, DWORD dwYieldData)
-{
- LPWINE_MCIDRIVER wmd;
-
- TRACE("(%u, %p, %08lx)\n", uDeviceID, fpYieldProc, dwYieldData);
+ TRACE("(%u, %p, %08lx)\n", uDeviceID, fpYieldProc, dwYieldData);
if (!(wmd = MCI_GetDriver(uDeviceID))) {
WARN("Bad uDeviceID\n");
@@ -1876,27 +538,6 @@
}
/**************************************************************************
- * mciSetYieldProc [WINMM.@]
- */
-BOOL WINAPI mciSetYieldProc(UINT uDeviceID, YIELDPROC fpYieldProc, DWORD dwYieldData)
-{
- LPWINE_MCIDRIVER wmd;
-
- TRACE("(%u, %p, %08lx)\n", uDeviceID, fpYieldProc, dwYieldData);
-
- if (!(wmd = MCI_GetDriver(uDeviceID))) {
- WARN("Bad uDeviceID\n");
- return FALSE;
- }
-
- wmd->lpfnYieldProc = fpYieldProc;
- wmd->dwYieldData = dwYieldData;
- wmd->bIs32 = TRUE;
-
- return TRUE;
-}
-
-/**************************************************************************
* mciGetDeviceIDFromElementID [MMSYSTEM.715]
*/
UINT16 WINAPI mciGetDeviceIDFromElementID16(DWORD dwElementID, LPCSTR lpstrType)
@@ -1906,18 +547,6 @@
}
/**************************************************************************
- * mciGetDeviceIDFromElementIDW [WINMM.@]
- */
-UINT WINAPI mciGetDeviceIDFromElementIDW(DWORD dwElementID, LPCWSTR lpstrType)
-{
- /* FIXME: that's rather strange, there is no
- * mciGetDeviceIDFromElementID32A in winmm.spec
- */
- FIXME("(%lu, %p) stub\n", dwElementID, lpstrType);
- return 0;
-}
-
-/**************************************************************************
* mciGetYieldProc [MMSYSTEM.716]
*/
YIELDPROC16 WINAPI mciGetYieldProc16(UINT16 uDeviceID, DWORD* lpdwYieldData)
@@ -1942,30 +571,6 @@
}
/**************************************************************************
- * mciGetYieldProc [WINMM.@]
- */
-YIELDPROC WINAPI mciGetYieldProc(UINT uDeviceID, DWORD* lpdwYieldData)
-{
- LPWINE_MCIDRIVER wmd;
-
- TRACE("(%u, %p)\n", uDeviceID, lpdwYieldData);
-
- if (!(wmd = MCI_GetDriver(uDeviceID))) {
- WARN("Bad uDeviceID\n");
- return NULL;
- }
- if (!wmd->lpfnYieldProc) {
- WARN("No proc set\n");
- return NULL;
- }
- if (!wmd->bIs32) {
- WARN("Proc is 32 bit\n");
- return NULL;
- }
- return wmd->lpfnYieldProc;
-}
-
-/**************************************************************************
* mciGetCreatorTask [MMSYSTEM.717]
*/
HTASK16 WINAPI mciGetCreatorTask16(UINT16 uDeviceID)
@@ -1980,20 +585,6 @@
}
/**************************************************************************
- * mciGetCreatorTask [WINMM.@]
- */
-HTASK WINAPI mciGetCreatorTask(UINT uDeviceID)
-{
- LPWINE_MCIDRIVER wmd;
- HTASK ret = 0;
-
- if ((wmd = MCI_GetDriver(uDeviceID))) ret = (HTASK)wmd->CreatorThread;
-
- TRACE("(%u) => %08x\n", uDeviceID, ret);
- return ret;
-}
-
-/**************************************************************************
* mciDriverYield [MMSYSTEM.710]
*/
UINT16 WINAPI mciDriverYield16(UINT16 uDeviceID)
@@ -2013,33 +604,6 @@
}
/**************************************************************************
- * mciDriverYield [WINMM.@]
- */
-UINT WINAPI mciDriverYield(UINT uDeviceID)
-{
- LPWINE_MCIDRIVER wmd;
- UINT ret = 0;
-
- TRACE("(%04x)\n", uDeviceID);
-
- if (!(wmd = MCI_GetDriver(uDeviceID)) || !wmd->lpfnYieldProc || !wmd->bIs32) {
- UserYield16();
- } else {
- ret = wmd->lpfnYieldProc(uDeviceID, wmd->dwYieldData);
- }
-
- return ret;
-}
-
-/**************************************************************************
- * midiOutGetNumDevs [WINMM.@]
- */
-UINT WINAPI midiOutGetNumDevs(void)
-{
- return MMDRV_GetNum(MMDRV_MIDIOUT);
-}
-
-/**************************************************************************
* midiOutGetNumDevs [MMSYSTEM.201]
*/
UINT16 WINAPI midiOutGetNumDevs16(void)
@@ -2048,47 +612,6 @@
}
/**************************************************************************
- * midiOutGetDevCapsW [WINMM.@]
- */
-UINT WINAPI midiOutGetDevCapsW(UINT uDeviceID, LPMIDIOUTCAPSW lpCaps,
- UINT uSize)
-{
- MIDIOUTCAPSA mocA;
- UINT ret;
-
- ret = midiOutGetDevCapsA(uDeviceID, &mocA, sizeof(mocA));
- lpCaps->wMid = mocA.wMid;
- lpCaps->wPid = mocA.wPid;
- lpCaps->vDriverVersion = mocA.vDriverVersion;
- MultiByteToWideChar( CP_ACP, 0, mocA.szPname, -1, lpCaps->szPname,
- sizeof(lpCaps->szPname)/sizeof(WCHAR) );
- lpCaps->wTechnology = mocA.wTechnology;
- lpCaps->wVoices = mocA.wVoices;
- lpCaps->wNotes = mocA.wNotes;
- lpCaps->wChannelMask = mocA.wChannelMask;
- lpCaps->dwSupport = mocA.dwSupport;
- return ret;
-}
-
-/**************************************************************************
- * midiOutGetDevCapsA [WINMM.@]
- */
-UINT WINAPI midiOutGetDevCapsA(UINT uDeviceID, LPMIDIOUTCAPSA lpCaps,
- UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%u, %p, %u);\n", uDeviceID, lpCaps, uSize);
-
- if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
-
- if ((wmld = MMDRV_Get(uDeviceID, MMDRV_MIDIOUT, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MODM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
-}
-
-/**************************************************************************
* midiOutGetDevCaps [MMSYSTEM.202]
*/
UINT16 WINAPI midiOutGetDevCaps16(UINT16 uDeviceID, LPMIDIOUTCAPS16 lpCaps,
@@ -2115,133 +638,11 @@
}
/**************************************************************************
- * MIDI_GetErrorText [internal]
- */
-static UINT16 MIDI_GetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
-{
- UINT16 ret = MMSYSERR_BADERRNUM;
-
- if (lpText == NULL) {
- ret = MMSYSERR_INVALPARAM;
- } else if (uSize == 0) {
- ret = MMSYSERR_NOERROR;
- } else if (
- /* test has been removed 'coz MMSYSERR_BASE is 0, and gcc did emit
- * a warning for the test was always true */
- (/*uError >= MMSYSERR_BASE && */ uError <= MMSYSERR_LASTERROR) ||
- (uError >= MIDIERR_BASE && uError <= MIDIERR_LASTERROR)) {
-
- if (LoadStringA(MULTIMEDIA_GetIData()->hWinMM32Instance,
- uError, lpText, uSize) > 0) {
- ret = MMSYSERR_NOERROR;
- }
- }
- return ret;
-}
-
-/**************************************************************************
- * midiOutGetErrorTextA [WINMM.@]
- */
-UINT WINAPI midiOutGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
-{
- return MIDI_GetErrorText(uError, lpText, uSize);
-}
-
-/**************************************************************************
- * midiOutGetErrorTextW [WINMM.@]
- */
-UINT WINAPI midiOutGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
-{
- LPSTR xstr = HeapAlloc(GetProcessHeap(), 0, uSize);
- UINT ret;
-
- ret = MIDI_GetErrorText(uError, xstr, uSize);
- MultiByteToWideChar( CP_ACP, 0, xstr, -1, lpText, uSize );
- HeapFree(GetProcessHeap(), 0, xstr);
- return ret;
-}
-
-/**************************************************************************
* midiOutGetErrorText [MMSYSTEM.203]
*/
UINT16 WINAPI midiOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
{
- return MIDI_GetErrorText(uError, lpText, uSize);
-}
-
-/**************************************************************************
- * MIDI_OutAlloc [internal]
- */
-static LPWINE_MIDI MIDI_OutAlloc(HMIDIOUT* lphMidiOut, LPDWORD lpdwCallback,
- LPDWORD lpdwInstance, LPDWORD lpdwFlags,
- DWORD cIDs, MIDIOPENSTRMID* lpIDs, BOOL bFrom32)
-{
- HMIDIOUT hMidiOut;
- LPWINE_MIDI lpwm;
- UINT size;
-
- size = sizeof(WINE_MIDI) + (cIDs ? (cIDs-1) : 0) * sizeof(MIDIOPENSTRMID);
-
- lpwm = (LPWINE_MIDI)MMDRV_Alloc(size, MMDRV_MIDIOUT, &hMidiOut, lpdwFlags,
- lpdwCallback, lpdwInstance, bFrom32);
-
- if (lphMidiOut != NULL)
- *lphMidiOut = hMidiOut;
-
- if (lpwm) {
- lpwm->mod.hMidi = (HMIDI) hMidiOut;
- lpwm->mod.dwCallback = *lpdwCallback;
- lpwm->mod.dwInstance = *lpdwInstance;
- lpwm->mod.dnDevNode = 0;
- lpwm->mod.cIds = cIDs;
- if (cIDs)
- memcpy(&(lpwm->mod.rgIds), lpIDs, cIDs * sizeof(MIDIOPENSTRMID));
- }
- return lpwm;
-}
-
-UINT MMSYSTEM_midiOutOpen(HMIDIOUT* lphMidiOut, UINT uDeviceID, DWORD dwCallback,
- DWORD dwInstance, DWORD dwFlags, BOOL bFrom32)
-{
- HMIDIOUT hMidiOut;
- LPWINE_MIDI lpwm;
- UINT dwRet = 0;
-
- TRACE("(%p, %d, %08lX, %08lX, %08lX);\n",
- lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags);
-
- if (lphMidiOut != NULL) *lphMidiOut = 0;
-
- lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &dwFlags,
- 0, NULL, bFrom32);
-
- if (lpwm == NULL)
- return MMSYSERR_NOMEM;
-
- lpwm->mld.uDeviceID = uDeviceID;
-
- dwRet = MMDRV_Open((LPWINE_MLD)lpwm, MODM_OPEN, (DWORD)&lpwm->mod,
- dwFlags);
-
- if (dwRet != MMSYSERR_NOERROR) {
- MMDRV_Free(hMidiOut, (LPWINE_MLD)lpwm);
- hMidiOut = 0;
- }
-
- if (lphMidiOut) *lphMidiOut = hMidiOut;
- TRACE("=> %d hMidi=%04x\n", dwRet, hMidiOut);
-
- return dwRet;
-}
-
-/**************************************************************************
- * midiOutOpen [WINMM.@]
- */
-UINT WINAPI midiOutOpen(HMIDIOUT* lphMidiOut, UINT uDeviceID,
- DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
-{
- return MMSYSTEM_midiOutOpen(lphMidiOut, uDeviceID, dwCallback,
- dwInstance, dwFlags, TRUE);
+ return midiOutGetErrorTextA(uError, lpText, uSize);
}
/**************************************************************************
@@ -2261,25 +662,6 @@
}
/**************************************************************************
- * midiOutClose [WINMM.@]
- */
-UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
-{
- LPWINE_MLD wmld;
- DWORD dwRet;
-
- TRACE("(%04X)\n", hMidiOut);
-
- if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- dwRet = MMDRV_Close(wmld, MODM_CLOSE);
- MMDRV_Free(hMidiOut, wmld);
-
- return dwRet;
-}
-
-/**************************************************************************
* midiOutClose [MMSYSTEM.205]
*/
UINT16 WINAPI midiOutClose16(HMIDIOUT16 hMidiOut)
@@ -2288,22 +670,6 @@
}
/**************************************************************************
- * midiOutPrepareHeader [WINMM.@]
- */
-UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut,
- MIDIHDR* lpMidiOutHdr, UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
-
- if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MODM_PREPARE, (DWORD)lpMidiOutHdr, uSize, TRUE);
-}
-
-/**************************************************************************
* midiOutPrepareHeader [MMSYSTEM.206]
*/
UINT16 WINAPI midiOutPrepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */
@@ -2321,34 +687,14 @@
}
/**************************************************************************
- * midiOutUnprepareHeader [WINMM.@]
+ * midiOutUnprepareHeader [MMSYSTEM.207]
*/
-UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut,
- MIDIHDR* lpMidiOutHdr, UINT uSize)
+UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */
+ SEGPTR lpsegMidiOutHdr, /* [???] */
+ UINT16 uSize) /* [in] */
{
LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
-
- if (!(lpMidiOutHdr->dwFlags & MHDR_PREPARED)) {
- return MMSYSERR_NOERROR;
- }
-
- if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD)lpMidiOutHdr, uSize, TRUE);
-}
-
-/**************************************************************************
- * midiOutUnprepareHeader [MMSYSTEM.207]
- */
-UINT16 WINAPI midiOutUnprepareHeader16(HMIDIOUT16 hMidiOut, /* [in] */
- SEGPTR lpsegMidiOutHdr, /* [???] */
- UINT16 uSize) /* [in] */
-{
- LPWINE_MLD wmld;
- LPMIDIHDR16 lpMidiOutHdr = MapSL(lpsegMidiOutHdr);
+ LPMIDIHDR16 lpMidiOutHdr = MapSL(lpsegMidiOutHdr);
TRACE("(%04X, %08lx, %d)\n", hMidiOut, lpsegMidiOutHdr, uSize);
@@ -2363,21 +709,6 @@
}
/**************************************************************************
- * midiOutShortMsg [WINMM.@]
- */
-UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %08lX)\n", hMidiOut, dwMsg);
-
- if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MODM_DATA, dwMsg, 0L, FALSE);
-}
-
-/**************************************************************************
* midiOutShortMsg [MMSYSTEM.208]
*/
UINT16 WINAPI midiOutShortMsg16(HMIDIOUT16 hMidiOut, DWORD dwMsg)
@@ -2386,22 +717,6 @@
}
/**************************************************************************
- * midiOutLongMsg [WINMM.@]
- */
-UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut,
- MIDIHDR* lpMidiOutHdr, UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
-
- if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD)lpMidiOutHdr, uSize, TRUE);
-}
-
-/**************************************************************************
* midiOutLongMsg [MMSYSTEM.209]
*/
UINT16 WINAPI midiOutLongMsg16(HMIDIOUT16 hMidiOut, /* [in] */
@@ -2419,21 +734,6 @@
}
/**************************************************************************
- * midiOutReset [WINMM.@]
- */
-UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X)\n", hMidiOut);
-
- if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MODM_RESET, 0L, 0L, TRUE);
-}
-
-/**************************************************************************
* midiOutReset [MMSYSTEM.210]
*/
UINT16 WINAPI midiOutReset16(HMIDIOUT16 hMidiOut)
@@ -2442,21 +742,6 @@
}
/**************************************************************************
- * midiOutGetVolume [WINMM.@]
- */
-UINT WINAPI midiOutGetVolume(UINT uDeviceID, DWORD* lpdwVolume)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p);\n", uDeviceID, lpdwVolume);
-
- if ((wmld = MMDRV_Get(uDeviceID, MMDRV_MIDIOUT, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MODM_GETVOLUME, (DWORD)lpdwVolume, 0L, TRUE);
-}
-
-/**************************************************************************
* midiOutGetVolume [MMSYSTEM.211]
*/
UINT16 WINAPI midiOutGetVolume16(UINT16 uDeviceID, DWORD* lpdwVolume)
@@ -2465,21 +750,6 @@
}
/**************************************************************************
- * midiOutSetVolume [WINMM.@]
- */
-UINT WINAPI midiOutSetVolume(UINT uDeviceID, DWORD dwVolume)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %ld);\n", uDeviceID, dwVolume);
-
- if ((wmld = MMDRV_Get(uDeviceID, MMDRV_MIDIOUT, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MODM_SETVOLUME, dwVolume, 0L, TRUE);
-}
-
-/**************************************************************************
* midiOutSetVolume [MMSYSTEM.212]
*/
UINT16 WINAPI midiOutSetVolume16(UINT16 uDeviceID, DWORD dwVolume)
@@ -2488,17 +758,6 @@
}
/**************************************************************************
- * midiOutCachePatches [WINMM.@]
- */
-UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank,
- WORD* lpwPatchArray, UINT uFlags)
-{
- /* not really necessary to support this */
- FIXME("not supported yet\n");
- return MMSYSERR_NOTSUPPORTED;
-}
-
-/**************************************************************************
* midiOutCachePatches [MMSYSTEM.213]
*/
UINT16 WINAPI midiOutCachePatches16(HMIDIOUT16 hMidiOut, UINT16 uBank,
@@ -2509,16 +768,6 @@
}
/**************************************************************************
- * midiOutCacheDrumPatches [WINMM.@]
- */
-UINT WINAPI midiOutCacheDrumPatches(HMIDIOUT hMidiOut, UINT uPatch,
- WORD* lpwKeyArray, UINT uFlags)
-{
- FIXME("not supported yet\n");
- return MMSYSERR_NOTSUPPORTED;
-}
-
-/**************************************************************************
* midiOutCacheDrumPatches [MMSYSTEM.214]
*/
UINT16 WINAPI midiOutCacheDrumPatches16(HMIDIOUT16 hMidiOut, UINT16 uPatch,
@@ -2528,23 +777,6 @@
}
/**************************************************************************
- * midiOutGetID [WINMM.@]
- */
-UINT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT* lpuDeviceID)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p)\n", hMidiOut, lpuDeviceID);
-
- if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
- if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- *lpuDeviceID = wmld->uDeviceID;
- return MMSYSERR_NOERROR;
-}
-
-/**************************************************************************
* midiOutGetID [MMSYSTEM.215]
*/
UINT16 WINAPI midiOutGetID16(HMIDIOUT16 hMidiOut, UINT16* lpuDeviceID)
@@ -2562,37 +794,6 @@
}
/**************************************************************************
- * midiOutMessage [WINMM.@]
- */
-DWORD WINAPI midiOutMessage(HMIDIOUT hMidiOut, UINT uMessage,
- DWORD dwParam1, DWORD dwParam2)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiOut, uMessage, dwParam1, dwParam2);
-
- if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL) {
- /* HACK... */
- if (uMessage == 0x0001) {
- *(LPDWORD)dwParam1 = 1;
- return 0;
- }
- if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, TRUE)) != NULL) {
- return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
- }
- return MMSYSERR_INVALHANDLE;
- }
-
- switch (uMessage) {
- case MODM_OPEN:
- case MODM_CLOSE:
- FIXME("can't handle OPEN or CLOSE message!\n");
- return MMSYSERR_NOTSUPPORTED;
- }
- return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
-}
-
-/**************************************************************************
* midiOutMessage [MMSYSTEM.216]
*/
DWORD WINAPI midiOutMessage16(HMIDIOUT16 hMidiOut, UINT16 uMessage,
@@ -2625,14 +826,6 @@
}
/**************************************************************************
- * midiInGetNumDevs [WINMM.@]
- */
-UINT WINAPI midiInGetNumDevs(void)
-{
- return MMDRV_GetNum(MMDRV_MIDIIN);
-}
-
-/**************************************************************************
* midiInGetNumDevs [MMSYSTEM.301]
*/
UINT16 WINAPI midiInGetNumDevs16(void)
@@ -2641,40 +834,6 @@
}
/**************************************************************************
- * midiInGetDevCapsW [WINMM.@]
- */
-UINT WINAPI midiInGetDevCapsW(UINT uDeviceID, LPMIDIINCAPSW lpCaps, UINT uSize)
-{
- MIDIINCAPSA micA;
- UINT ret = midiInGetDevCapsA(uDeviceID, &micA, uSize);
-
- if (ret == MMSYSERR_NOERROR) {
- lpCaps->wMid = micA.wMid;
- lpCaps->wPid = micA.wPid;
- lpCaps->vDriverVersion = micA.vDriverVersion;
- MultiByteToWideChar( CP_ACP, 0, micA.szPname, -1, lpCaps->szPname,
- sizeof(lpCaps->szPname)/sizeof(WCHAR) );
- lpCaps->dwSupport = micA.dwSupport;
- }
- return ret;
-}
-
-/**************************************************************************
- * midiInGetDevCapsA [WINMM.@]
- */
-UINT WINAPI midiInGetDevCapsA(UINT uDeviceID, LPMIDIINCAPSA lpCaps, UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%d, %p, %d);\n", uDeviceID, lpCaps, uSize);
-
- if ((wmld = MMDRV_Get(uDeviceID, MMDRV_MIDIIN, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MIDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
-}
-
-/**************************************************************************
* midiInGetDevCaps [MMSYSTEM.302]
*/
UINT16 WINAPI midiInGetDevCaps16(UINT16 uDeviceID, LPMIDIINCAPS16 lpCaps,
@@ -2695,77 +854,11 @@
}
/**************************************************************************
- * midiInGetErrorTextW [WINMM.@]
- */
-UINT WINAPI midiInGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
-{
- LPSTR xstr = HeapAlloc(GetProcessHeap(), 0, uSize);
- UINT ret = MIDI_GetErrorText(uError, xstr, uSize);
-
- MultiByteToWideChar( CP_ACP, 0, xstr, -1, lpText, uSize );
- HeapFree(GetProcessHeap(), 0, xstr);
- return ret;
-}
-
-/**************************************************************************
- * midiInGetErrorTextA [WINMM.@]
- */
-UINT WINAPI midiInGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
-{
- return MIDI_GetErrorText(uError, lpText, uSize);
-}
-
-/**************************************************************************
* midiInGetErrorText [MMSYSTEM.303]
*/
UINT16 WINAPI midiInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
{
- return MIDI_GetErrorText(uError, lpText, uSize);
-}
-
-static UINT MMSYSTEM_midiInOpen(HMIDIIN* lphMidiIn, UINT uDeviceID, DWORD dwCallback,
- DWORD dwInstance, DWORD dwFlags, BOOL bFrom32)
-{
- HMIDIIN hMidiIn;
- LPWINE_MIDI lpwm;
- DWORD dwRet = 0;
-
- TRACE("(%p, %d, %08lX, %08lX, %08lX);\n",
- lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
-
- if (lphMidiIn != NULL) *lphMidiIn = 0;
-
- lpwm = (LPWINE_MIDI)MMDRV_Alloc(sizeof(WINE_MIDI), MMDRV_MIDIIN, &hMidiIn,
- &dwFlags, &dwCallback, &dwInstance, bFrom32);
-
- if (lpwm == NULL)
- return MMSYSERR_NOMEM;
-
- lpwm->mod.hMidi = (HMIDI) hMidiIn;
- lpwm->mod.dwCallback = dwCallback;
- lpwm->mod.dwInstance = dwInstance;
-
- lpwm->mld.uDeviceID = uDeviceID;
- dwRet = MMDRV_Open(&lpwm->mld, MIDM_OPEN, (DWORD)&lpwm->mod, dwFlags);
-
- if (dwRet != MMSYSERR_NOERROR) {
- MMDRV_Free(hMidiIn, &lpwm->mld);
- hMidiIn = 0;
- }
- if (lphMidiIn != NULL) *lphMidiIn = hMidiIn;
- TRACE("=> %ld hMidi=%04x\n", dwRet, hMidiIn);
-
- return dwRet;
-}
-
-/**************************************************************************
- * midiInOpen [WINMM.@]
- */
-UINT WINAPI midiInOpen(HMIDIIN* lphMidiIn, UINT uDeviceID,
- DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
-{
- return MMSYSTEM_midiInOpen(lphMidiIn, uDeviceID, dwCallback,
- dwInstance, dwFlags, TRUE);
+ return midiInGetErrorTextA(uError, lpText, uSize);
}
/**************************************************************************
@@ -2785,24 +878,6 @@
}
/**************************************************************************
- * midiInClose [WINMM.@]
- */
-UINT WINAPI midiInClose(HMIDIIN hMidiIn)
-{
- LPWINE_MLD wmld;
- DWORD dwRet;
-
- TRACE("(%04X)\n", hMidiIn);
-
- if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- dwRet = MMDRV_Close(wmld, MIDM_CLOSE);
- MMDRV_Free(hMidiIn, wmld);
- return dwRet;
-}
-
-/**************************************************************************
* midiInClose [MMSYSTEM.305]
*/
UINT16 WINAPI midiInClose16(HMIDIIN16 hMidiIn)
@@ -2811,22 +886,6 @@
}
/**************************************************************************
- * midiInPrepareHeader [WINMM.@]
- */
-UINT WINAPI midiInPrepareHeader(HMIDIIN hMidiIn,
- MIDIHDR* lpMidiInHdr, UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
-
- if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MIDM_PREPARE, (DWORD)lpMidiInHdr, uSize, TRUE);
-}
-
-/**************************************************************************
* midiInPrepareHeader [MMSYSTEM.306]
*/
UINT16 WINAPI midiInPrepareHeader16(HMIDIIN16 hMidiIn, /* [in] */
@@ -2844,26 +903,6 @@
}
/**************************************************************************
- * midiInUnprepareHeader [WINMM.@]
- */
-UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn,
- MIDIHDR* lpMidiInHdr, UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
-
- if (!(lpMidiInHdr->dwFlags & MHDR_PREPARED)) {
- return MMSYSERR_NOERROR;
- }
-
- if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD)lpMidiInHdr, uSize, TRUE);
-}
-
-/**************************************************************************
* midiInUnprepareHeader [MMSYSTEM.307]
*/
UINT16 WINAPI midiInUnprepareHeader16(HMIDIIN16 hMidiIn, /* [in] */
@@ -2886,22 +925,6 @@
}
/**************************************************************************
- * midiInAddBuffer [WINMM.@]
- */
-UINT WINAPI midiInAddBuffer(HMIDIIN hMidiIn,
- MIDIHDR* lpMidiInHdr, UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
-
- if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD)lpMidiInHdr, uSize, TRUE);
-}
-
-/**************************************************************************
* midiInAddBuffer [MMSYSTEM.308]
*/
UINT16 WINAPI midiInAddBuffer16(HMIDIIN16 hMidiIn, /* [in] */
@@ -2919,759 +942,78 @@
}
/**************************************************************************
- * midiInStart [WINMM.@]
- */
-UINT WINAPI midiInStart(HMIDIIN hMidiIn)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X)\n", hMidiIn);
-
- if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MIDM_START, 0L, 0L, TRUE);
-}
-
-/**************************************************************************
* midiInStart [MMSYSTEM.309]
- */
-UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn)
-{
- return midiInStart(HMIDIIN_32(hMidiIn));
-}
-
-/**************************************************************************
- * midiInStop [WINMM.@]
- */
-UINT WINAPI midiInStop(HMIDIIN hMidiIn)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X)\n", hMidiIn);
-
- if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MIDM_STOP, 0L, 0L, TRUE);
-}
-
-/**************************************************************************
- * midiInStop [MMSYSTEM.310]
- */
-UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn)
-{
- return midiInStop(HMIDIIN_32(hMidiIn));
-}
-
-/**************************************************************************
- * midiInReset [WINMM.@]
- */
-UINT WINAPI midiInReset(HMIDIIN hMidiIn)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X)\n", hMidiIn);
-
- if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, MIDM_RESET, 0L, 0L, TRUE);
-}
-
-/**************************************************************************
- * midiInReset [MMSYSTEM.311]
- */
-UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn)
-{
- return midiInReset(HMIDIIN_32(hMidiIn));
-}
-
-/**************************************************************************
- * midiInGetID [WINMM.@]
- */
-UINT WINAPI midiInGetID(HMIDIIN hMidiIn, UINT* lpuDeviceID)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p)\n", hMidiIn, lpuDeviceID);
-
- if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
-
- if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- *lpuDeviceID = wmld->uDeviceID;
-
- return MMSYSERR_NOERROR;
-}
-
-/**************************************************************************
- * midiInGetID [MMSYSTEM.312]
- */
-UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16* lpuDeviceID)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p)\n", hMidiIn, lpuDeviceID);
-
- if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
-
- if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- *lpuDeviceID = wmld->uDeviceID;
-
- return MMSYSERR_NOERROR;
-}
-
-/**************************************************************************
- * midiInMessage [WINMM.@]
- */
-DWORD WINAPI midiInMessage(HMIDIIN hMidiIn, UINT uMessage,
- DWORD dwParam1, DWORD dwParam2)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiIn, uMessage, dwParam1, dwParam2);
-
- if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- switch (uMessage) {
- case MIDM_OPEN:
- case MIDM_CLOSE:
- FIXME("can't handle OPEN or CLOSE message!\n");
- return MMSYSERR_NOTSUPPORTED;
- }
- return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
-}
-
-/**************************************************************************
- * midiInMessage [MMSYSTEM.313]
- */
-DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage,
- DWORD dwParam1, DWORD dwParam2)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiIn, uMessage, dwParam1, dwParam2);
-
- switch (uMessage) {
- case MIDM_OPEN:
- case MIDM_CLOSE:
- FIXME("can't handle OPEN or CLOSE message!\n");
- return MMSYSERR_NOTSUPPORTED;
-
- case MIDM_GETDEVCAPS:
- return midiInGetDevCaps16(hMidiIn, MapSL(dwParam1), dwParam2);
- case MIDM_PREPARE:
- return midiInPrepareHeader16(hMidiIn, dwParam1, dwParam2);
- case MIDM_UNPREPARE:
- return midiInUnprepareHeader16(hMidiIn, dwParam1, dwParam2);
- case MIDM_ADDBUFFER:
- return midiInAddBuffer16(hMidiIn, MapSL(dwParam1), dwParam2);
- }
-
- if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
-}
-
-typedef struct WINE_MIDIStream {
- HMIDIOUT hDevice;
- HANDLE hThread;
- DWORD dwThreadID;
- DWORD dwTempo;
- DWORD dwTimeDiv;
- DWORD dwPositionMS;
- DWORD dwPulses;
- DWORD dwStartTicks;
- WORD wFlags;
- HANDLE hEvent;
- LPMIDIHDR lpMidiHdr;
-} WINE_MIDIStream;
-
-#define WINE_MSM_HEADER (WM_USER+0)
-#define WINE_MSM_STOP (WM_USER+1)
-
-/**************************************************************************
- * MMSYSTEM_GetMidiStream [internal]
- */
-static BOOL MMSYSTEM_GetMidiStream(HMIDISTRM hMidiStrm, WINE_MIDIStream** lpMidiStrm, WINE_MIDI** lplpwm)
-{
- WINE_MIDI* lpwm = (LPWINE_MIDI)MMDRV_Get(hMidiStrm, MMDRV_MIDIOUT, FALSE);
-
- if (lplpwm)
- *lplpwm = lpwm;
-
- if (lpwm == NULL) {
- return FALSE;
- }
-
- *lpMidiStrm = (WINE_MIDIStream*)lpwm->mod.rgIds.dwStreamID;
-
- return *lpMidiStrm != NULL;
-}
-
-/**************************************************************************
- * MMSYSTEM_MidiStream_Convert [internal]
- */
-static DWORD MMSYSTEM_MidiStream_Convert(WINE_MIDIStream* lpMidiStrm, DWORD pulse)
-{
- DWORD ret = 0;
-
- if (lpMidiStrm->dwTimeDiv == 0) {
- FIXME("Shouldn't happen. lpMidiStrm->dwTimeDiv = 0\n");
- } else if (lpMidiStrm->dwTimeDiv > 0x8000) { /* SMPTE, unchecked FIXME? */
- int nf = -(char)HIBYTE(lpMidiStrm->dwTimeDiv); /* number of frames */
- int nsf = LOBYTE(lpMidiStrm->dwTimeDiv); /* number of sub-frames */
- ret = (pulse * 1000) / (nf * nsf);
- } else {
- ret = (DWORD)((double)pulse * ((double)lpMidiStrm->dwTempo / 1000) /
- (double)lpMidiStrm->dwTimeDiv);
- }
-
- return ret;
-}
-
-/**************************************************************************
- * MMSYSTEM_MidiStream_MessageHandler [internal]
- */
-static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWINE_MIDI lpwm, LPMSG msg)
-{
- LPMIDIHDR lpMidiHdr;
- LPMIDIHDR* lpmh;
- LPBYTE lpData;
-
- switch (msg->message) {
- case WM_QUIT:
- SetEvent(lpMidiStrm->hEvent);
- return FALSE;
- case WINE_MSM_STOP:
- TRACE("STOP\n");
- /* this is not quite what MS doc says... */
- midiOutReset(lpMidiStrm->hDevice);
- /* empty list of already submitted buffers */
- for (lpMidiHdr = lpMidiStrm->lpMidiHdr; lpMidiHdr; lpMidiHdr = (LPMIDIHDR)lpMidiHdr->lpNext) {
- lpMidiHdr->dwFlags |= MHDR_DONE;
- lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
-
- DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
- (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
- lpwm->mod.dwInstance, (DWORD)lpMidiHdr, 0L);
- }
- lpMidiStrm->lpMidiHdr = 0;
- SetEvent(lpMidiStrm->hEvent);
- break;
- case WINE_MSM_HEADER:
- /* sets initial tick count for first MIDIHDR */
- if (!lpMidiStrm->dwStartTicks)
- lpMidiStrm->dwStartTicks = GetTickCount();
-
- /* FIXME(EPP): "I don't understand the content of the first MIDIHDR sent
- * by native mcimidi, it doesn't look like a correct one".
- * this trick allows to throw it away... but I don't like it.
- * It looks like part of the file I'm trying to play and definitively looks
- * like raw midi content
- * I'd really like to understand why native mcimidi sends it. Perhaps a bad
- * synchronization issue where native mcimidi is still processing raw MIDI
- * content before generating MIDIEVENTs ?
- *
- * 4c 04 89 3b 00 81 7c 99 3b 43 00 99 23 5e 04 89 L..;..|.;C..#^..
- * 3b 00 00 89 23 00 7c 99 3b 45 00 99 28 62 04 89 ;...#.|.;E..(b..
- * 3b 00 00 89 28 00 81 7c 99 3b 4e 00 99 23 5e 04 ;...(..|.;N..#^.
- * 89 3b 00 00 89 23 00 7c 99 3b 45 00 99 23 78 04 .;...#.|.;E..#x.
- * 89 3b 00 00 89 23 00 81 7c 99 3b 48 00 99 23 5e .;...#..|.;H..#^
- * 04 89 3b 00 00 89 23 00 7c 99 3b 4e 00 99 28 62 ..;...#.|.;N..(b
- * 04 89 3b 00 00 89 28 00 81 7c 99 39 4c 00 99 23 ..;...(..|.9L..#
- * 5e 04 89 39 00 00 89 23 00 82 7c 99 3b 4c 00 99 ^..9...#..|.;L..
- * 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b 48 00 99 #^..;...#.|.;H..
- * 28 62 04 89 3b 00 00 89 28 00 81 7c 99 3b 3f 04 (b..;...(..|.;?.
- * 89 3b 00 1c 99 23 5e 04 89 23 00 5c 99 3b 45 00 .;...#^..#.\.;E.
- * 99 23 78 04 89 3b 00 00 89 23 00 81 7c 99 3b 46 .#x..;...#..|.;F
- * 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b 48 ..#^..;...#.|.;H
- * 00 99 28 62 04 89 3b 00 00 89 28 00 81 7c 99 3b ..(b..;...(..|.;
- * 46 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b F..#^..;...#.|.;
- * 48 00 99 23 78 04 89 3b 00 00 89 23 00 81 7c 99 H..#x..;...#..|.
- * 3b 4c 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 ;L..#^..;...#.|.
- */
- lpMidiHdr = (LPMIDIHDR)msg->lParam;
- lpData = lpMidiHdr->lpData;
- TRACE("Adding %s lpMidiHdr=%p [lpData=0x%08lx dwBufferLength=%lu/%lu dwFlags=0x%08lx size=%u]\n",
- (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular", lpMidiHdr,
- (DWORD)lpMidiHdr, lpMidiHdr->dwBufferLength, lpMidiHdr->dwBytesRecorded,
- lpMidiHdr->dwFlags, msg->wParam);
-#if 0
- /* dumps content of lpMidiHdr->lpData
- * FIXME: there should be a debug routine somewhere that already does this
- * I hate spreading this type of shit all around the code
- */
- for (dwToGo = 0; dwToGo < lpMidiHdr->dwBufferLength; dwToGo += 16) {
- DWORD i;
- BYTE ch;
-
- for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++)
- printf("%02x ", lpData[dwToGo + i]);
- for (; i < 16; i++)
- printf(" ");
- for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++) {
- ch = lpData[dwToGo + i];
- printf("%c", (ch >= 0x20 && ch <= 0x7F) ? ch : '.');
- }
- printf("\n");
- }
-#endif
- if (((LPMIDIEVENT)lpData)->dwStreamID != 0 &&
- ((LPMIDIEVENT)lpData)->dwStreamID != 0xFFFFFFFF &&
- ((LPMIDIEVENT)lpData)->dwStreamID != (DWORD)lpMidiStrm) {
- FIXME("Dropping bad %s lpMidiHdr (streamID=%08lx)\n",
- (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular",
- ((LPMIDIEVENT)lpData)->dwStreamID);
- lpMidiHdr->dwFlags |= MHDR_DONE;
- lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
-
- DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
- (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
- lpwm->mod.dwInstance, (DWORD)lpMidiHdr, 0L);
- break;
- }
-
- for (lpmh = &lpMidiStrm->lpMidiHdr; *lpmh; lpmh = (LPMIDIHDR*)&((*lpmh)->lpNext));
- *lpmh = lpMidiHdr;
- lpMidiHdr = (LPMIDIHDR)msg->lParam;
- lpMidiHdr->lpNext = 0;
- lpMidiHdr->dwFlags |= MHDR_INQUEUE;
- lpMidiHdr->dwFlags &= MHDR_DONE;
- lpMidiHdr->dwOffset = 0;
-
- break;
- default:
- FIXME("Unknown message %d\n", msg->message);
- break;
- }
- return TRUE;
-}
-
-/**************************************************************************
- * MMSYSTEM_MidiStream_Player [internal]
- */
-static DWORD CALLBACK MMSYSTEM_MidiStream_Player(LPVOID pmt)
-{
- WINE_MIDIStream* lpMidiStrm = pmt;
- WINE_MIDI* lpwm;
- MSG msg;
- DWORD dwToGo;
- DWORD dwCurrTC;
- LPMIDIHDR lpMidiHdr;
- LPMIDIEVENT me;
- LPBYTE lpData = 0;
-
- TRACE("(%p)!\n", lpMidiStrm);
-
- if (!lpMidiStrm ||
- (lpwm = (LPWINE_MIDI)MMDRV_Get(lpMidiStrm->hDevice, MMDRV_MIDIOUT, FALSE)) == NULL)
- goto the_end;
-
- /* force thread's queue creation */
- /* Used to be InitThreadInput16(0, 5); */
- /* but following works also with hack in midiStreamOpen */
- PeekMessageA(&msg, 0, 0, 0, 0);
-
- /* FIXME: this next line must be called before midiStreamOut or midiStreamRestart are called */
- SetEvent(lpMidiStrm->hEvent);
- TRACE("Ready to go 1\n");
- /* thread is started in paused mode */
- SuspendThread(lpMidiStrm->hThread);
- TRACE("Ready to go 2\n");
-
- lpMidiStrm->dwStartTicks = 0;
- lpMidiStrm->dwPulses = 0;
-
- lpMidiStrm->lpMidiHdr = 0;
-
- for (;;) {
- lpMidiHdr = lpMidiStrm->lpMidiHdr;
- if (!lpMidiHdr) {
- /* for first message, block until one arrives, then process all that are available */
- GetMessageA(&msg, 0, 0, 0);
- do {
- if (!MMSYSTEM_MidiStream_MessageHandler(lpMidiStrm, lpwm, &msg))
- goto the_end;
- } while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE));
- lpData = 0;
- continue;
- }
-
- if (!lpData)
- lpData = lpMidiHdr->lpData;
-
- me = (LPMIDIEVENT)(lpData + lpMidiHdr->dwOffset);
-
- /* do we have to wait ? */
- if (me->dwDeltaTime) {
- lpMidiStrm->dwPositionMS += MMSYSTEM_MidiStream_Convert(lpMidiStrm, me->dwDeltaTime);
- lpMidiStrm->dwPulses += me->dwDeltaTime;
-
- dwToGo = lpMidiStrm->dwStartTicks + lpMidiStrm->dwPositionMS;
-
- TRACE("%ld/%ld/%ld\n", dwToGo, GetTickCount(), me->dwDeltaTime);
- while ((dwCurrTC = GetTickCount()) < dwToGo) {
- if (MsgWaitForMultipleObjects(0, NULL, FALSE, dwToGo - dwCurrTC, QS_ALLINPUT) == WAIT_OBJECT_0) {
- /* got a message, handle it */
- while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
- if (!MMSYSTEM_MidiStream_MessageHandler(lpMidiStrm, lpwm, &msg))
- goto the_end;
- }
- lpData = 0;
- } else {
- /* timeout, so me->dwDeltaTime is elapsed, can break the while loop */
- break;
- }
- }
- }
- switch (MEVT_EVENTTYPE(me->dwEvent & ~MEVT_F_CALLBACK)) {
- case MEVT_COMMENT:
- FIXME("NIY: MEVT_COMMENT\n");
- /* do nothing, skip bytes */
- break;
- case MEVT_LONGMSG:
- FIXME("NIY: MEVT_LONGMSG, aka sending Sysex event\n");
- break;
- case MEVT_NOP:
- break;
- case MEVT_SHORTMSG:
- midiOutShortMsg(lpMidiStrm->hDevice, MEVT_EVENTPARM(me->dwEvent));
- break;
- case MEVT_TEMPO:
- lpMidiStrm->dwTempo = MEVT_EVENTPARM(me->dwEvent);
- break;
- case MEVT_VERSION:
- break;
- default:
- FIXME("Unknown MEVT (0x%02x)\n", MEVT_EVENTTYPE(me->dwEvent & ~MEVT_F_CALLBACK));
- break;
- }
- if (me->dwEvent & MEVT_F_CALLBACK) {
- DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
- (HDRVR)lpMidiStrm->hDevice, MM_MOM_POSITIONCB,
- lpwm->mod.dwInstance, (LPARAM)lpMidiHdr, 0L);
- }
- lpMidiHdr->dwOffset += sizeof(MIDIEVENT) - sizeof(me->dwParms);
- if (me->dwEvent & MEVT_F_LONG)
- lpMidiHdr->dwOffset += (MEVT_EVENTPARM(me->dwEvent) + 3) & ~3;
- if (lpMidiHdr->dwOffset >= lpMidiHdr->dwBufferLength) {
- /* done with this header */
- lpMidiHdr->dwFlags |= MHDR_DONE;
- lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
-
- lpMidiStrm->lpMidiHdr = (LPMIDIHDR)lpMidiHdr->lpNext;
- DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
- (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
- lpwm->mod.dwInstance, (DWORD)lpMidiHdr, 0L);
- lpData = 0;
- }
- }
-the_end:
- TRACE("End of thread\n");
- ExitThread(0);
- return 0; /* for removing the warning, never executed */
-}
-
-/**************************************************************************
- * MMSYSTEM_MidiStream_PostMessage [internal]
- */
-static BOOL MMSYSTEM_MidiStream_PostMessage(WINE_MIDIStream* lpMidiStrm, WORD msg, DWORD pmt1, DWORD pmt2)
-{
- if (PostThreadMessageA(lpMidiStrm->dwThreadID, msg, pmt1, pmt2)) {
- DWORD count;
-
- ReleaseThunkLock(&count);
- WaitForSingleObject(lpMidiStrm->hEvent, INFINITE);
- RestoreThunkLock(count);
- } else {
- WARN("bad PostThreadMessageA\n");
- return FALSE;
- }
- return TRUE;
-}
-
-/**************************************************************************
- * midiStreamClose [WINMM.@]
- */
-MMRESULT WINAPI midiStreamClose(HMIDISTRM hMidiStrm)
-{
- WINE_MIDIStream* lpMidiStrm;
-
- TRACE("(%08x)!\n", hMidiStrm);
-
- if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
- return MMSYSERR_INVALHANDLE;
-
- midiStreamStop(hMidiStrm);
- MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WM_QUIT, 0, 0);
- HeapFree(GetProcessHeap(), 0, lpMidiStrm);
- CloseHandle(lpMidiStrm->hEvent);
-
- return midiOutClose((HMIDIOUT)hMidiStrm);
-}
-
-/**************************************************************************
- * MMSYSTEM_MidiStream_Open [internal]
- */
-static MMRESULT WINAPI MMSYSTEM_MidiStream_Open(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
- DWORD cMidi, DWORD dwCallback,
- DWORD dwInstance, DWORD fdwOpen, BOOL bFrom32)
-{
- WINE_MIDIStream* lpMidiStrm;
- MMRESULT ret;
- MIDIOPENSTRMID mosm;
- LPWINE_MIDI lpwm;
- HMIDIOUT hMidiOut;
-
- TRACE("(%p, %p, %ld, 0x%08lx, 0x%08lx, 0x%08lx)!\n",
- lphMidiStrm, lpuDeviceID, cMidi, dwCallback, dwInstance, fdwOpen);
-
- if (cMidi != 1 || lphMidiStrm == NULL || lpuDeviceID == NULL)
- return MMSYSERR_INVALPARAM;
-
- lpMidiStrm = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_MIDIStream));
- if (!lpMidiStrm)
- return MMSYSERR_NOMEM;
-
- lpMidiStrm->dwTempo = 500000;
- lpMidiStrm->dwTimeDiv = 480; /* 480 is 120 quater notes per minute *//* FIXME ??*/
- lpMidiStrm->dwPositionMS = 0;
-
- mosm.dwStreamID = (DWORD)lpMidiStrm;
- /* FIXME: the correct value is not allocated yet for MAPPER */
- mosm.wDeviceID = *lpuDeviceID;
- lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &fdwOpen, 1, &mosm, bFrom32);
- lpMidiStrm->hDevice = hMidiOut;
- if (lphMidiStrm)
- *lphMidiStrm = (HMIDISTRM)hMidiOut;
-
- /* FIXME: is lpuDevice initialized upon entering midiStreamOpen ? */
- FIXME("*lpuDeviceID=%x\n", *lpuDeviceID);
- lpwm->mld.uDeviceID = *lpuDeviceID = 0;
-
- ret = MMDRV_Open(&lpwm->mld, MODM_OPEN, (DWORD)&lpwm->mod, fdwOpen);
- lpMidiStrm->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
- lpMidiStrm->wFlags = HIWORD(fdwOpen);
-
- lpMidiStrm->hThread = CreateThread(NULL, 0, MMSYSTEM_MidiStream_Player,
- lpMidiStrm, 0, &(lpMidiStrm->dwThreadID));
-
- if (!lpMidiStrm->hThread) {
- midiStreamClose((HMIDISTRM)hMidiOut);
- return MMSYSERR_NOMEM;
- }
-
- /* wait for thread to have started, and for its queue to be created */
- {
- DWORD count;
-
- /* (Release|Restore)ThunkLock() is needed when this method is called from 16 bit code,
- * (meaning the Win16Lock is set), so that it's released and the 32 bit thread running
- * MMSYSTEM_MidiStreamPlayer can acquire Win16Lock to create its queue.
- */
- ReleaseThunkLock(&count);
- WaitForSingleObject(lpMidiStrm->hEvent, INFINITE);
- RestoreThunkLock(count);
- }
-
- TRACE("=> (%u/%d) hMidi=0x%04x ret=%d lpMidiStrm=%p\n",
- *lpuDeviceID, lpwm->mld.uDeviceID, *lphMidiStrm, ret, lpMidiStrm);
- return ret;
-}
-
-/**************************************************************************
- * midiStreamOpen [WINMM.@]
- */
-MMRESULT WINAPI midiStreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
- DWORD cMidi, DWORD dwCallback,
- DWORD dwInstance, DWORD fdwOpen)
-{
- return MMSYSTEM_MidiStream_Open(lphMidiStrm, lpuDeviceID, cMidi, dwCallback,
- dwInstance, fdwOpen, TRUE);
-}
-
-/**************************************************************************
- * midiStreamOut [WINMM.@]
- */
-MMRESULT WINAPI midiStreamOut(HMIDISTRM hMidiStrm, LPMIDIHDR lpMidiHdr,
- UINT cbMidiHdr)
-{
- WINE_MIDIStream* lpMidiStrm;
- DWORD ret = MMSYSERR_NOERROR;
-
- TRACE("(%08x, %p, %u)!\n", hMidiStrm, lpMidiHdr, cbMidiHdr);
-
- if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
- ret = MMSYSERR_INVALHANDLE;
- } else if (!lpMidiHdr) {
- ret = MMSYSERR_INVALPARAM;
- } else {
- if (!PostThreadMessageA(lpMidiStrm->dwThreadID,
- WINE_MSM_HEADER, cbMidiHdr,
- (DWORD)lpMidiHdr)) {
- WARN("bad PostThreadMessageA\n");
- ret = MMSYSERR_ERROR;
- }
- }
- return ret;
+ */
+UINT16 WINAPI midiInStart16(HMIDIIN16 hMidiIn)
+{
+ return midiInStart(HMIDIIN_32(hMidiIn));
}
/**************************************************************************
- * midiStreamPause [WINMM.@]
+ * midiInStop [MMSYSTEM.310]
*/
-MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
+UINT16 WINAPI midiInStop16(HMIDIIN16 hMidiIn)
{
- WINE_MIDIStream* lpMidiStrm;
- DWORD ret = MMSYSERR_NOERROR;
-
- TRACE("(%08x)!\n", hMidiStrm);
-
- if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
- ret = MMSYSERR_INVALHANDLE;
- } else {
- if (SuspendThread(lpMidiStrm->hThread) == 0xFFFFFFFF) {
- WARN("bad Suspend (%ld)\n", GetLastError());
- ret = MMSYSERR_ERROR;
- }
- }
- return ret;
+ return midiInStop(HMIDIIN_32(hMidiIn));
}
/**************************************************************************
- * midiStreamPosition [WINMM.@]
+ * midiInReset [MMSYSTEM.311]
*/
-MMRESULT WINAPI midiStreamPosition(HMIDISTRM hMidiStrm, LPMMTIME lpMMT, UINT cbmmt)
+UINT16 WINAPI midiInReset16(HMIDIIN16 hMidiIn)
{
- WINE_MIDIStream* lpMidiStrm;
- DWORD ret = MMSYSERR_NOERROR;
-
- TRACE("(%08x, %p, %u)!\n", hMidiStrm, lpMMT, cbmmt);
-
- if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
- ret = MMSYSERR_INVALHANDLE;
- } else if (lpMMT == NULL || cbmmt != sizeof(MMTIME)) {
- ret = MMSYSERR_INVALPARAM;
- } else {
- switch (lpMMT->wType) {
- case TIME_MS:
- lpMMT->u.ms = lpMidiStrm->dwPositionMS;
- TRACE("=> %ld ms\n", lpMMT->u.ms);
- break;
- case TIME_TICKS:
- lpMMT->u.ticks = lpMidiStrm->dwPulses;
- TRACE("=> %ld ticks\n", lpMMT->u.ticks);
- break;
- default:
- WARN("Unsupported time type %d\n", lpMMT->wType);
- lpMMT->wType = TIME_MS;
- ret = MMSYSERR_INVALPARAM;
- break;
- }
- }
- return ret;
+ return midiInReset(HMIDIIN_32(hMidiIn));
}
/**************************************************************************
- * midiStreamProperty [WINMM.@]
+ * midiInGetID [MMSYSTEM.312]
*/
-MMRESULT WINAPI midiStreamProperty(HMIDISTRM hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
+UINT16 WINAPI midiInGetID16(HMIDIIN16 hMidiIn, UINT16* lpuDeviceID)
{
- WINE_MIDIStream* lpMidiStrm;
- MMRESULT ret = MMSYSERR_NOERROR;
+ LPWINE_MLD wmld;
- TRACE("(%08x, %p, %lx)\n", hMidiStrm, lpPropData, dwProperty);
+ TRACE("(%04X, %p)\n", hMidiIn, lpuDeviceID);
- if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
- ret = MMSYSERR_INVALHANDLE;
- } else if ((dwProperty & (MIDIPROP_GET|MIDIPROP_SET)) == 0) {
- ret = MMSYSERR_INVALPARAM;
- } else if (dwProperty & MIDIPROP_TEMPO) {
- MIDIPROPTEMPO* mpt = (MIDIPROPTEMPO*)lpPropData;
-
- if (sizeof(MIDIPROPTEMPO) != mpt->cbStruct) {
- ret = MMSYSERR_INVALPARAM;
- } else if (dwProperty & MIDIPROP_SET) {
- lpMidiStrm->dwTempo = mpt->dwTempo;
- TRACE("Setting tempo to %ld\n", mpt->dwTempo);
- } else if (dwProperty & MIDIPROP_GET) {
- mpt->dwTempo = lpMidiStrm->dwTempo;
- TRACE("Getting tempo <= %ld\n", mpt->dwTempo);
- }
- } else if (dwProperty & MIDIPROP_TIMEDIV) {
- MIDIPROPTIMEDIV* mptd = (MIDIPROPTIMEDIV*)lpPropData;
+ if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
- if (sizeof(MIDIPROPTIMEDIV) != mptd->cbStruct) {
- ret = MMSYSERR_INVALPARAM;
- } else if (dwProperty & MIDIPROP_SET) {
- lpMidiStrm->dwTimeDiv = mptd->dwTimeDiv;
- TRACE("Setting time div to %ld\n", mptd->dwTimeDiv);
- } else if (dwProperty & MIDIPROP_GET) {
- mptd->dwTimeDiv = lpMidiStrm->dwTimeDiv;
- TRACE("Getting time div <= %ld\n", mptd->dwTimeDiv);
- }
- } else {
- ret = MMSYSERR_INVALPARAM;
- }
+ if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
- return ret;
+ *lpuDeviceID = wmld->uDeviceID;
+
+ return MMSYSERR_NOERROR;
}
/**************************************************************************
- * midiStreamRestart [WINMM.@]
+ * midiInMessage [MMSYSTEM.313]
*/
-MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
+DWORD WINAPI midiInMessage16(HMIDIIN16 hMidiIn, UINT16 uMessage,
+ DWORD dwParam1, DWORD dwParam2)
{
- WINE_MIDIStream* lpMidiStrm;
- MMRESULT ret = MMSYSERR_NOERROR;
+ LPWINE_MLD wmld;
- TRACE("(%08x)!\n", hMidiStrm);
+ TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiIn, uMessage, dwParam1, dwParam2);
- if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
- ret = MMSYSERR_INVALHANDLE;
- } else {
- DWORD ret;
+ switch (uMessage) {
+ case MIDM_OPEN:
+ case MIDM_CLOSE:
+ FIXME("can't handle OPEN or CLOSE message!\n");
+ return MMSYSERR_NOTSUPPORTED;
- /* since we increase the thread suspend count on each midiStreamPause
- * there may be a need for several midiStreamResume
- */
- do {
- ret = ResumeThread(lpMidiStrm->hThread);
- } while (ret != 0xFFFFFFFF && ret != 0);
- if (ret == 0xFFFFFFFF) {
- WARN("bad Resume (%ld)\n", GetLastError());
- ret = MMSYSERR_ERROR;
- } else {
- lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwPositionMS;
- }
+ case MIDM_GETDEVCAPS:
+ return midiInGetDevCaps16(hMidiIn, MapSL(dwParam1), dwParam2);
+ case MIDM_PREPARE:
+ return midiInPrepareHeader16(hMidiIn, dwParam1, dwParam2);
+ case MIDM_UNPREPARE:
+ return midiInUnprepareHeader16(hMidiIn, dwParam1, dwParam2);
+ case MIDM_ADDBUFFER:
+ return midiInAddBuffer16(hMidiIn, MapSL(dwParam1), dwParam2);
}
- return ret;
-}
-
-/**************************************************************************
- * midiStreamStop [WINMM.@]
- */
-MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
-{
- WINE_MIDIStream* lpMidiStrm;
- MMRESULT ret = MMSYSERR_NOERROR;
- TRACE("(%08x)!\n", hMidiStrm);
+ if ((wmld = MMDRV_Get(HMIDIIN_32(hMidiIn), MMDRV_MIDIIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
- if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
- ret = MMSYSERR_INVALHANDLE;
- } else {
- /* in case stream has been paused... FIXME is the current state correct ? */
- midiStreamRestart(hMidiStrm);
- MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_STOP, 0, 0);
- }
- return ret;
+ return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, FALSE);
}
/**************************************************************************
@@ -3760,81 +1102,6 @@
return midiStreamStop(HMIDISTRM_32(hMidiStrm));
}
-static UINT WINAPI MMSYSTEM_waveOpen(HANDLE* lphndl, UINT uDeviceID, UINT uType,
- const LPWAVEFORMATEX lpFormat,
- DWORD dwCallback, DWORD dwInstance,
- DWORD dwFlags, BOOL bFrom32)
-{
- HANDLE handle;
- LPWINE_MLD wmld;
- DWORD dwRet = MMSYSERR_NOERROR;
- WAVEOPENDESC wod;
-
- TRACE("(%p, %d, %s, %p, %08lX, %08lX, %08lX, %d);\n",
- lphndl, (int)uDeviceID, (uType==MMDRV_WAVEOUT)?"Out":"In", lpFormat, dwCallback,
- dwInstance, dwFlags, bFrom32?32:16);
-
- if (dwFlags & WAVE_FORMAT_QUERY) TRACE("WAVE_FORMAT_QUERY requested !\n");
-
- if (lpFormat == NULL) return WAVERR_BADFORMAT;
- if ((dwFlags & WAVE_MAPPED) && (uDeviceID == (UINT)-1))
- return MMSYSERR_INVALPARAM;
-
- TRACE("wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u\n",
- lpFormat->wFormatTag, lpFormat->nChannels, lpFormat->nSamplesPerSec,
- lpFormat->nAvgBytesPerSec, lpFormat->nBlockAlign, lpFormat->wBitsPerSample, lpFormat->cbSize);
-
- if ((wmld = MMDRV_Alloc(sizeof(WINE_WAVE), uType, &handle,
- &dwFlags, &dwCallback, &dwInstance, bFrom32)) == NULL)
- return MMSYSERR_NOMEM;
-
- wod.hWave = handle;
- wod.lpFormat = lpFormat; /* should the struct be copied iso pointer? */
- wod.dwCallback = dwCallback;
- wod.dwInstance = dwInstance;
- wod.dnDevNode = 0L;
-
- for (;;) {
- if (dwFlags & WAVE_MAPPED) {
- wod.uMappedDeviceID = uDeviceID;
- uDeviceID = WAVE_MAPPER;
- } else {
- wod.uMappedDeviceID = -1;
- }
- wmld->uDeviceID = uDeviceID;
-
- dwRet = MMDRV_Open(wmld, (uType == MMDRV_WAVEOUT) ? WODM_OPEN : WIDM_OPEN,
- (DWORD)&wod, dwFlags);
-
- if (dwRet != WAVERR_BADFORMAT ||
- (dwFlags & (WAVE_MAPPED|WAVE_FORMAT_DIRECT)) != 0) break;
- /* if we ask for a format which isn't supported by the physical driver,
- * let's try to map it through the wave mapper (except, if we already tried
- * or user didn't allow us to use acm codecs)
- */
- dwFlags |= WAVE_MAPPED;
- /* we shall loop only one */
- }
-
- if ((dwFlags & WAVE_FORMAT_QUERY) || dwRet != MMSYSERR_NOERROR) {
- MMDRV_Free(handle, wmld);
- handle = 0;
- }
-
- if (lphndl != NULL) *lphndl = handle;
- TRACE("=> %ld hWave=%04x\n", dwRet, handle);
-
- return dwRet;
-}
-
-/**************************************************************************
- * waveOutGetNumDevs [WINMM.@]
- */
-UINT WINAPI waveOutGetNumDevs(void)
-{
- return MMDRV_GetNum(MMDRV_WAVEOUT);
-}
-
/**************************************************************************
* waveOutGetNumDevs [MMSYSTEM.401]
*/
@@ -3870,114 +1137,11 @@
}
/**************************************************************************
- * waveOutGetDevCapsA [WINMM.@]
- */
-UINT WINAPI waveOutGetDevCapsA(UINT uDeviceID, LPWAVEOUTCAPSA lpCaps,
- UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%u %p %u)!\n", uDeviceID, lpCaps, uSize);
-
- if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
-
- if ((wmld = MMDRV_Get(uDeviceID, MMDRV_WAVEOUT, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WODM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
-
-}
-
-/**************************************************************************
- * waveOutGetDevCapsW [WINMM.@]
- */
-UINT WINAPI waveOutGetDevCapsW(UINT uDeviceID, LPWAVEOUTCAPSW lpCaps,
- UINT uSize)
-{
- WAVEOUTCAPSA wocA;
- UINT ret;
-
- if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
-
- ret = waveOutGetDevCapsA(uDeviceID, &wocA, sizeof(wocA));
-
- if (ret == MMSYSERR_NOERROR) {
- lpCaps->wMid = wocA.wMid;
- lpCaps->wPid = wocA.wPid;
- lpCaps->vDriverVersion = wocA.vDriverVersion;
- MultiByteToWideChar( CP_ACP, 0, wocA.szPname, -1, lpCaps->szPname,
- sizeof(lpCaps->szPname)/sizeof(WCHAR) );
- lpCaps->dwFormats = wocA.dwFormats;
- lpCaps->wChannels = wocA.wChannels;
- lpCaps->dwSupport = wocA.dwSupport;
- }
- return ret;
-}
-
-/**************************************************************************
- * WAVE_GetErrorText [internal]
- */
-static UINT16 WAVE_GetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
-{
- UINT16 ret = MMSYSERR_BADERRNUM;
-
- if (lpText == NULL) {
- ret = MMSYSERR_INVALPARAM;
- } else if (uSize == 0) {
- ret = MMSYSERR_NOERROR;
- } else if (
- /* test has been removed 'coz MMSYSERR_BASE is 0, and gcc did emit
- * a warning for the test was always true */
- (/*uError >= MMSYSERR_BASE && */uError <= MMSYSERR_LASTERROR) ||
- (uError >= WAVERR_BASE && uError <= WAVERR_LASTERROR)) {
-
- if (LoadStringA(MULTIMEDIA_GetIData()->hWinMM32Instance,
- uError, lpText, uSize) > 0) {
- ret = MMSYSERR_NOERROR;
- }
- }
- return ret;
-}
-
-/**************************************************************************
* waveOutGetErrorText [MMSYSTEM.403]
*/
UINT16 WINAPI waveOutGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
{
- return WAVE_GetErrorText(uError, lpText, uSize);
-}
-
-/**************************************************************************
- * waveOutGetErrorTextA [WINMM.@]
- */
-UINT WINAPI waveOutGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
-{
- return WAVE_GetErrorText(uError, lpText, uSize);
-}
-
-/**************************************************************************
- * waveOutGetErrorTextW [WINMM.@]
- */
-UINT WINAPI waveOutGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
-{
- LPSTR xstr = HeapAlloc(GetProcessHeap(), 0, uSize);
- UINT ret = WAVE_GetErrorText(uError, xstr, uSize);
-
- MultiByteToWideChar( CP_ACP, 0, xstr, -1, lpText, uSize );
- HeapFree(GetProcessHeap(), 0, xstr);
- return ret;
-}
-
-/**************************************************************************
- * waveOutOpen [WINMM.@]
- * All the args/structs have the same layout as the win16 equivalents
- */
-UINT WINAPI waveOutOpen(HWAVEOUT* lphWaveOut, UINT uDeviceID,
- const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
- DWORD dwInstance, DWORD dwFlags)
-{
- return MMSYSTEM_waveOpen(lphWaveOut, uDeviceID, MMDRV_WAVEOUT, lpFormat,
- dwCallback, dwInstance, dwFlags, TRUE);
+ return waveOutGetErrorTextA(uError, lpText, uSize);
}
/**************************************************************************
@@ -4003,25 +1167,6 @@
}
/**************************************************************************
- * waveOutClose [WINMM.@]
- */
-UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
-{
- LPWINE_MLD wmld;
- DWORD dwRet;
-
- TRACE("(%04X)\n", hWaveOut);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- dwRet = MMDRV_Close(wmld, WODM_CLOSE);
- MMDRV_Free(hWaveOut, wmld);
-
- return dwRet;
-}
-
-/**************************************************************************
* waveOutClose [MMSYSTEM.405]
*/
UINT16 WINAPI waveOutClose16(HWAVEOUT16 hWaveOut)
@@ -4036,24 +1181,6 @@
}
/**************************************************************************
- * waveOutPrepareHeader [WINMM.@]
- */
-UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut,
- WAVEHDR* lpWaveOutHdr, UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
-
- if (lpWaveOutHdr == NULL) return MMSYSERR_INVALPARAM;
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WODM_PREPARE, (DWORD)lpWaveOutHdr, uSize, TRUE);
-}
-
-/**************************************************************************
* waveOutPrepareHeader [MMSYSTEM.406]
*/
UINT16 WINAPI waveOutPrepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */
@@ -4074,26 +1201,6 @@
}
/**************************************************************************
- * waveOutUnprepareHeader [WINMM.@]
- */
-UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut,
- LPWAVEHDR lpWaveOutHdr, UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
-
- if (!(lpWaveOutHdr->dwFlags & WHDR_PREPARED)) {
- return MMSYSERR_NOERROR;
- }
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD)lpWaveOutHdr, uSize, TRUE);
-}
-
-/**************************************************************************
* waveOutUnprepareHeader [MMSYSTEM.407]
*/
UINT16 WINAPI waveOutUnprepareHeader16(HWAVEOUT16 hWaveOut, /* [in] */
@@ -4116,22 +1223,6 @@
}
/**************************************************************************
- * waveOutWrite [WINMM.@]
- */
-UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr,
- UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WODM_WRITE, (DWORD)lpWaveOutHdr, uSize, TRUE);
-}
-
-/**************************************************************************
* waveOutWrite [MMSYSTEM.408]
*/
UINT16 WINAPI waveOutWrite16(HWAVEOUT16 hWaveOut, /* [in] */
@@ -4149,20 +1240,6 @@
}
/**************************************************************************
- * waveOutBreakLoop [WINMM.@]
- */
-UINT WINAPI waveOutBreakLoop(HWAVEOUT hWaveOut)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X);\n", hWaveOut);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
- return MMDRV_Message(wmld, WODM_BREAKLOOP, 0L, 0L, TRUE);
-}
-
-/**************************************************************************
* waveOutBreakLoop [MMSYSTEM.419]
*/
UINT16 WINAPI waveOutBreakLoop16(HWAVEOUT16 hWaveOut16)
@@ -4177,20 +1254,6 @@
}
/**************************************************************************
- * waveOutPause [WINMM.@]
- */
-UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X);\n", hWaveOut);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
- return MMDRV_Message(wmld, WODM_PAUSE, 0L, 0L, TRUE);
-}
-
-/**************************************************************************
* waveOutPause [MMSYSTEM.409]
*/
UINT16 WINAPI waveOutPause16(HWAVEOUT16 hWaveOut16)
@@ -4205,20 +1268,6 @@
}
/**************************************************************************
- * waveOutReset [WINMM.@]
- */
-UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X);\n", hWaveOut);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
- return MMDRV_Message(wmld, WODM_RESET, 0L, 0L, TRUE);
-}
-
-/**************************************************************************
* waveOutReset [MMSYSTEM.411]
*/
UINT16 WINAPI waveOutReset16(HWAVEOUT16 hWaveOut16)
@@ -4233,20 +1282,6 @@
}
/**************************************************************************
- * waveOutRestart [WINMM.@]
- */
-UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X);\n", hWaveOut);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
- return MMDRV_Message(wmld, WODM_RESTART, 0L, 0L, TRUE);
-}
-
-/**************************************************************************
* waveOutRestart [MMSYSTEM.410]
*/
UINT16 WINAPI waveOutRestart16(HWAVEOUT16 hWaveOut16)
@@ -4261,22 +1296,6 @@
}
/**************************************************************************
- * waveOutGetPosition [WINMM.@]
- */
-UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, LPMMTIME lpTime,
- UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %u);\n", hWaveOut, lpTime, uSize);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WODM_GETPOS, (DWORD)lpTime, uSize, TRUE);
-}
-
-/**************************************************************************
* waveOutGetPosition [MMSYSTEM.412]
*/
UINT16 WINAPI waveOutGetPosition16(HWAVEOUT16 hWaveOut, LPMMTIME16 lpTime,
@@ -4285,24 +1304,10 @@
UINT ret;
MMTIME mmt;
- mmt.wType = lpTime->wType;
- ret = waveOutGetPosition(HWAVEOUT_32(hWaveOut), &mmt, sizeof(mmt));
- MMSYSTEM_MMTIME32to16(lpTime, &mmt);
- return ret;
-}
-
-/**************************************************************************
- * waveOutGetPitch [WINMM.@]
- */
-UINT WINAPI waveOutGetPitch(HWAVEOUT hWaveOut, LPDWORD lpdw)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %08lx);\n", hWaveOut, (DWORD)lpdw);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
- return MMDRV_Message(wmld, WODM_GETPITCH, (DWORD)lpdw, 0L, TRUE);
+ mmt.wType = lpTime->wType;
+ ret = waveOutGetPosition(HWAVEOUT_32(hWaveOut), &mmt, sizeof(mmt));
+ MMSYSTEM_MMTIME32to16(lpTime, &mmt);
+ return ret;
}
/**************************************************************************
@@ -4314,20 +1319,6 @@
}
/**************************************************************************
- * waveOutSetPitch [WINMM.@]
- */
-UINT WINAPI waveOutSetPitch(HWAVEOUT hWaveOut, DWORD dw)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %08lx);\n", hWaveOut, (DWORD)dw);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
- return MMDRV_Message(wmld, WODM_SETPITCH, dw, 0L, TRUE);
-}
-
-/**************************************************************************
* waveOutSetPitch [MMSYSTEM.414]
*/
UINT16 WINAPI waveOutSetPitch16(HWAVEOUT16 hWaveOut16, DWORD dw)
@@ -4336,20 +1327,6 @@
}
/**************************************************************************
- * waveOutGetPlaybackRate [WINMM.@]
- */
-UINT WINAPI waveOutGetPlaybackRate(HWAVEOUT hWaveOut, LPDWORD lpdw)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %08lx);\n", hWaveOut, (DWORD)lpdw);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
- return MMDRV_Message(wmld, WODM_GETPLAYBACKRATE, (DWORD)lpdw, 0L, TRUE);
-}
-
-/**************************************************************************
* waveOutGetPlaybackRate [MMSYSTEM.417]
*/
UINT16 WINAPI waveOutGetPlaybackRate16(HWAVEOUT16 hWaveOut16, LPDWORD lpdw)
@@ -4358,20 +1335,6 @@
}
/**************************************************************************
- * waveOutSetPlaybackRate [WINMM.@]
- */
-UINT WINAPI waveOutSetPlaybackRate(HWAVEOUT hWaveOut, DWORD dw)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %08lx);\n", hWaveOut, (DWORD)dw);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
- return MMDRV_Message(wmld, WODM_SETPLAYBACKRATE, dw, 0L, TRUE);
-}
-
-/**************************************************************************
* waveOutSetPlaybackRate [MMSYSTEM.418]
*/
UINT16 WINAPI waveOutSetPlaybackRate16(HWAVEOUT16 hWaveOut16, DWORD dw)
@@ -4380,21 +1343,6 @@
}
/**************************************************************************
- * waveOutGetVolume [WINMM.@]
- */
-UINT WINAPI waveOutGetVolume(UINT devid, LPDWORD lpdw)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %08lx);\n", devid, (DWORD)lpdw);
-
- if ((wmld = MMDRV_Get(devid, MMDRV_WAVEOUT, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WODM_GETVOLUME, (DWORD)lpdw, 0L, TRUE);
-}
-
-/**************************************************************************
* waveOutGetVolume [MMSYSTEM.415]
*/
UINT16 WINAPI waveOutGetVolume16(UINT16 devid, LPDWORD lpdw)
@@ -4403,21 +1351,6 @@
}
/**************************************************************************
- * waveOutSetVolume [WINMM.@]
- */
-UINT WINAPI waveOutSetVolume(UINT devid, DWORD dw)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %08lx);\n", devid, dw);
-
- if ((wmld = MMDRV_Get(devid, MMDRV_WAVEOUT, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WODM_SETVOLUME, dw, 0L, TRUE);
-}
-
-/**************************************************************************
* waveOutSetVolume [MMSYSTEM.416]
*/
UINT16 WINAPI waveOutSetVolume16(UINT16 devid, DWORD dw)
@@ -4426,24 +1359,6 @@
}
/**************************************************************************
- * waveOutGetID [WINMM.@]
- */
-UINT WINAPI waveOutGetID(HWAVEOUT hWaveOut, UINT* lpuDeviceID)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p);\n", hWaveOut, lpuDeviceID);
-
- if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- *lpuDeviceID = wmld->uDeviceID;
- return 0;
-}
-
-/**************************************************************************
* waveOutGetID [MMSYSTEM.420]
*/
UINT16 WINAPI waveOutGetID16(HWAVEOUT16 hWaveOut, UINT16* lpuDeviceID)
@@ -4462,30 +1377,6 @@
}
/**************************************************************************
- * waveOutMessage [WINMM.@]
- */
-DWORD WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage,
- DWORD dwParam1, DWORD dwParam2)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04x, %u, %ld, %ld)\n", hWaveOut, uMessage, dwParam1, dwParam2);
-
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL) {
- if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, TRUE)) != NULL) {
- return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
- }
- return MMSYSERR_INVALHANDLE;
- }
-
- /* from M$ KB */
- if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
- return MMSYSERR_INVALPARAM;
-
- return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
-}
-
-/**************************************************************************
* waveOutMessage [MMSYSTEM.421]
*/
DWORD WINAPI waveOutMessage16(HWAVEOUT16 hWaveOut, UINT16 uMessage,
@@ -4510,14 +1401,6 @@
}
/**************************************************************************
- * waveInGetNumDevs [WINMM.@]
- */
-UINT WINAPI waveInGetNumDevs(void)
-{
- return MMDRV_GetNum(MMDRV_WAVEIN);
-}
-
-/**************************************************************************
* waveInGetNumDevs [MMSYSTEM.501]
*/
UINT16 WINAPI waveInGetNumDevs16(void)
@@ -4526,42 +1409,6 @@
}
/**************************************************************************
- * waveInGetDevCapsW [WINMM.@]
- */
-UINT WINAPI waveInGetDevCapsW(UINT uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize)
-{
- WAVEINCAPSA wicA;
- UINT ret = waveInGetDevCapsA(uDeviceID, &wicA, uSize);
-
- if (ret == MMSYSERR_NOERROR) {
- lpCaps->wMid = wicA.wMid;
- lpCaps->wPid = wicA.wPid;
- lpCaps->vDriverVersion = wicA.vDriverVersion;
- MultiByteToWideChar( CP_ACP, 0, wicA.szPname, -1, lpCaps->szPname,
- sizeof(lpCaps->szPname)/sizeof(WCHAR) );
- lpCaps->dwFormats = wicA.dwFormats;
- lpCaps->wChannels = wicA.wChannels;
- }
-
- return ret;
-}
-
-/**************************************************************************
- * waveInGetDevCapsA [WINMM.@]
- */
-UINT WINAPI waveInGetDevCapsA(UINT uDeviceID, LPWAVEINCAPSA lpCaps, UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%u %p %u)!\n", uDeviceID, lpCaps, uSize);
-
- if ((wmld = MMDRV_Get(uDeviceID, MMDRV_WAVEIN, TRUE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WIDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
-}
-
-/**************************************************************************
* waveInGetDevCaps [MMSYSTEM.502]
*/
UINT16 WINAPI waveInGetDevCaps16(UINT16 uDeviceID, LPWAVEINCAPS16 lpCaps,
@@ -4584,43 +1431,11 @@
}
/**************************************************************************
- * waveInGetErrorTextA [WINMM.@]
- */
-UINT WINAPI waveInGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
-{
- return WAVE_GetErrorText(uError, lpText, uSize);
-}
-
-/**************************************************************************
- * waveInGetErrorTextW [WINMM.@]
- */
-UINT WINAPI waveInGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
-{
- LPSTR txt = HeapAlloc(GetProcessHeap(), 0, uSize);
- UINT ret = WAVE_GetErrorText(uError, txt, uSize);
-
- MultiByteToWideChar( CP_ACP, 0, txt, -1, lpText, uSize );
- HeapFree(GetProcessHeap(), 0, txt);
- return ret;
-}
-
-/**************************************************************************
* waveInGetErrorText [MMSYSTEM.503]
*/
UINT16 WINAPI waveInGetErrorText16(UINT16 uError, LPSTR lpText, UINT16 uSize)
{
- return WAVE_GetErrorText(uError, lpText, uSize);
-}
-
-/**************************************************************************
- * waveInOpen [WINMM.@]
- */
-UINT WINAPI waveInOpen(HWAVEIN* lphWaveIn, UINT uDeviceID,
- const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
- DWORD dwInstance, DWORD dwFlags)
-{
- return MMSYSTEM_waveOpen(lphWaveIn, uDeviceID, MMDRV_WAVEIN, lpFormat,
- dwCallback, dwInstance, dwFlags, TRUE);
+ return waveInGetErrorTextA(uError, lpText, uSize);
}
/**************************************************************************
@@ -4646,24 +1461,6 @@
}
/**************************************************************************
- * waveInClose [WINMM.@]
- */
-UINT WINAPI waveInClose(HWAVEIN hWaveIn)
-{
- LPWINE_MLD wmld;
- DWORD dwRet;
-
- TRACE("(%04X)\n", hWaveIn);
-
- if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- dwRet = MMDRV_Message(wmld, WIDM_CLOSE, 0L, 0L, TRUE);
- MMDRV_Free(hWaveIn, wmld);
- return dwRet;
-}
-
-/**************************************************************************
* waveInClose [MMSYSTEM.505]
*/
UINT16 WINAPI waveInClose16(HWAVEIN16 hWaveIn)
@@ -4678,25 +1475,6 @@
}
/**************************************************************************
- * waveInPrepareHeader [WINMM.@]
- */
-UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr,
- UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
-
- if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
- if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- lpWaveInHdr->dwBytesRecorded = 0;
-
- return MMDRV_Message(wmld, WIDM_PREPARE, (DWORD)lpWaveInHdr, uSize, TRUE);
-}
-
-/**************************************************************************
* waveInPrepareHeader [MMSYSTEM.506]
*/
UINT16 WINAPI waveInPrepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
@@ -4720,27 +1498,6 @@
}
/**************************************************************************
- * waveInUnprepareHeader [WINMM.@]
- */
-UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr,
- UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
-
- if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
- if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED)) {
- return MMSYSERR_NOERROR;
- }
-
- if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD)lpWaveInHdr, uSize, TRUE);
-}
-
-/**************************************************************************
* waveInUnprepareHeader [MMSYSTEM.507]
*/
UINT16 WINAPI waveInUnprepareHeader16(HWAVEIN16 hWaveIn, /* [in] */
@@ -4765,23 +1522,6 @@
}
/**************************************************************************
- * waveInAddBuffer [WINMM.@]
- */
-UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn,
- WAVEHDR* lpWaveInHdr, UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
-
- if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
- if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD)lpWaveInHdr, uSize, TRUE);
-}
-
-/**************************************************************************
* waveInAddBuffer [MMSYSTEM.508]
*/
UINT16 WINAPI waveInAddBuffer16(HWAVEIN16 hWaveIn, /* [in] */
@@ -4800,21 +1540,6 @@
}
/**************************************************************************
- * waveInReset [WINMM.@]
- */
-UINT WINAPI waveInReset(HWAVEIN hWaveIn)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X);\n", hWaveIn);
-
- if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WIDM_RESET, 0L, 0L, TRUE);
-}
-
-/**************************************************************************
* waveInReset [MMSYSTEM.511]
*/
UINT16 WINAPI waveInReset16(HWAVEIN16 hWaveIn16)
@@ -4829,21 +1554,6 @@
}
/**************************************************************************
- * waveInStart [WINMM.@]
- */
-UINT WINAPI waveInStart(HWAVEIN hWaveIn)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X);\n", hWaveIn);
-
- if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WIDM_START, 0L, 0L, TRUE);
-}
-
-/**************************************************************************
* waveInStart [MMSYSTEM.509]
*/
UINT16 WINAPI waveInStart16(HWAVEIN16 hWaveIn16)
@@ -4858,21 +1568,6 @@
}
/**************************************************************************
- * waveInStop [WINMM.@]
- */
-UINT WINAPI waveInStop(HWAVEIN hWaveIn)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X);\n", hWaveIn);
-
- if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld,WIDM_STOP, 0L, 0L, TRUE);
-}
-
-/**************************************************************************
* waveInStop [MMSYSTEM.510]
*/
UINT16 WINAPI waveInStop16(HWAVEIN16 hWaveIn16)
@@ -4887,22 +1582,6 @@
}
/**************************************************************************
- * waveInGetPosition [WINMM.@]
- */
-UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, LPMMTIME lpTime,
- UINT uSize)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p, %u);\n", hWaveIn, lpTime, uSize);
-
- if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, WIDM_GETPOS, (DWORD)lpTime, uSize, TRUE);
-}
-
-/**************************************************************************
* waveInGetPosition [MMSYSTEM.512]
*/
UINT16 WINAPI waveInGetPosition16(HWAVEIN16 hWaveIn, LPMMTIME16 lpTime,
@@ -4918,24 +1597,6 @@
}
/**************************************************************************
- * waveInGetID [WINMM.@]
- */
-UINT WINAPI waveInGetID(HWAVEIN hWaveIn, UINT* lpuDeviceID)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04X, %p);\n", hWaveIn, lpuDeviceID);
-
- if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
-
- if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- *lpuDeviceID = wmld->uDeviceID;
- return MMSYSERR_NOERROR;
-}
-
-/**************************************************************************
* waveInGetID [MMSYSTEM.513]
*/
UINT16 WINAPI waveInGetID16(HWAVEIN16 hWaveIn, UINT16* lpuDeviceID)
@@ -4954,26 +1615,6 @@
}
/**************************************************************************
- * waveInMessage [WINMM.@]
- */
-DWORD WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage,
- DWORD dwParam1, DWORD dwParam2)
-{
- LPWINE_MLD wmld;
-
- TRACE("(%04x, %u, %ld, %ld)\n", hWaveIn, uMessage, dwParam1, dwParam2);
-
- /* from M$ KB */
- if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
- return MMSYSERR_INVALPARAM;
-
- if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
- return MMSYSERR_INVALHANDLE;
-
- return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
-}
-
-/**************************************************************************
* waveInMessage [MMSYSTEM.514]
*/
DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
@@ -5124,7 +1765,7 @@
}
}
-DWORD WINAPI GetProcessFlags(DWORD);
+extern DWORD WINAPI GetProcessFlags(DWORD);
/**************************************************************************
* mmThreadCreate [MMSYSTEM.1120]
@@ -5248,9 +1889,6 @@
}
}
-/**************************************************************************
- * MMSYSTEM_ThreadBlock [internal]
- */
static void MMSYSTEM_ThreadBlock(WINE_MMTHREAD* lpMMThd)
{
MSG msg;
Index: dlls/winmm/winemm.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/winemm.h,v
retrieving revision 1.21
diff -u -u -r1.21 winemm.h
--- dlls/winmm/winemm.h 6 Sep 2002 19:41:19 -0000 1.21
+++ dlls/winmm/winemm.h 9 Oct 2002 19:58:54 -0000
@@ -221,8 +221,22 @@
void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16);
void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32);
+UINT MMSYSTEM_mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD dwCallback,
+ DWORD dwInstance, DWORD fdwOpen, BOOL bFrom32);
+UINT MMSYSTEM_midiOutOpen(HMIDIOUT* lphMidiOut, UINT uDeviceID, DWORD dwCallback,
+ DWORD dwInstance, DWORD dwFlags, BOOL bFrom32);
+UINT MMSYSTEM_midiInOpen(HMIDIIN* lphMidiIn, UINT uDeviceID, DWORD dwCallback,
+ DWORD dwInstance, DWORD dwFlags, BOOL bFrom32);
+MMRESULT MMSYSTEM_MidiStream_Open(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
+ DWORD cMidi, DWORD dwCallback,
+ DWORD dwInstance, DWORD fdwOpen, BOOL bFrom32);
+UINT MMSYSTEM_waveOpen(HANDLE* lphndl, UINT uDeviceID, UINT uType,
+ const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
+ DWORD dwInstance, DWORD dwFlags, BOOL bFrom32);
+
BOOL MULTIMEDIA_MciInit(void);
LPWINE_MM_IDATA MULTIMEDIA_GetIData(void);
+BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode);
LPWINE_MM_IDATA TIME_MMTimeStart(void);
void TIME_MMTimeStop(void);
--- /dev/null Thu Jan 1 01:00:00 1970
+++ dlls/winmm/playsound.c Wed Oct 9 22:06:04 2002
@@ -0,0 +1,571 @@
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+
+/*
+ * MMSYTEM functions
+ *
+ * Copyright 1993 Martin Ayotte
+ * 1998-2002 Eric Pouech
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <string.h>
+
+#include "mmsystem.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "heap.h"
+#include "winreg.h"
+#include "winemm.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(winmm);
+
+static HMMIO get_mmioFromFile(LPCWSTR lpszName)
+{
+ HMMIO ret;
+ WCHAR buf[256];
+ LPWSTR dummy;
+
+ ret = mmioOpenW((LPWSTR)lpszName, NULL,
+ MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
+ if (ret != 0) return ret;
+ if (SearchPathW(NULL, lpszName, NULL, sizeof(buf)/sizeof(buf[0]), buf, &dummy))
+ {
+ return mmioOpenW(buf, NULL,
+ MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
+ }
+ return 0;
+}
+
+static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)
+{
+ WCHAR str[128];
+ LPWSTR ptr;
+ HMMIO hmmio;
+ HKEY hRegSnd, hRegApp, hScheme, hSnd;
+ DWORD err, type, count;
+
+ static WCHAR wszSounds[] = {'S','o','u','n','d','s',0};
+ static WCHAR wszDefault[] = {'D','e','f','a','u','l','t',0};
+ static WCHAR wszKey[] = {'A','p','p','E','v','e','n','t','s','\\',
+ 'S','c','h','e','m','e','s','\\',
+ 'A','p','p','s',0};
+ static WCHAR wszDotDefault[] = {'.','D','e','f','a','u','l','t',0};
+ static WCHAR wszNull[] = {0};
+
+ TRACE("searching in SystemSound list for %s\n", debugstr_w(lpszName));
+ GetProfileStringW(wszSounds, (LPWSTR)lpszName, wszNull, str, sizeof(str)/sizeof(str[0]));
+ if (lstrlenW(str) == 0)
+ {
+ if (uFlags & SND_NODEFAULT) goto next;
+ GetProfileStringW(wszSounds, wszDefault, wszNull, str, sizeof(str)/sizeof(str[0]));
+ if (lstrlenW(str) == 0) goto next;
+ }
+ for (ptr = str; *ptr && *ptr != ','; ptr++);
+ if (*ptr) *ptr = 0;
+ hmmio = mmioOpenW(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
+ if (hmmio != 0) return hmmio;
+ next:
+ /* we look up the registry under
+ * HKCU\AppEvents\Schemes\Apps\.Default
+ * HKCU\AppEvents\Schemes\Apps\<AppName>
+ */
+ if (RegOpenKeyW(HKEY_CURRENT_USER, wszKey, &hRegSnd) != 0) goto none;
+ if (uFlags & SND_APPLICATION)
+ {
+ err = 1; /* error */
+ if (GetModuleFileNameW(0, str, sizeof(str)/sizeof(str[0])))
+ {
+ for (ptr = str + lstrlenW(str) - 1; ptr >= str; ptr--)
+ {
+ if (*ptr == '.') *ptr = 0;
+ if (*ptr == '\\')
+ {
+ err = RegOpenKeyW(hRegSnd, str, &hRegApp);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ err = RegOpenKeyW(hRegSnd, wszDotDefault, &hRegApp);
+ }
+ RegCloseKey(hRegSnd);
+ if (err != 0) goto none;
+ err = RegOpenKeyW(hRegApp, lpszName, &hScheme);
+ RegCloseKey(hRegApp);
+ if (err != 0) goto none;
+ err = RegOpenKeyW(hScheme, wszDotDefault, &hSnd);
+ RegCloseKey(hScheme);
+ if (err != 0) goto none;
+ count = sizeof(str)/sizeof(str[0]);
+ err = RegQueryValueExW(hSnd, NULL, 0, &type, (LPBYTE)str, &count);
+ RegCloseKey(hSnd);
+ if (err != 0 || !*str) goto none;
+ hmmio = mmioOpenW(str, NULL, MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
+ if (hmmio) return hmmio;
+ none:
+ WARN("can't find SystemSound='%s' !\n", debugstr_w(lpszName));
+ return 0;
+}
+
+struct playsound_data
+{
+ HANDLE hEvent;
+ DWORD dwEventCount;
+};
+
+static void CALLBACK PlaySound_Callback(HWAVEOUT hwo, UINT uMsg,
+ DWORD dwInstance,
+ DWORD dwParam1, DWORD dwParam2)
+{
+ struct playsound_data* s = (struct playsound_data*)dwInstance;
+
+ switch (uMsg) {
+ case WOM_OPEN:
+ case WOM_CLOSE:
+ break;
+ case WOM_DONE:
+ InterlockedIncrement(&s->dwEventCount);
+ TRACE("Returning waveHdr=%lx\n", dwParam1);
+ SetEvent(s->hEvent);
+ break;
+ default:
+ ERR("Unknown uMsg=%d\n", uMsg);
+ }
+}
+
+static void PlaySound_WaitDone(struct playsound_data* s)
+{
+ for (;;) {
+ ResetEvent(s->hEvent);
+ if (InterlockedDecrement(&s->dwEventCount) >= 0) break;
+ InterlockedIncrement(&s->dwEventCount);
+
+ WaitForSingleObject(s->hEvent, INFINITE);
+ }
+}
+
+static BOOL PlaySound_IsString(DWORD fdwSound, const void* psz)
+{
+ /* SND_RESOURCE is 0x40004 while
+ * SND_MEMORY is 0x00004
+ */
+ switch (fdwSound & (SND_RESOURCE|SND_ALIAS|SND_FILENAME))
+ {
+ case SND_RESOURCE: return HIWORD(psz) != 0; /* by name or by ID ? */
+ case SND_MEMORY: return FALSE;
+ case SND_ALIAS: /* what about ALIAS_ID ??? */
+ case SND_FILENAME:
+ case 0: return TRUE;
+ default: FIXME("WTF\n"); return FALSE;
+ }
+}
+
+static void PlaySound_Free(WINE_PLAYSOUND* wps)
+{
+ LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
+ WINE_PLAYSOUND** p;
+
+ EnterCriticalSection(&iData->cs);
+ for (p = &iData->lpPlaySound; *p && *p != wps; p = &((*p)->lpNext));
+ if (*p) *p = (*p)->lpNext;
+ if (iData->lpPlaySound == NULL) SetEvent(iData->psLastEvent);
+ LeaveCriticalSection(&iData->cs);
+ if (wps->bAlloc) HeapFree(GetProcessHeap(), 0, (void*)wps->pszSound);
+ HeapFree(GetProcessHeap(), 0, wps);
+}
+
+static WINE_PLAYSOUND* PlaySound_Alloc(const void* pszSound, HMODULE hmod,
+ DWORD fdwSound, BOOL bUnicode)
+{
+ WINE_PLAYSOUND* wps;
+
+ wps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wps));
+ if (!wps) return NULL;
+
+ wps->hMod = hmod;
+ wps->fdwSound = fdwSound;
+ if (PlaySound_IsString(fdwSound, pszSound))
+ {
+ if (bUnicode)
+ {
+ if (fdwSound & SND_ASYNC)
+ {
+ wps->pszSound = HeapAlloc(GetProcessHeap(), 0,
+ (lstrlenW(pszSound)+1) * sizeof(WCHAR));
+ if (!wps->pszSound) goto oom_error;
+ lstrcpyW((LPWSTR)wps->pszSound, pszSound);
+ wps->bAlloc = TRUE;
+ }
+ else
+ wps->pszSound = pszSound;
+ }
+ else
+ {
+ wps->pszSound = HEAP_strdupAtoW(GetProcessHeap(), 0, pszSound);
+ if (!wps->pszSound) goto oom_error;
+ wps->bAlloc = TRUE;
+ }
+ }
+ else
+ wps->pszSound = pszSound;
+
+ return wps;
+ oom_error:
+ PlaySound_Free(wps);
+ return NULL;
+}
+
+static DWORD WINAPI proc_PlaySound(LPVOID arg)
+{
+ WINE_PLAYSOUND* wps = (WINE_PLAYSOUND*)arg;
+ LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
+ BOOL bRet = FALSE;
+ HMMIO hmmio = 0;
+ MMCKINFO ckMainRIFF;
+ MMCKINFO mmckInfo;
+ LPWAVEFORMATEX lpWaveFormat = NULL;
+ HWAVEOUT hWave = 0;
+ LPWAVEHDR waveHdr = NULL;
+ INT count, bufsize, left, index;
+ struct playsound_data s;
+ void* data;
+
+ s.hEvent = 0;
+
+ TRACE("SoundName='%s' !\n", debugstr_w(wps->pszSound));
+
+ /* if resource, grab it */
+ if ((wps->fdwSound & SND_RESOURCE) == SND_RESOURCE) {
+ static WCHAR wszWave[] = {'W','A','V','E',0};
+ HRSRC hRes;
+ HGLOBAL hGlob;
+
+ if ((hRes = FindResourceW(wps->hMod, wps->pszSound, wszWave)) == 0 ||
+ (hGlob = LoadResource(wps->hMod, hRes)) == 0)
+ goto errCleanUp;
+ if ((data = LockResource(hGlob)) == NULL) {
+ FreeResource(hGlob);
+ goto errCleanUp;
+ }
+ FreeResource(hGlob);
+ } else
+ data = (void*)wps->pszSound;
+
+ /* construct an MMIO stream (either in memory, or from a file */
+ if (wps->fdwSound & SND_MEMORY)
+ { /* NOTE: SND_RESOURCE has the SND_MEMORY bit set */
+ MMIOINFO mminfo;
+
+ memset(&mminfo, 0, sizeof(mminfo));
+ mminfo.fccIOProc = FOURCC_MEM;
+ mminfo.pchBuffer = (LPSTR)data;
+ mminfo.cchBuffer = -1; /* FIXME: when a resource, could grab real size */
+ TRACE("Memory sound %p\n", data);
+ hmmio = mmioOpenW(NULL, &mminfo, MMIO_READ);
+ }
+ else if (wps->fdwSound & SND_ALIAS)
+ {
+ hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
+ }
+ else if (wps->fdwSound & SND_FILENAME)
+ {
+ hmmio = get_mmioFromFile(wps->pszSound);
+ }
+ else
+ {
+ if ((hmmio = get_mmioFromProfile(wps->fdwSound | SND_NODEFAULT, wps->pszSound)) == 0)
+ {
+ if ((hmmio = get_mmioFromFile(wps->pszSound)) == 0)
+ {
+ hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
+ }
+ }
+ }
+ if (hmmio == 0) goto errCleanUp;
+
+ if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0))
+ goto errCleanUp;
+
+ TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
+ (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
+
+ if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
+ (ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E')))
+ goto errCleanUp;
+
+ mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
+ if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
+ goto errCleanUp;
+
+ TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
+ (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
+
+ lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
+ if (mmioRead(hmmio, (HPSTR)lpWaveFormat, mmckInfo.cksize) < sizeof(WAVEFORMAT))
+ goto errCleanUp;
+
+ TRACE("wFormatTag=%04X !\n", lpWaveFormat->wFormatTag);
+ TRACE("nChannels=%d \n", lpWaveFormat->nChannels);
+ TRACE("nSamplesPerSec=%ld\n", lpWaveFormat->nSamplesPerSec);
+ TRACE("nAvgBytesPerSec=%ld\n", lpWaveFormat->nAvgBytesPerSec);
+ TRACE("nBlockAlign=%d \n", lpWaveFormat->nBlockAlign);
+ TRACE("wBitsPerSample=%u !\n", lpWaveFormat->wBitsPerSample);
+
+ /* move to end of 'fmt ' chunk */
+ mmioAscend(hmmio, &mmckInfo, 0);
+
+ mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
+ if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
+ goto errCleanUp;
+
+ TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX\n",
+ (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
+
+ s.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
+
+ if (waveOutOpen(&hWave, WAVE_MAPPER, lpWaveFormat, (DWORD)PlaySound_Callback,
+ (DWORD)&s, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
+ goto errCleanUp;
+
+ /* make it so that 3 buffers per second are needed */
+ bufsize = (((lpWaveFormat->nAvgBytesPerSec / 3) - 1) / lpWaveFormat->nBlockAlign + 1) *
+ lpWaveFormat->nBlockAlign;
+ waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize);
+ waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
+ waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
+ waveHdr[0].dwUser = waveHdr[1].dwUser = 0L;
+ waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
+ waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
+ waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
+ if (waveOutPrepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
+ waveOutPrepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR))) {
+ goto errCleanUp;
+ }
+
+ s.dwEventCount = 1L; /* for first buffer */
+
+ do {
+ index = 0;
+ left = mmckInfo.cksize;
+
+ mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET);
+ while (left)
+ {
+ if (WaitForSingleObject(iData->psStopEvent, 0) == WAIT_OBJECT_0)
+ {
+ wps->bLoop = FALSE;
+ break;
+ }
+ count = mmioRead(hmmio, waveHdr[index].lpData, min(bufsize, left));
+ if (count < 1) break;
+ left -= count;
+ waveHdr[index].dwBufferLength = count;
+ waveHdr[index].dwFlags &= ~WHDR_DONE;
+ if (waveOutWrite(hWave, &waveHdr[index], sizeof(WAVEHDR)) == MMSYSERR_NOERROR) {
+ index ^= 1;
+ PlaySound_WaitDone(&s);
+ }
+ else FIXME("Couldn't play header\n");
+ }
+ bRet = TRUE;
+ } while (wps->bLoop);
+
+ PlaySound_WaitDone(&s); /* for last buffer */
+ waveOutReset(hWave);
+
+ waveOutUnprepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR));
+ waveOutUnprepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR));
+
+errCleanUp:
+ TRACE("Done playing='%s' => %s!\n", debugstr_w(wps->pszSound), bRet ? "ok" : "ko");
+ CloseHandle(s.hEvent);
+ if (waveHdr) HeapFree(GetProcessHeap(), 0, waveHdr);
+ if (lpWaveFormat) HeapFree(GetProcessHeap(), 0, lpWaveFormat);
+ if (hWave) while (waveOutClose(hWave) == WAVERR_STILLPLAYING) Sleep(100);
+ if (hmmio) mmioClose(hmmio, 0);
+
+ PlaySound_Free(wps);
+
+ return bRet;
+}
+
+BOOL MULTIMEDIA_PlaySound(const void* pszSound, HMODULE hmod, DWORD fdwSound, BOOL bUnicode)
+{
+ WINE_PLAYSOUND* wps = NULL;
+ LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
+
+ TRACE("pszSound='%p' hmod=%04X fdwSound=%08lX\n",
+ pszSound, hmod, fdwSound);
+
+ /* FIXME? I see no difference between SND_NOWAIT and SND_NOSTOP !
+ * there could be one if several sounds can be played at once...
+ */
+ if ((fdwSound & (SND_NOWAIT | SND_NOSTOP)) && iData->lpPlaySound != NULL)
+ return FALSE;
+
+ /* alloc internal structure, if we need to play something */
+ if (pszSound && !(fdwSound & SND_PURGE))
+ {
+ if (!(wps = PlaySound_Alloc(pszSound, hmod, fdwSound, bUnicode)))
+ return FALSE;
+ }
+
+ EnterCriticalSection(&iData->cs);
+ /* since several threads can enter PlaySound in parallel, we're not
+ * sure, at this point, that another thread didn't start a new playsound
+ */
+ while (iData->lpPlaySound != NULL)
+ {
+ ResetEvent(iData->psLastEvent);
+ /* FIXME: doc says we have to stop all instances of pszSound if it's non
+ * NULL... as of today, we stop all playing instances */
+ SetEvent(iData->psStopEvent);
+
+ LeaveCriticalSection(&iData->cs);
+ WaitForSingleObject(iData->psLastEvent, INFINITE);
+ EnterCriticalSection(&iData->cs);
+
+ ResetEvent(iData->psStopEvent);
+ }
+
+ if (wps) wps->lpNext = iData->lpPlaySound;
+ iData->lpPlaySound = wps;
+ LeaveCriticalSection(&iData->cs);
+
+ if (!pszSound || (fdwSound & SND_PURGE)) return TRUE;
+
+ if (fdwSound & SND_ASYNC)
+ {
+ DWORD id;
+ wps->bLoop = (fdwSound & SND_LOOP) ? TRUE : FALSE;
+ if (CreateThread(NULL, 0, proc_PlaySound, wps, 0, &id) != 0)
+ return TRUE;
+ }
+ else return proc_PlaySound(wps);
+
+ /* error cases */
+ PlaySound_Free(wps);
+ return FALSE;
+}
+
+/**************************************************************************
+ * PlaySoundA [WINMM.@]
+ */
+BOOL WINAPI PlaySoundA(LPCSTR pszSoundA, HMODULE hmod, DWORD fdwSound)
+{
+ return MULTIMEDIA_PlaySound(pszSoundA, hmod, fdwSound, FALSE);
+}
+
+/**************************************************************************
+ * PlaySoundW [WINMM.@]
+ */
+BOOL WINAPI PlaySoundW(LPCWSTR pszSoundW, HMODULE hmod, DWORD fdwSound)
+{
+ return MULTIMEDIA_PlaySound(pszSoundW, hmod, fdwSound, TRUE);
+}
+
+/**************************************************************************
+ * sndPlaySoundA [WINMM.@]
+ */
+BOOL WINAPI sndPlaySoundA(LPCSTR pszSoundA, UINT uFlags)
+{
+ uFlags &= SND_ASYNC|SND_LOOP|SND_MEMORY|SND_NODEFAULT|SND_NOSTOP|SND_SYNC;
+ return MULTIMEDIA_PlaySound(pszSoundA, 0, uFlags, FALSE);
+}
+
+/**************************************************************************
+ * sndPlaySoundW [WINMM.@]
+ */
+BOOL WINAPI sndPlaySoundW(LPCWSTR pszSound, UINT uFlags)
+{
+ uFlags &= SND_ASYNC|SND_LOOP|SND_MEMORY|SND_NODEFAULT|SND_NOSTOP|SND_SYNC;
+ return MULTIMEDIA_PlaySound(pszSound, 0, uFlags, TRUE);
+}
+
+/**************************************************************************
+ * mmsystemGetVersion [WINMM.@]
+ */
+UINT WINAPI mmsystemGetVersion(void)
+{
+ TRACE("3.10 (Win95?)\n");
+ return 0x030a;
+}
+
+/**************************************************************************
+ * DriverCallback [WINMM.@]
+ */
+BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev,
+ UINT wMsg, DWORD dwUser, DWORD dwParam1,
+ DWORD dwParam2)
+{
+ TRACE("(%08lX, %04X, %04X, %04X, %08lX, %08lX, %08lX); !\n",
+ dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);
+
+ switch (uFlags & DCB_TYPEMASK) {
+ case DCB_NULL:
+ TRACE("Null !\n");
+ if (dwCallBack)
+ WARN("uFlags=%04X has null DCB value, but dwCallBack=%08lX is not null !\n", uFlags, dwCallBack);
+ break;
+ case DCB_WINDOW:
+ TRACE("Window(%04lX) handle=%04X!\n", dwCallBack, hDev);
+ PostMessageA((HWND)dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
+ break;
+ case DCB_TASK: /* aka DCB_THREAD */
+ TRACE("Task(%04lx) !\n", dwCallBack);
+ PostThreadMessageA(dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
+ break;
+ case DCB_FUNCTION:
+ TRACE("Function (32 bit) !\n");
+ ((LPDRVCALLBACK)dwCallBack)(hDev, wMsg, dwUser, dwParam1, dwParam2);
+ break;
+ case DCB_EVENT:
+ TRACE("Event(%08lx) !\n", dwCallBack);
+ SetEvent((HANDLE)dwCallBack);
+ break;
+ case 6: /* I would dub it DCB_MMTHREADSIGNAL */
+ /* this is an undocumented DCB_ value used for mmThreads
+ * loword of dwCallBack contains the handle of the lpMMThd block
+ * which dwSignalCount has to be incremented
+ */
+ {
+ WINE_MMTHREAD* lpMMThd = MapSL( MAKESEGPTR(LOWORD(dwCallBack), 0) );
+
+ TRACE("mmThread (%04x, %p) !\n", LOWORD(dwCallBack), lpMMThd);
+ /* same as mmThreadSignal16 */
+ InterlockedIncrement(&lpMMThd->dwSignalCount);
+ SetEvent(lpMMThd->hEvent);
+ /* some other stuff on lpMMThd->hVxD */
+ }
+ break;
+#if 0
+ case 4:
+ /* this is an undocumented DCB_ value for... I don't know */
+ break;
+#endif
+ default:
+ WARN("Unknown callback type %d\n", uFlags & DCB_TYPEMASK);
+ return FALSE;
+ }
+ TRACE("Done\n");
+ return TRUE;
+}
+
--- /dev/null Thu Jan 1 01:00:00 1970
+++ dlls/winmm/winmm.c Wed Oct 9 22:17:07 2002
@@ -0,0 +1,2879 @@
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+
+/*
+ * MMSYTEM functions
+ *
+ * Copyright 1993 Martin Ayotte
+ * 1998-2002 Eric Pouech
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Eric POUECH :
+ * 98/9 added Win32 MCI support
+ * 99/4 added midiStream support
+ * 99/9 added support for loadable low level drivers
+ */
+
+#include <string.h>
+
+#include "mmsystem.h"
+#include "winbase.h"
+#include "wingdi.h"
+
+#include "winuser.h"
+#include "wine/winuser16.h" /* FIXME: should be removed */
+#include "heap.h"
+#include "winternl.h"
+#include "winemm.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(winmm);
+
+/* ========================================================================
+ * T I M E C O N V E R S I O N F U N C T I O N S
+ * ========================================================================*/
+
+/* FIXME: should be in mmsystem.c */
+
+void MMSYSTEM_MMTIME32to16(LPMMTIME16 mmt16, const MMTIME* mmt32)
+{
+ mmt16->wType = mmt32->wType;
+ /* layout of rest is the same for 32/16,
+ * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
+ */
+ memcpy(&(mmt16->u), &(mmt32->u), sizeof(mmt16->u));
+}
+
+void MMSYSTEM_MMTIME16to32(LPMMTIME mmt32, const MMTIME16* mmt16)
+{
+ mmt32->wType = mmt16->wType;
+ /* layout of rest is the same for 32/16,
+ * Note: mmt16->u is 2 bytes smaller than mmt32->u, which has padding
+ */
+ memcpy(&(mmt32->u), &(mmt16->u), sizeof(mmt16->u));
+}
+
+/* ========================================================================
+ * G L O B A L S E T T I N G S
+ * ========================================================================*/
+
+static LPWINE_MM_IDATA lpFirstIData = NULL;
+
+static LPWINE_MM_IDATA MULTIMEDIA_GetIDataNoCheck(void)
+{
+ DWORD pid = GetCurrentProcessId();
+ LPWINE_MM_IDATA iData;
+
+ for (iData = lpFirstIData; iData; iData = iData->lpNextIData) {
+ if (iData->dwThisProcess == pid)
+ break;
+ }
+ return iData;
+}
+
+/**************************************************************************
+ * MULTIMEDIA_GetIData [internal]
+ */
+LPWINE_MM_IDATA MULTIMEDIA_GetIData(void)
+{
+ LPWINE_MM_IDATA iData = MULTIMEDIA_GetIDataNoCheck();
+
+ if (!iData) {
+ ERR("IData not found for pid=%08lx. Suicide !!!\n", GetCurrentProcessId());
+ DbgBreakPoint();
+ ExitProcess(0);
+ }
+ return iData;
+}
+
+/**************************************************************************
+ * MULTIMEDIA_CreateIData [internal]
+ */
+static BOOL MULTIMEDIA_CreateIData(HINSTANCE hInstDLL)
+{
+ LPWINE_MM_IDATA iData;
+
+ iData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MM_IDATA));
+
+ if (!iData)
+ return FALSE;
+ iData->hWinMM32Instance = hInstDLL;
+ iData->dwThisProcess = GetCurrentProcessId();
+ iData->lpNextIData = lpFirstIData;
+ lpFirstIData = iData;
+ InitializeCriticalSection(&iData->cs);
+ iData->cs.DebugInfo = (void*)__FILE__ ": WinMM";
+ iData->psStopEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
+ iData->psLastEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
+ TRACE("Created IData (%p) for pid %08lx\n", iData, iData->dwThisProcess);
+ return TRUE;
+}
+
+/**************************************************************************
+ * MULTIMEDIA_DeleteIData [internal]
+ */
+static void MULTIMEDIA_DeleteIData(void)
+{
+ LPWINE_MM_IDATA iData = MULTIMEDIA_GetIDataNoCheck();
+ LPWINE_MM_IDATA* ppid;
+
+ if (iData) {
+ TIME_MMTimeStop();
+
+ for (ppid = &lpFirstIData; *ppid; ppid = &(*ppid)->lpNextIData) {
+ if (*ppid == iData) {
+ *ppid = iData->lpNextIData;
+ break;
+ }
+ }
+ /* FIXME: should also free content and resources allocated
+ * inside iData */
+ CloseHandle(iData->psStopEvent);
+ CloseHandle(iData->psLastEvent);
+ DeleteCriticalSection(&iData->cs);
+ HeapFree(GetProcessHeap(), 0, iData);
+ }
+}
+
+/**************************************************************************
+ * DllEntryPoint (WINMM.init)
+ *
+ * WINMM DLL entry point
+ *
+ */
+BOOL WINAPI WINMM_LibMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
+{
+ TRACE("0x%x 0x%lx %p\n", hInstDLL, fdwReason, fImpLoad);
+
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ if (!MULTIMEDIA_CreateIData(hInstDLL))
+ return FALSE;
+ if (!MULTIMEDIA_MciInit() || !MMDRV_Init()) {
+ MULTIMEDIA_DeleteIData();
+ return FALSE;
+ }
+ break;
+ case DLL_PROCESS_DETACH:
+ MULTIMEDIA_DeleteIData();
+ break;
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
+/**************************************************************************
+ * Mixer devices. New to Win95
+ */
+
+/**************************************************************************
+ * find out the real mixer ID depending on hmix (depends on dwFlags)
+ */
+static LPWINE_MIXER MIXER_GetDev(HMIXEROBJ hmix, DWORD dwFlags)
+{
+ LPWINE_MIXER lpwm = NULL;
+
+ switch (dwFlags & 0xF0000000ul) {
+ case MIXER_OBJECTF_MIXER:
+ lpwm = (LPWINE_MIXER)MMDRV_Get(hmix, MMDRV_MIXER, TRUE);
+ break;
+ case MIXER_OBJECTF_HMIXER:
+ lpwm = (LPWINE_MIXER)MMDRV_Get(hmix, MMDRV_MIXER, FALSE);
+ break;
+ case MIXER_OBJECTF_WAVEOUT:
+ lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_WAVEOUT, TRUE, MMDRV_MIXER);
+ break;
+ case MIXER_OBJECTF_HWAVEOUT:
+ lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_WAVEOUT, FALSE, MMDRV_MIXER);
+ break;
+ case MIXER_OBJECTF_WAVEIN:
+ lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_WAVEIN, TRUE, MMDRV_MIXER);
+ break;
+ case MIXER_OBJECTF_HWAVEIN:
+ lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_WAVEIN, FALSE, MMDRV_MIXER);
+ break;
+ case MIXER_OBJECTF_MIDIOUT:
+ lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_MIDIOUT, TRUE, MMDRV_MIXER);
+ break;
+ case MIXER_OBJECTF_HMIDIOUT:
+ lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_MIDIOUT, FALSE, MMDRV_MIXER);
+ break;
+ case MIXER_OBJECTF_MIDIIN:
+ lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_MIDIIN, TRUE, MMDRV_MIXER);
+ break;
+ case MIXER_OBJECTF_HMIDIIN:
+ lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_MIDIIN, FALSE, MMDRV_MIXER);
+ break;
+ case MIXER_OBJECTF_AUX:
+ lpwm = (LPWINE_MIXER)MMDRV_GetRelated(hmix, MMDRV_AUX, TRUE, MMDRV_MIXER);
+ break;
+ default:
+ FIXME("Unsupported flag (%08lx)\n", dwFlags & 0xF0000000ul);
+ break;
+ }
+ return lpwm;
+}
+
+/**************************************************************************
+ * mixerGetNumDevs [WINMM.@]
+ */
+UINT WINAPI mixerGetNumDevs(void)
+{
+ return MMDRV_GetNum(MMDRV_MIXER);
+}
+
+/**************************************************************************
+ * mixerGetDevCapsA [WINMM.@]
+ */
+UINT WINAPI mixerGetDevCapsA(UINT devid, LPMIXERCAPSA mixcaps, UINT size)
+{
+ LPWINE_MLD wmld;
+
+ if ((wmld = MMDRV_Get(devid, MMDRV_MIXER, TRUE)) == NULL)
+ return MMSYSERR_BADDEVICEID;
+
+ return MMDRV_Message(wmld, MXDM_GETDEVCAPS, (DWORD)mixcaps, size, TRUE);
+}
+
+/**************************************************************************
+ * mixerGetDevCapsW [WINMM.@]
+ */
+UINT WINAPI mixerGetDevCapsW(UINT devid, LPMIXERCAPSW mixcaps, UINT size)
+{
+ MIXERCAPSA micA;
+ UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
+
+ if (ret == MMSYSERR_NOERROR) {
+ mixcaps->wMid = micA.wMid;
+ mixcaps->wPid = micA.wPid;
+ mixcaps->vDriverVersion = micA.vDriverVersion;
+ MultiByteToWideChar( CP_ACP, 0, micA.szPname, -1, mixcaps->szPname,
+ sizeof(mixcaps->szPname)/sizeof(WCHAR) );
+ mixcaps->fdwSupport = micA.fdwSupport;
+ mixcaps->cDestinations = micA.cDestinations;
+ }
+ return ret;
+}
+
+UINT MMSYSTEM_mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD dwCallback,
+ DWORD dwInstance, DWORD fdwOpen, BOOL bFrom32)
+{
+ HMIXER hMix;
+ LPWINE_MLD wmld;
+ DWORD dwRet = 0;
+ MIXEROPENDESC mod;
+
+ TRACE("(%p, %d, %08lx, %08lx, %08lx)\n",
+ lphMix, uDeviceID, dwCallback, dwInstance, fdwOpen);
+
+ wmld = MMDRV_Alloc(sizeof(WINE_MIXER), MMDRV_MIXER, &hMix, &fdwOpen,
+ &dwCallback, &dwInstance, bFrom32);
+
+ wmld->uDeviceID = uDeviceID;
+ mod.hmx = (HMIXEROBJ)hMix;
+ mod.dwCallback = dwCallback;
+ mod.dwInstance = dwInstance;
+
+ dwRet = MMDRV_Open(wmld, MXDM_OPEN, (DWORD)&mod, fdwOpen);
+
+ if (dwRet != MMSYSERR_NOERROR) {
+ MMDRV_Free(hMix, wmld);
+ hMix = 0;
+ }
+ if (lphMix) *lphMix = hMix;
+ TRACE("=> %ld hMixer=%04x\n", dwRet, hMix);
+
+ return dwRet;
+}
+
+/**************************************************************************
+ * mixerOpen [WINMM.@]
+ */
+UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD dwCallback,
+ DWORD dwInstance, DWORD fdwOpen)
+{
+ return MMSYSTEM_mixerOpen(lphMix, uDeviceID,
+ dwCallback, dwInstance, fdwOpen, TRUE);
+}
+
+/**************************************************************************
+ * mixerClose [WINMM.@]
+ */
+UINT WINAPI mixerClose(HMIXER hMix)
+{
+ LPWINE_MLD wmld;
+ DWORD dwRet;
+
+ TRACE("(%04x)\n", hMix);
+
+ if ((wmld = MMDRV_Get(hMix, MMDRV_MIXER, FALSE)) == NULL) return MMSYSERR_INVALHANDLE;
+
+ dwRet = MMDRV_Close(wmld, MXDM_CLOSE);
+ MMDRV_Free(hMix, wmld);
+
+ return dwRet;
+}
+
+/**************************************************************************
+ * mixerGetID [WINMM.@]
+ */
+UINT WINAPI mixerGetID(HMIXEROBJ hmix, LPUINT lpid, DWORD fdwID)
+{
+ LPWINE_MIXER lpwm;
+
+ TRACE("(%04x %p %08lx)\n", hmix, lpid, fdwID);
+
+ if ((lpwm = MIXER_GetDev(hmix, fdwID)) == NULL) {
+ return MMSYSERR_INVALHANDLE;
+ }
+
+ if (lpid)
+ *lpid = lpwm->mld.uDeviceID;
+
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+ * mixerGetControlDetailsA [WINMM.@]
+ */
+UINT WINAPI mixerGetControlDetailsA(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdA,
+ DWORD fdwDetails)
+{
+ LPWINE_MIXER lpwm;
+
+ TRACE("(%04x, %p, %08lx)\n", hmix, lpmcdA, fdwDetails);
+
+ if ((lpwm = MIXER_GetDev(hmix, fdwDetails)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ if (lpmcdA == NULL || lpmcdA->cbStruct != sizeof(*lpmcdA))
+ return MMSYSERR_INVALPARAM;
+
+ return MMDRV_Message(&lpwm->mld, MXDM_GETCONTROLDETAILS, (DWORD)lpmcdA,
+ fdwDetails, TRUE);
+}
+
+/**************************************************************************
+ * mixerGetControlDetailsW [WINMM.@]
+ */
+UINT WINAPI mixerGetControlDetailsW(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcd, DWORD fdwDetails)
+{
+ DWORD ret = MMSYSERR_NOTENABLED;
+
+ TRACE("(%04x, %p, %08lx)\n", hmix, lpmcd, fdwDetails);
+
+ if (lpmcd == NULL || lpmcd->cbStruct != sizeof(*lpmcd))
+ return MMSYSERR_INVALPARAM;
+
+ switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
+ case MIXER_GETCONTROLDETAILSF_VALUE:
+ /* can savely use W structure as it is, no string inside */
+ ret = mixerGetControlDetailsA(hmix, lpmcd, fdwDetails);
+ break;
+ case MIXER_GETCONTROLDETAILSF_LISTTEXT:
+ {
+ MIXERCONTROLDETAILS_LISTTEXTW *pDetailsW = (MIXERCONTROLDETAILS_LISTTEXTW *)lpmcd->paDetails;
+ MIXERCONTROLDETAILS_LISTTEXTA *pDetailsA;
+ int size = max(1, lpmcd->cChannels) * sizeof(MIXERCONTROLDETAILS_LISTTEXTA);
+ int i;
+
+ if (lpmcd->u.cMultipleItems != 0) {
+ size *= lpmcd->u.cMultipleItems;
+ }
+ pDetailsA = (MIXERCONTROLDETAILS_LISTTEXTA *)HeapAlloc(GetProcessHeap(), 0, size);
+ lpmcd->paDetails = pDetailsA;
+ lpmcd->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTA);
+ /* set up lpmcd->paDetails */
+ ret = mixerGetControlDetailsA(hmix, lpmcd, fdwDetails);
+ /* copy from lpmcd->paDetails back to paDetailsW; */
+ if(ret == MMSYSERR_NOERROR) {
+ for(i=0;i<lpmcd->u.cMultipleItems*lpmcd->cChannels;i++) {
+ pDetailsW->dwParam1 = pDetailsA->dwParam1;
+ pDetailsW->dwParam2 = pDetailsA->dwParam2;
+ MultiByteToWideChar( CP_ACP, 0, pDetailsA->szName, -1,
+ pDetailsW->szName,
+ sizeof(pDetailsW->szName)/sizeof(WCHAR) );
+ pDetailsA++;
+ pDetailsW++;
+ }
+ pDetailsA -= lpmcd->u.cMultipleItems*lpmcd->cChannels;
+ pDetailsW -= lpmcd->u.cMultipleItems*lpmcd->cChannels;
+ }
+ HeapFree(GetProcessHeap(), 0, pDetailsA);
+ lpmcd->paDetails = pDetailsW;
+ lpmcd->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTW);
+ }
+ break;
+ default:
+ ERR("Unsupported fdwDetails=0x%08lx\n", fdwDetails);
+ }
+
+ return ret;
+}
+
+/**************************************************************************
+ * mixerGetLineControlsA [WINMM.@]
+ */
+UINT WINAPI mixerGetLineControlsA(HMIXEROBJ hmix, LPMIXERLINECONTROLSA lpmlcA,
+ DWORD fdwControls)
+{
+ LPWINE_MIXER lpwm;
+
+ TRACE("(%04x, %p, %08lx)\n", hmix, lpmlcA, fdwControls);
+
+ if ((lpwm = MIXER_GetDev(hmix, fdwControls)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ if (lpmlcA == NULL || lpmlcA->cbStruct != sizeof(*lpmlcA))
+ return MMSYSERR_INVALPARAM;
+
+ return MMDRV_Message(&lpwm->mld, MXDM_GETLINECONTROLS, (DWORD)lpmlcA,
+ fdwControls, TRUE);
+}
+
+/**************************************************************************
+ * mixerGetLineControlsW [WINMM.@]
+ */
+UINT WINAPI mixerGetLineControlsW(HMIXEROBJ hmix, LPMIXERLINECONTROLSW lpmlcW,
+ DWORD fdwControls)
+{
+ MIXERLINECONTROLSA mlcA;
+ DWORD ret;
+ int i;
+
+ TRACE("(%04x, %p, %08lx)\n", hmix, lpmlcW, fdwControls);
+
+ if (lpmlcW == NULL || lpmlcW->cbStruct != sizeof(*lpmlcW) ||
+ lpmlcW->cbmxctrl != sizeof(MIXERCONTROLW))
+ return MMSYSERR_INVALPARAM;
+
+ mlcA.cbStruct = sizeof(mlcA);
+ mlcA.dwLineID = lpmlcW->dwLineID;
+ mlcA.u.dwControlID = lpmlcW->u.dwControlID;
+ mlcA.u.dwControlType = lpmlcW->u.dwControlType;
+ mlcA.cControls = lpmlcW->cControls;
+ mlcA.cbmxctrl = sizeof(MIXERCONTROLA);
+ mlcA.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
+ mlcA.cControls * mlcA.cbmxctrl);
+
+ ret = mixerGetLineControlsA(hmix, &mlcA, fdwControls);
+
+ if (ret == MMSYSERR_NOERROR) {
+ lpmlcW->dwLineID = mlcA.dwLineID;
+ lpmlcW->u.dwControlID = mlcA.u.dwControlID;
+ lpmlcW->u.dwControlType = mlcA.u.dwControlType;
+ lpmlcW->cControls = mlcA.cControls;
+
+ for (i = 0; i < mlcA.cControls; i++) {
+ lpmlcW->pamxctrl[i].cbStruct = sizeof(MIXERCONTROLW);
+ lpmlcW->pamxctrl[i].dwControlID = mlcA.pamxctrl[i].dwControlID;
+ lpmlcW->pamxctrl[i].dwControlType = mlcA.pamxctrl[i].dwControlType;
+ lpmlcW->pamxctrl[i].fdwControl = mlcA.pamxctrl[i].fdwControl;
+ lpmlcW->pamxctrl[i].cMultipleItems = mlcA.pamxctrl[i].cMultipleItems;
+ MultiByteToWideChar( CP_ACP, 0, mlcA.pamxctrl[i].szShortName, -1,
+ lpmlcW->pamxctrl[i].szShortName,
+ sizeof(lpmlcW->pamxctrl[i].szShortName)/sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, mlcA.pamxctrl[i].szName, -1,
+ lpmlcW->pamxctrl[i].szName,
+ sizeof(lpmlcW->pamxctrl[i].szName)/sizeof(WCHAR) );
+ /* sizeof(lpmlcW->pamxctrl[i].Bounds) ==
+ * sizeof(mlcA.pamxctrl[i].Bounds) */
+ memcpy(&lpmlcW->pamxctrl[i].Bounds, &mlcA.pamxctrl[i].Bounds,
+ sizeof(mlcA.pamxctrl[i].Bounds));
+ /* sizeof(lpmlcW->pamxctrl[i].Metrics) ==
+ * sizeof(mlcA.pamxctrl[i].Metrics) */
+ memcpy(&lpmlcW->pamxctrl[i].Metrics, &mlcA.pamxctrl[i].Metrics,
+ sizeof(mlcA.pamxctrl[i].Metrics));
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, mlcA.pamxctrl);
+
+ return ret;
+}
+
+/**************************************************************************
+ * mixerGetLineInfoA [WINMM.@]
+ */
+UINT WINAPI mixerGetLineInfoA(HMIXEROBJ hmix, LPMIXERLINEA lpmliW, DWORD fdwInfo)
+{
+ LPWINE_MIXER lpwm;
+
+ TRACE("(%04x, %p, %08lx)\n", hmix, lpmliW, fdwInfo);
+
+ if ((lpwm = MIXER_GetDev(hmix, fdwInfo)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(&lpwm->mld, MXDM_GETLINEINFO, (DWORD)lpmliW,
+ fdwInfo, TRUE);
+}
+
+/**************************************************************************
+ * mixerGetLineInfoW [WINMM.@]
+ */
+UINT WINAPI mixerGetLineInfoW(HMIXEROBJ hmix, LPMIXERLINEW lpmliW,
+ DWORD fdwInfo)
+{
+ MIXERLINEA mliA;
+ UINT ret;
+
+ TRACE("(%04x, %p, %08lx)\n", hmix, lpmliW, fdwInfo);
+
+ if (lpmliW == NULL || lpmliW->cbStruct != sizeof(*lpmliW))
+ return MMSYSERR_INVALPARAM;
+
+ mliA.cbStruct = sizeof(mliA);
+ switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
+ case MIXER_GETLINEINFOF_COMPONENTTYPE:
+ mliA.dwComponentType = lpmliW->dwComponentType;
+ break;
+ case MIXER_GETLINEINFOF_DESTINATION:
+ mliA.dwDestination = lpmliW->dwDestination;
+ break;
+ case MIXER_GETLINEINFOF_LINEID:
+ mliA.dwLineID = lpmliW->dwLineID;
+ break;
+ case MIXER_GETLINEINFOF_SOURCE:
+ mliA.dwDestination = lpmliW->dwDestination;
+ mliA.dwSource = lpmliW->dwSource;
+ break;
+ case MIXER_GETLINEINFOF_TARGETTYPE:
+ mliA.Target.dwType = lpmliW->Target.dwType;
+ mliA.Target.wMid = lpmliW->Target.wMid;
+ mliA.Target.wPid = lpmliW->Target.wPid;
+ mliA.Target.vDriverVersion = lpmliW->Target.vDriverVersion;
+ WideCharToMultiByte( CP_ACP, 0, lpmliW->Target.szPname, -1, mliA.Target.szPname, sizeof(mliA.Target.szPname), NULL, NULL);
+ break;
+ default:
+ FIXME("Unsupported fdwControls=0x%08lx\n", fdwInfo);
+ }
+
+ ret = mixerGetLineInfoA(hmix, &mliA, fdwInfo);
+
+ lpmliW->dwDestination = mliA.dwDestination;
+ lpmliW->dwSource = mliA.dwSource;
+ lpmliW->dwLineID = mliA.dwLineID;
+ lpmliW->fdwLine = mliA.fdwLine;
+ lpmliW->dwUser = mliA.dwUser;
+ lpmliW->dwComponentType = mliA.dwComponentType;
+ lpmliW->cChannels = mliA.cChannels;
+ lpmliW->cConnections = mliA.cConnections;
+ lpmliW->cControls = mliA.cControls;
+ MultiByteToWideChar( CP_ACP, 0, mliA.szShortName, -1, lpmliW->szShortName,
+ sizeof(lpmliW->szShortName)/sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, mliA.szName, -1, lpmliW->szName,
+ sizeof(lpmliW->szName)/sizeof(WCHAR) );
+ lpmliW->Target.dwType = mliA.Target.dwType;
+ lpmliW->Target.dwDeviceID = mliA.Target.dwDeviceID;
+ lpmliW->Target.wMid = mliA.Target.wMid;
+ lpmliW->Target.wPid = mliA.Target.wPid;
+ lpmliW->Target.vDriverVersion = mliA.Target.vDriverVersion;
+ MultiByteToWideChar( CP_ACP, 0, mliA.Target.szPname, -1, lpmliW->Target.szPname,
+ sizeof(lpmliW->Target.szPname)/sizeof(WCHAR) );
+
+ return ret;
+}
+
+/**************************************************************************
+ * mixerSetControlDetails [WINMM.@]
+ */
+UINT WINAPI mixerSetControlDetails(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdA,
+ DWORD fdwDetails)
+{
+ LPWINE_MIXER lpwm;
+
+ TRACE("(%04x, %p, %08lx)\n", hmix, lpmcdA, fdwDetails);
+
+ if ((lpwm = MIXER_GetDev(hmix, fdwDetails)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(&lpwm->mld, MXDM_SETCONTROLDETAILS, (DWORD)lpmcdA,
+ fdwDetails, TRUE);
+}
+
+/**************************************************************************
+ * mixerMessage [WINMM.@]
+ */
+UINT WINAPI mixerMessage(HMIXER hmix, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04lx, %d, %08lx, %08lx): semi-stub?\n",
+ (DWORD)hmix, uMsg, dwParam1, dwParam2);
+
+ if ((wmld = MMDRV_Get(hmix, MMDRV_MIXER, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, uMsg, dwParam1, dwParam2, TRUE);
+}
+
+/**************************************************************************
+ * auxGetNumDevs [WINMM.@]
+ */
+UINT WINAPI auxGetNumDevs(void)
+{
+ return MMDRV_GetNum(MMDRV_AUX);
+}
+
+/**************************************************************************
+ * auxGetDevCapsW [WINMM.@]
+ */
+UINT WINAPI auxGetDevCapsW(UINT uDeviceID, LPAUXCAPSW lpCaps, UINT uSize)
+{
+ AUXCAPSA acA;
+ UINT ret = auxGetDevCapsA(uDeviceID, &acA, sizeof(acA));
+
+ lpCaps->wMid = acA.wMid;
+ lpCaps->wPid = acA.wPid;
+ lpCaps->vDriverVersion = acA.vDriverVersion;
+ MultiByteToWideChar( CP_ACP, 0, acA.szPname, -1, lpCaps->szPname,
+ sizeof(lpCaps->szPname)/sizeof(WCHAR) );
+ lpCaps->wTechnology = acA.wTechnology;
+ lpCaps->dwSupport = acA.dwSupport;
+ return ret;
+}
+
+/**************************************************************************
+ * auxGetDevCapsA [WINMM.@]
+ */
+UINT WINAPI auxGetDevCapsA(UINT uDeviceID, LPAUXCAPSA lpCaps, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %d) !\n", uDeviceID, lpCaps, uSize);
+
+ if ((wmld = MMDRV_Get(uDeviceID, MMDRV_AUX, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ return MMDRV_Message(wmld, AUXDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
+}
+
+/**************************************************************************
+ * auxGetVolume [WINMM.@]
+ */
+UINT WINAPI auxGetVolume(UINT uDeviceID, DWORD* lpdwVolume)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p) !\n", uDeviceID, lpdwVolume);
+
+ if ((wmld = MMDRV_Get(uDeviceID, MMDRV_AUX, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD)lpdwVolume, 0L, TRUE);
+}
+
+/**************************************************************************
+ * auxSetVolume [WINMM.@]
+ */
+UINT WINAPI auxSetVolume(UINT uDeviceID, DWORD dwVolume)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %lu) !\n", uDeviceID, dwVolume);
+
+ if ((wmld = MMDRV_Get(uDeviceID, MMDRV_AUX, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ return MMDRV_Message(wmld, AUXDM_SETVOLUME, dwVolume, 0L, TRUE);
+}
+
+/**************************************************************************
+ * auxOutMessage [WINMM.@]
+ */
+DWORD WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD dw1, DWORD dw2)
+{
+ LPWINE_MLD wmld;
+
+ if ((wmld = MMDRV_Get(uDeviceID, MMDRV_AUX, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, uMessage, dw1, dw2, TRUE);
+}
+
+/**************************************************************************
+ * mciGetErrorStringW [WINMM.@]
+ */
+BOOL WINAPI mciGetErrorStringW(DWORD wError, LPWSTR lpstrBuffer, UINT uLength)
+{
+ LPSTR bufstr = HeapAlloc(GetProcessHeap(), 0, uLength);
+ BOOL ret = mciGetErrorStringA(wError, bufstr, uLength);
+
+ MultiByteToWideChar( CP_ACP, 0, bufstr, -1, lpstrBuffer, uLength );
+ HeapFree(GetProcessHeap(), 0, bufstr);
+ return ret;
+}
+
+/**************************************************************************
+ * mciGetErrorStringA [WINMM.@]
+ */
+BOOL WINAPI mciGetErrorStringA(DWORD dwError, LPSTR lpstrBuffer, UINT uLength)
+{
+ BOOL16 ret = FALSE;
+
+ if (lpstrBuffer != NULL && uLength > 0 &&
+ dwError >= MCIERR_BASE && dwError <= MCIERR_CUSTOM_DRIVER_BASE) {
+
+ if (LoadStringA(MULTIMEDIA_GetIData()->hWinMM32Instance,
+ dwError, lpstrBuffer, uLength) > 0) {
+ ret = TRUE;
+ }
+ }
+ return ret;
+}
+
+/**************************************************************************
+ * mciDriverNotify [WINMM.@]
+ */
+BOOL WINAPI mciDriverNotify(HWND hWndCallBack, UINT wDevID, UINT wStatus)
+{
+
+ TRACE("(%08X, %04x, %04X)\n", hWndCallBack, wDevID, wStatus);
+
+ return PostMessageA(hWndCallBack, MM_MCINOTIFY, wStatus, wDevID);
+}
+
+/**************************************************************************
+ * mciGetDriverData [WINMM.@]
+ */
+DWORD WINAPI mciGetDriverData(UINT uDeviceID)
+{
+ LPWINE_MCIDRIVER wmd;
+
+ TRACE("(%04x)\n", uDeviceID);
+
+ wmd = MCI_GetDriver(uDeviceID);
+
+ if (!wmd) {
+ WARN("Bad uDeviceID\n");
+ return 0L;
+ }
+
+ return wmd->dwPrivate;
+}
+
+/**************************************************************************
+ * mciSetDriverData [WINMM.@]
+ */
+BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD data)
+{
+ LPWINE_MCIDRIVER wmd;
+
+ TRACE("(%04x, %08lx)\n", uDeviceID, data);
+
+ wmd = MCI_GetDriver(uDeviceID);
+
+ if (!wmd) {
+ WARN("Bad uDeviceID\n");
+ return FALSE;
+ }
+
+ wmd->dwPrivate = data;
+ return TRUE;
+}
+
+/**************************************************************************
+ * mciSendCommandA [WINMM.@]
+ */
+DWORD WINAPI mciSendCommandA(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
+{
+ DWORD dwRet;
+
+ TRACE("(%08x, %s, %08lx, %08lx)\n",
+ wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
+
+ dwRet = MCI_SendCommand(wDevID, wMsg, dwParam1, dwParam2, TRUE);
+ dwRet = MCI_CleanUp(dwRet, wMsg, dwParam2, TRUE);
+ TRACE("=> %08lx\n", dwRet);
+ return dwRet;
+}
+
+/**************************************************************************
+ * mciSendCommandW [WINMM.@]
+ */
+DWORD WINAPI mciSendCommandW(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
+{
+ FIXME("(%08x, %s, %08lx, %08lx): stub\n",
+ wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2);
+ return MCIERR_UNSUPPORTED_FUNCTION;
+}
+
+/**************************************************************************
+ * mciGetDeviceIDA [WINMM.@]
+ */
+UINT WINAPI mciGetDeviceIDA(LPCSTR lpstrName)
+{
+ return MCI_GetDriverFromString(lpstrName);
+}
+
+/**************************************************************************
+ * mciGetDeviceIDW [WINMM.@]
+ */
+UINT WINAPI mciGetDeviceIDW(LPCWSTR lpwstrName)
+{
+ LPSTR lpstrName;
+ UINT ret;
+
+ lpstrName = HEAP_strdupWtoA(GetProcessHeap(), 0, lpwstrName);
+ ret = MCI_GetDriverFromString(lpstrName);
+ HeapFree(GetProcessHeap(), 0, lpstrName);
+ return ret;
+}
+
+/**************************************************************************
+ * MCI_DefYieldProc [internal]
+ */
+UINT WINAPI MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data)
+{
+ INT16 ret;
+
+ TRACE("(0x%04x, 0x%08lx)\n", wDevID, data);
+
+ if ((HIWORD(data) != 0 && HWND_16(GetActiveWindow()) != HIWORD(data)) ||
+ (GetAsyncKeyState(LOWORD(data)) & 1) == 0) {
+ UserYield16();
+ ret = 0;
+ } else {
+ MSG msg;
+
+ msg.hwnd = HWND_32(HIWORD(data));
+ while (!PeekMessageA(&msg, msg.hwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE));
+ ret = -1;
+ }
+ return ret;
+}
+
+/**************************************************************************
+ * mciSetYieldProc [WINMM.@]
+ */
+BOOL WINAPI mciSetYieldProc(UINT uDeviceID, YIELDPROC fpYieldProc, DWORD dwYieldData)
+{
+ LPWINE_MCIDRIVER wmd;
+
+ TRACE("(%u, %p, %08lx)\n", uDeviceID, fpYieldProc, dwYieldData);
+
+ if (!(wmd = MCI_GetDriver(uDeviceID))) {
+ WARN("Bad uDeviceID\n");
+ return FALSE;
+ }
+
+ wmd->lpfnYieldProc = fpYieldProc;
+ wmd->dwYieldData = dwYieldData;
+ wmd->bIs32 = TRUE;
+
+ return TRUE;
+}
+
+/**************************************************************************
+ * mciGetDeviceIDFromElementIDW [WINMM.@]
+ */
+UINT WINAPI mciGetDeviceIDFromElementIDW(DWORD dwElementID, LPCWSTR lpstrType)
+{
+ /* FIXME: that's rather strange, there is no
+ * mciGetDeviceIDFromElementID32A in winmm.spec
+ */
+ FIXME("(%lu, %p) stub\n", dwElementID, lpstrType);
+ return 0;
+}
+
+/**************************************************************************
+ * mciGetYieldProc [WINMM.@]
+ */
+YIELDPROC WINAPI mciGetYieldProc(UINT uDeviceID, DWORD* lpdwYieldData)
+{
+ LPWINE_MCIDRIVER wmd;
+
+ TRACE("(%u, %p)\n", uDeviceID, lpdwYieldData);
+
+ if (!(wmd = MCI_GetDriver(uDeviceID))) {
+ WARN("Bad uDeviceID\n");
+ return NULL;
+ }
+ if (!wmd->lpfnYieldProc) {
+ WARN("No proc set\n");
+ return NULL;
+ }
+ if (!wmd->bIs32) {
+ WARN("Proc is 32 bit\n");
+ return NULL;
+ }
+ return wmd->lpfnYieldProc;
+}
+
+/**************************************************************************
+ * mciGetCreatorTask [WINMM.@]
+ */
+HTASK WINAPI mciGetCreatorTask(UINT uDeviceID)
+{
+ LPWINE_MCIDRIVER wmd;
+ HTASK ret = 0;
+
+ if ((wmd = MCI_GetDriver(uDeviceID))) ret = (HTASK)wmd->CreatorThread;
+
+ TRACE("(%u) => %08x\n", uDeviceID, ret);
+ return ret;
+}
+
+/**************************************************************************
+ * mciDriverYield [WINMM.@]
+ */
+UINT WINAPI mciDriverYield(UINT uDeviceID)
+{
+ LPWINE_MCIDRIVER wmd;
+ UINT ret = 0;
+
+ TRACE("(%04x)\n", uDeviceID);
+
+ if (!(wmd = MCI_GetDriver(uDeviceID)) || !wmd->lpfnYieldProc || !wmd->bIs32) {
+ UserYield16();
+ } else {
+ ret = wmd->lpfnYieldProc(uDeviceID, wmd->dwYieldData);
+ }
+
+ return ret;
+}
+
+/**************************************************************************
+ * midiOutGetNumDevs [WINMM.@]
+ */
+UINT WINAPI midiOutGetNumDevs(void)
+{
+ return MMDRV_GetNum(MMDRV_MIDIOUT);
+}
+
+/**************************************************************************
+ * midiOutGetDevCapsW [WINMM.@]
+ */
+UINT WINAPI midiOutGetDevCapsW(UINT uDeviceID, LPMIDIOUTCAPSW lpCaps,
+ UINT uSize)
+{
+ MIDIOUTCAPSA mocA;
+ UINT ret;
+
+ ret = midiOutGetDevCapsA(uDeviceID, &mocA, sizeof(mocA));
+ lpCaps->wMid = mocA.wMid;
+ lpCaps->wPid = mocA.wPid;
+ lpCaps->vDriverVersion = mocA.vDriverVersion;
+ MultiByteToWideChar( CP_ACP, 0, mocA.szPname, -1, lpCaps->szPname,
+ sizeof(lpCaps->szPname)/sizeof(WCHAR) );
+ lpCaps->wTechnology = mocA.wTechnology;
+ lpCaps->wVoices = mocA.wVoices;
+ lpCaps->wNotes = mocA.wNotes;
+ lpCaps->wChannelMask = mocA.wChannelMask;
+ lpCaps->dwSupport = mocA.dwSupport;
+ return ret;
+}
+
+/**************************************************************************
+ * midiOutGetDevCapsA [WINMM.@]
+ */
+UINT WINAPI midiOutGetDevCapsA(UINT uDeviceID, LPMIDIOUTCAPSA lpCaps,
+ UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%u, %p, %u);\n", uDeviceID, lpCaps, uSize);
+
+ if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
+
+ if ((wmld = MMDRV_Get(uDeviceID, MMDRV_MIDIOUT, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MODM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
+}
+
+/**************************************************************************
+ * MIDI_GetErrorText [internal]
+ */
+static UINT16 MIDI_GetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
+{
+ UINT16 ret = MMSYSERR_BADERRNUM;
+
+ if (lpText == NULL) {
+ ret = MMSYSERR_INVALPARAM;
+ } else if (uSize == 0) {
+ ret = MMSYSERR_NOERROR;
+ } else if (
+ /* test has been removed 'coz MMSYSERR_BASE is 0, and gcc did emit
+ * a warning for the test was always true */
+ (/*uError >= MMSYSERR_BASE && */ uError <= MMSYSERR_LASTERROR) ||
+ (uError >= MIDIERR_BASE && uError <= MIDIERR_LASTERROR)) {
+
+ if (LoadStringA(MULTIMEDIA_GetIData()->hWinMM32Instance,
+ uError, lpText, uSize) > 0) {
+ ret = MMSYSERR_NOERROR;
+ }
+ }
+ return ret;
+}
+
+/**************************************************************************
+ * midiOutGetErrorTextA [WINMM.@]
+ */
+UINT WINAPI midiOutGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
+{
+ return MIDI_GetErrorText(uError, lpText, uSize);
+}
+
+/**************************************************************************
+ * midiOutGetErrorTextW [WINMM.@]
+ */
+UINT WINAPI midiOutGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
+{
+ LPSTR xstr = HeapAlloc(GetProcessHeap(), 0, uSize);
+ UINT ret;
+
+ ret = MIDI_GetErrorText(uError, xstr, uSize);
+ MultiByteToWideChar( CP_ACP, 0, xstr, -1, lpText, uSize );
+ HeapFree(GetProcessHeap(), 0, xstr);
+ return ret;
+}
+
+/**************************************************************************
+ * MIDI_OutAlloc [internal]
+ */
+static LPWINE_MIDI MIDI_OutAlloc(HMIDIOUT* lphMidiOut, LPDWORD lpdwCallback,
+ LPDWORD lpdwInstance, LPDWORD lpdwFlags,
+ DWORD cIDs, MIDIOPENSTRMID* lpIDs, BOOL bFrom32)
+{
+ HMIDIOUT hMidiOut;
+ LPWINE_MIDI lpwm;
+ UINT size;
+
+ size = sizeof(WINE_MIDI) + (cIDs ? (cIDs-1) : 0) * sizeof(MIDIOPENSTRMID);
+
+ lpwm = (LPWINE_MIDI)MMDRV_Alloc(size, MMDRV_MIDIOUT, &hMidiOut, lpdwFlags,
+ lpdwCallback, lpdwInstance, bFrom32);
+
+ if (lphMidiOut != NULL)
+ *lphMidiOut = hMidiOut;
+
+ if (lpwm) {
+ lpwm->mod.hMidi = (HMIDI) hMidiOut;
+ lpwm->mod.dwCallback = *lpdwCallback;
+ lpwm->mod.dwInstance = *lpdwInstance;
+ lpwm->mod.dnDevNode = 0;
+ lpwm->mod.cIds = cIDs;
+ if (cIDs)
+ memcpy(&(lpwm->mod.rgIds), lpIDs, cIDs * sizeof(MIDIOPENSTRMID));
+ }
+ return lpwm;
+}
+
+UINT MMSYSTEM_midiOutOpen(HMIDIOUT* lphMidiOut, UINT uDeviceID, DWORD dwCallback,
+ DWORD dwInstance, DWORD dwFlags, BOOL bFrom32)
+{
+ HMIDIOUT hMidiOut;
+ LPWINE_MIDI lpwm;
+ UINT dwRet = 0;
+
+ TRACE("(%p, %d, %08lX, %08lX, %08lX);\n",
+ lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags);
+
+ if (lphMidiOut != NULL) *lphMidiOut = 0;
+
+ lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &dwFlags,
+ 0, NULL, bFrom32);
+
+ if (lpwm == NULL)
+ return MMSYSERR_NOMEM;
+
+ lpwm->mld.uDeviceID = uDeviceID;
+
+ dwRet = MMDRV_Open((LPWINE_MLD)lpwm, MODM_OPEN, (DWORD)&lpwm->mod,
+ dwFlags);
+
+ if (dwRet != MMSYSERR_NOERROR) {
+ MMDRV_Free(hMidiOut, (LPWINE_MLD)lpwm);
+ hMidiOut = 0;
+ }
+
+ if (lphMidiOut) *lphMidiOut = hMidiOut;
+ TRACE("=> %d hMidi=%04x\n", dwRet, hMidiOut);
+
+ return dwRet;
+}
+
+/**************************************************************************
+ * midiOutOpen [WINMM.@]
+ */
+UINT WINAPI midiOutOpen(HMIDIOUT* lphMidiOut, UINT uDeviceID,
+ DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
+{
+ return MMSYSTEM_midiOutOpen(lphMidiOut, uDeviceID, dwCallback,
+ dwInstance, dwFlags, TRUE);
+}
+
+/**************************************************************************
+ * midiOutClose [WINMM.@]
+ */
+UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
+{
+ LPWINE_MLD wmld;
+ DWORD dwRet;
+
+ TRACE("(%04X)\n", hMidiOut);
+
+ if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ dwRet = MMDRV_Close(wmld, MODM_CLOSE);
+ MMDRV_Free(hMidiOut, wmld);
+
+ return dwRet;
+}
+
+/**************************************************************************
+ * midiOutPrepareHeader [WINMM.@]
+ */
+UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut,
+ MIDIHDR* lpMidiOutHdr, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
+
+ if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MODM_PREPARE, (DWORD)lpMidiOutHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * midiOutUnprepareHeader [WINMM.@]
+ */
+UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut,
+ MIDIHDR* lpMidiOutHdr, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
+
+ if (!(lpMidiOutHdr->dwFlags & MHDR_PREPARED)) {
+ return MMSYSERR_NOERROR;
+ }
+
+ if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD)lpMidiOutHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * midiOutShortMsg [WINMM.@]
+ */
+UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %08lX)\n", hMidiOut, dwMsg);
+
+ if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MODM_DATA, dwMsg, 0L, FALSE);
+}
+
+/**************************************************************************
+ * midiOutLongMsg [WINMM.@]
+ */
+UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut,
+ MIDIHDR* lpMidiOutHdr, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
+
+ if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD)lpMidiOutHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * midiOutReset [WINMM.@]
+ */
+UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X)\n", hMidiOut);
+
+ if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MODM_RESET, 0L, 0L, TRUE);
+}
+
+/**************************************************************************
+ * midiOutGetVolume [WINMM.@]
+ */
+UINT WINAPI midiOutGetVolume(UINT uDeviceID, DWORD* lpdwVolume)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p);\n", uDeviceID, lpdwVolume);
+
+ if ((wmld = MMDRV_Get(uDeviceID, MMDRV_MIDIOUT, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MODM_GETVOLUME, (DWORD)lpdwVolume, 0L, TRUE);
+}
+
+/**************************************************************************
+ * midiOutSetVolume [WINMM.@]
+ */
+UINT WINAPI midiOutSetVolume(UINT uDeviceID, DWORD dwVolume)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %ld);\n", uDeviceID, dwVolume);
+
+ if ((wmld = MMDRV_Get(uDeviceID, MMDRV_MIDIOUT, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MODM_SETVOLUME, dwVolume, 0L, TRUE);
+}
+
+/**************************************************************************
+ * midiOutCachePatches [WINMM.@]
+ */
+UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank,
+ WORD* lpwPatchArray, UINT uFlags)
+{
+ /* not really necessary to support this */
+ FIXME("not supported yet\n");
+ return MMSYSERR_NOTSUPPORTED;
+}
+
+/**************************************************************************
+ * midiOutCacheDrumPatches [WINMM.@]
+ */
+UINT WINAPI midiOutCacheDrumPatches(HMIDIOUT hMidiOut, UINT uPatch,
+ WORD* lpwKeyArray, UINT uFlags)
+{
+ FIXME("not supported yet\n");
+ return MMSYSERR_NOTSUPPORTED;
+}
+
+/**************************************************************************
+ * midiOutGetID [WINMM.@]
+ */
+UINT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT* lpuDeviceID)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p)\n", hMidiOut, lpuDeviceID);
+
+ if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
+ if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ *lpuDeviceID = wmld->uDeviceID;
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+ * midiOutMessage [WINMM.@]
+ */
+DWORD WINAPI midiOutMessage(HMIDIOUT hMidiOut, UINT uMessage,
+ DWORD dwParam1, DWORD dwParam2)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiOut, uMessage, dwParam1, dwParam2);
+
+ if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL) {
+ /* HACK... */
+ if (uMessage == 0x0001) {
+ *(LPDWORD)dwParam1 = 1;
+ return 0;
+ }
+ if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, TRUE)) != NULL) {
+ return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
+ }
+ return MMSYSERR_INVALHANDLE;
+ }
+
+ switch (uMessage) {
+ case MODM_OPEN:
+ case MODM_CLOSE:
+ FIXME("can't handle OPEN or CLOSE message!\n");
+ return MMSYSERR_NOTSUPPORTED;
+ }
+ return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
+}
+
+/**************************************************************************
+ * midiInGetNumDevs [WINMM.@]
+ */
+UINT WINAPI midiInGetNumDevs(void)
+{
+ return MMDRV_GetNum(MMDRV_MIDIIN);
+}
+
+/**************************************************************************
+ * midiInGetDevCapsW [WINMM.@]
+ */
+UINT WINAPI midiInGetDevCapsW(UINT uDeviceID, LPMIDIINCAPSW lpCaps, UINT uSize)
+{
+ MIDIINCAPSA micA;
+ UINT ret = midiInGetDevCapsA(uDeviceID, &micA, uSize);
+
+ if (ret == MMSYSERR_NOERROR) {
+ lpCaps->wMid = micA.wMid;
+ lpCaps->wPid = micA.wPid;
+ lpCaps->vDriverVersion = micA.vDriverVersion;
+ MultiByteToWideChar( CP_ACP, 0, micA.szPname, -1, lpCaps->szPname,
+ sizeof(lpCaps->szPname)/sizeof(WCHAR) );
+ lpCaps->dwSupport = micA.dwSupport;
+ }
+ return ret;
+}
+
+/**************************************************************************
+ * midiInGetDevCapsA [WINMM.@]
+ */
+UINT WINAPI midiInGetDevCapsA(UINT uDeviceID, LPMIDIINCAPSA lpCaps, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%d, %p, %d);\n", uDeviceID, lpCaps, uSize);
+
+ if ((wmld = MMDRV_Get(uDeviceID, MMDRV_MIDIIN, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MIDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
+}
+
+/**************************************************************************
+ * midiInGetErrorTextW [WINMM.@]
+ */
+UINT WINAPI midiInGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
+{
+ LPSTR xstr = HeapAlloc(GetProcessHeap(), 0, uSize);
+ UINT ret = MIDI_GetErrorText(uError, xstr, uSize);
+
+ MultiByteToWideChar( CP_ACP, 0, xstr, -1, lpText, uSize );
+ HeapFree(GetProcessHeap(), 0, xstr);
+ return ret;
+}
+
+/**************************************************************************
+ * midiInGetErrorTextA [WINMM.@]
+ */
+UINT WINAPI midiInGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
+{
+ return MIDI_GetErrorText(uError, lpText, uSize);
+}
+
+UINT MMSYSTEM_midiInOpen(HMIDIIN* lphMidiIn, UINT uDeviceID, DWORD dwCallback,
+ DWORD dwInstance, DWORD dwFlags, BOOL bFrom32)
+{
+ HMIDIIN hMidiIn;
+ LPWINE_MIDI lpwm;
+ DWORD dwRet = 0;
+
+ TRACE("(%p, %d, %08lX, %08lX, %08lX);\n",
+ lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
+
+ if (lphMidiIn != NULL) *lphMidiIn = 0;
+
+ lpwm = (LPWINE_MIDI)MMDRV_Alloc(sizeof(WINE_MIDI), MMDRV_MIDIIN, &hMidiIn,
+ &dwFlags, &dwCallback, &dwInstance, bFrom32);
+
+ if (lpwm == NULL)
+ return MMSYSERR_NOMEM;
+
+ lpwm->mod.hMidi = (HMIDI) hMidiIn;
+ lpwm->mod.dwCallback = dwCallback;
+ lpwm->mod.dwInstance = dwInstance;
+
+ lpwm->mld.uDeviceID = uDeviceID;
+ dwRet = MMDRV_Open(&lpwm->mld, MIDM_OPEN, (DWORD)&lpwm->mod, dwFlags);
+
+ if (dwRet != MMSYSERR_NOERROR) {
+ MMDRV_Free(hMidiIn, &lpwm->mld);
+ hMidiIn = 0;
+ }
+ if (lphMidiIn != NULL) *lphMidiIn = hMidiIn;
+ TRACE("=> %ld hMidi=%04x\n", dwRet, hMidiIn);
+
+ return dwRet;
+}
+
+/**************************************************************************
+ * midiInOpen [WINMM.@]
+ */
+UINT WINAPI midiInOpen(HMIDIIN* lphMidiIn, UINT uDeviceID,
+ DWORD dwCallback, DWORD dwInstance, DWORD dwFlags)
+{
+ return MMSYSTEM_midiInOpen(lphMidiIn, uDeviceID, dwCallback,
+ dwInstance, dwFlags, TRUE);
+}
+
+/**************************************************************************
+ * midiInClose [WINMM.@]
+ */
+UINT WINAPI midiInClose(HMIDIIN hMidiIn)
+{
+ LPWINE_MLD wmld;
+ DWORD dwRet;
+
+ TRACE("(%04X)\n", hMidiIn);
+
+ if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ dwRet = MMDRV_Close(wmld, MIDM_CLOSE);
+ MMDRV_Free(hMidiIn, wmld);
+ return dwRet;
+}
+
+/**************************************************************************
+ * midiInPrepareHeader [WINMM.@]
+ */
+UINT WINAPI midiInPrepareHeader(HMIDIIN hMidiIn,
+ MIDIHDR* lpMidiInHdr, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
+
+ if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MIDM_PREPARE, (DWORD)lpMidiInHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * midiInUnprepareHeader [WINMM.@]
+ */
+UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn,
+ MIDIHDR* lpMidiInHdr, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
+
+ if (!(lpMidiInHdr->dwFlags & MHDR_PREPARED)) {
+ return MMSYSERR_NOERROR;
+ }
+
+ if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD)lpMidiInHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * midiInAddBuffer [WINMM.@]
+ */
+UINT WINAPI midiInAddBuffer(HMIDIIN hMidiIn,
+ MIDIHDR* lpMidiInHdr, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
+
+ if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD)lpMidiInHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * midiInStart [WINMM.@]
+ */
+UINT WINAPI midiInStart(HMIDIIN hMidiIn)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X)\n", hMidiIn);
+
+ if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MIDM_START, 0L, 0L, TRUE);
+}
+
+/**************************************************************************
+ * midiInStop [WINMM.@]
+ */
+UINT WINAPI midiInStop(HMIDIIN hMidiIn)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X)\n", hMidiIn);
+
+ if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MIDM_STOP, 0L, 0L, TRUE);
+}
+
+/**************************************************************************
+ * midiInReset [WINMM.@]
+ */
+UINT WINAPI midiInReset(HMIDIIN hMidiIn)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X)\n", hMidiIn);
+
+ if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, MIDM_RESET, 0L, 0L, TRUE);
+}
+
+/**************************************************************************
+ * midiInGetID [WINMM.@]
+ */
+UINT WINAPI midiInGetID(HMIDIIN hMidiIn, UINT* lpuDeviceID)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p)\n", hMidiIn, lpuDeviceID);
+
+ if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
+
+ if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ *lpuDeviceID = wmld->uDeviceID;
+
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+ * midiInMessage [WINMM.@]
+ */
+DWORD WINAPI midiInMessage(HMIDIIN hMidiIn, UINT uMessage,
+ DWORD dwParam1, DWORD dwParam2)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %04X, %08lX, %08lX)\n", hMidiIn, uMessage, dwParam1, dwParam2);
+
+ if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ switch (uMessage) {
+ case MIDM_OPEN:
+ case MIDM_CLOSE:
+ FIXME("can't handle OPEN or CLOSE message!\n");
+ return MMSYSERR_NOTSUPPORTED;
+ }
+ return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
+}
+
+typedef struct WINE_MIDIStream {
+ HMIDIOUT hDevice;
+ HANDLE hThread;
+ DWORD dwThreadID;
+ DWORD dwTempo;
+ DWORD dwTimeDiv;
+ DWORD dwPositionMS;
+ DWORD dwPulses;
+ DWORD dwStartTicks;
+ WORD wFlags;
+ HANDLE hEvent;
+ LPMIDIHDR lpMidiHdr;
+} WINE_MIDIStream;
+
+#define WINE_MSM_HEADER (WM_USER+0)
+#define WINE_MSM_STOP (WM_USER+1)
+
+/**************************************************************************
+ * MMSYSTEM_GetMidiStream [internal]
+ */
+static BOOL MMSYSTEM_GetMidiStream(HMIDISTRM hMidiStrm, WINE_MIDIStream** lpMidiStrm, WINE_MIDI** lplpwm)
+{
+ WINE_MIDI* lpwm = (LPWINE_MIDI)MMDRV_Get(hMidiStrm, MMDRV_MIDIOUT, FALSE);
+
+ if (lplpwm)
+ *lplpwm = lpwm;
+
+ if (lpwm == NULL) {
+ return FALSE;
+ }
+
+ *lpMidiStrm = (WINE_MIDIStream*)lpwm->mod.rgIds.dwStreamID;
+
+ return *lpMidiStrm != NULL;
+}
+
+/**************************************************************************
+ * MMSYSTEM_MidiStream_Convert [internal]
+ */
+static DWORD MMSYSTEM_MidiStream_Convert(WINE_MIDIStream* lpMidiStrm, DWORD pulse)
+{
+ DWORD ret = 0;
+
+ if (lpMidiStrm->dwTimeDiv == 0) {
+ FIXME("Shouldn't happen. lpMidiStrm->dwTimeDiv = 0\n");
+ } else if (lpMidiStrm->dwTimeDiv > 0x8000) { /* SMPTE, unchecked FIXME? */
+ int nf = -(char)HIBYTE(lpMidiStrm->dwTimeDiv); /* number of frames */
+ int nsf = LOBYTE(lpMidiStrm->dwTimeDiv); /* number of sub-frames */
+ ret = (pulse * 1000) / (nf * nsf);
+ } else {
+ ret = (DWORD)((double)pulse * ((double)lpMidiStrm->dwTempo / 1000) /
+ (double)lpMidiStrm->dwTimeDiv);
+ }
+
+ return ret;
+}
+
+/**************************************************************************
+ * MMSYSTEM_MidiStream_MessageHandler [internal]
+ */
+static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream* lpMidiStrm, LPWINE_MIDI lpwm, LPMSG msg)
+{
+ LPMIDIHDR lpMidiHdr;
+ LPMIDIHDR* lpmh;
+ LPBYTE lpData;
+
+ switch (msg->message) {
+ case WM_QUIT:
+ SetEvent(lpMidiStrm->hEvent);
+ return FALSE;
+ case WINE_MSM_STOP:
+ TRACE("STOP\n");
+ /* this is not quite what MS doc says... */
+ midiOutReset(lpMidiStrm->hDevice);
+ /* empty list of already submitted buffers */
+ for (lpMidiHdr = lpMidiStrm->lpMidiHdr; lpMidiHdr; lpMidiHdr = (LPMIDIHDR)lpMidiHdr->lpNext) {
+ lpMidiHdr->dwFlags |= MHDR_DONE;
+ lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
+
+ DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
+ (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
+ lpwm->mod.dwInstance, (DWORD)lpMidiHdr, 0L);
+ }
+ lpMidiStrm->lpMidiHdr = 0;
+ SetEvent(lpMidiStrm->hEvent);
+ break;
+ case WINE_MSM_HEADER:
+ /* sets initial tick count for first MIDIHDR */
+ if (!lpMidiStrm->dwStartTicks)
+ lpMidiStrm->dwStartTicks = GetTickCount();
+
+ /* FIXME(EPP): "I don't understand the content of the first MIDIHDR sent
+ * by native mcimidi, it doesn't look like a correct one".
+ * this trick allows to throw it away... but I don't like it.
+ * It looks like part of the file I'm trying to play and definitively looks
+ * like raw midi content
+ * I'd really like to understand why native mcimidi sends it. Perhaps a bad
+ * synchronization issue where native mcimidi is still processing raw MIDI
+ * content before generating MIDIEVENTs ?
+ *
+ * 4c 04 89 3b 00 81 7c 99 3b 43 00 99 23 5e 04 89 L..;..|.;C..#^..
+ * 3b 00 00 89 23 00 7c 99 3b 45 00 99 28 62 04 89 ;...#.|.;E..(b..
+ * 3b 00 00 89 28 00 81 7c 99 3b 4e 00 99 23 5e 04 ;...(..|.;N..#^.
+ * 89 3b 00 00 89 23 00 7c 99 3b 45 00 99 23 78 04 .;...#.|.;E..#x.
+ * 89 3b 00 00 89 23 00 81 7c 99 3b 48 00 99 23 5e .;...#..|.;H..#^
+ * 04 89 3b 00 00 89 23 00 7c 99 3b 4e 00 99 28 62 ..;...#.|.;N..(b
+ * 04 89 3b 00 00 89 28 00 81 7c 99 39 4c 00 99 23 ..;...(..|.9L..#
+ * 5e 04 89 39 00 00 89 23 00 82 7c 99 3b 4c 00 99 ^..9...#..|.;L..
+ * 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b 48 00 99 #^..;...#.|.;H..
+ * 28 62 04 89 3b 00 00 89 28 00 81 7c 99 3b 3f 04 (b..;...(..|.;?.
+ * 89 3b 00 1c 99 23 5e 04 89 23 00 5c 99 3b 45 00 .;...#^..#.\.;E.
+ * 99 23 78 04 89 3b 00 00 89 23 00 81 7c 99 3b 46 .#x..;...#..|.;F
+ * 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b 48 ..#^..;...#.|.;H
+ * 00 99 28 62 04 89 3b 00 00 89 28 00 81 7c 99 3b ..(b..;...(..|.;
+ * 46 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b F..#^..;...#.|.;
+ * 48 00 99 23 78 04 89 3b 00 00 89 23 00 81 7c 99 H..#x..;...#..|.
+ * 3b 4c 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 ;L..#^..;...#.|.
+ */
+ lpMidiHdr = (LPMIDIHDR)msg->lParam;
+ lpData = lpMidiHdr->lpData;
+ TRACE("Adding %s lpMidiHdr=%p [lpData=0x%08lx dwBufferLength=%lu/%lu dwFlags=0x%08lx size=%u]\n",
+ (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular", lpMidiHdr,
+ (DWORD)lpMidiHdr, lpMidiHdr->dwBufferLength, lpMidiHdr->dwBytesRecorded,
+ lpMidiHdr->dwFlags, msg->wParam);
+#if 0
+ /* dumps content of lpMidiHdr->lpData
+ * FIXME: there should be a debug routine somewhere that already does this
+ * I hate spreading this type of shit all around the code
+ */
+ for (dwToGo = 0; dwToGo < lpMidiHdr->dwBufferLength; dwToGo += 16) {
+ DWORD i;
+ BYTE ch;
+
+ for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++)
+ printf("%02x ", lpData[dwToGo + i]);
+ for (; i < 16; i++)
+ printf(" ");
+ for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++) {
+ ch = lpData[dwToGo + i];
+ printf("%c", (ch >= 0x20 && ch <= 0x7F) ? ch : '.');
+ }
+ printf("\n");
+ }
+#endif
+ if (((LPMIDIEVENT)lpData)->dwStreamID != 0 &&
+ ((LPMIDIEVENT)lpData)->dwStreamID != 0xFFFFFFFF &&
+ ((LPMIDIEVENT)lpData)->dwStreamID != (DWORD)lpMidiStrm) {
+ FIXME("Dropping bad %s lpMidiHdr (streamID=%08lx)\n",
+ (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular",
+ ((LPMIDIEVENT)lpData)->dwStreamID);
+ lpMidiHdr->dwFlags |= MHDR_DONE;
+ lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
+
+ DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
+ (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
+ lpwm->mod.dwInstance, (DWORD)lpMidiHdr, 0L);
+ break;
+ }
+
+ for (lpmh = &lpMidiStrm->lpMidiHdr; *lpmh; lpmh = (LPMIDIHDR*)&((*lpmh)->lpNext));
+ *lpmh = lpMidiHdr;
+ lpMidiHdr = (LPMIDIHDR)msg->lParam;
+ lpMidiHdr->lpNext = 0;
+ lpMidiHdr->dwFlags |= MHDR_INQUEUE;
+ lpMidiHdr->dwFlags &= MHDR_DONE;
+ lpMidiHdr->dwOffset = 0;
+
+ break;
+ default:
+ FIXME("Unknown message %d\n", msg->message);
+ break;
+ }
+ return TRUE;
+}
+
+/**************************************************************************
+ * MMSYSTEM_MidiStream_Player [internal]
+ */
+static DWORD CALLBACK MMSYSTEM_MidiStream_Player(LPVOID pmt)
+{
+ WINE_MIDIStream* lpMidiStrm = pmt;
+ WINE_MIDI* lpwm;
+ MSG msg;
+ DWORD dwToGo;
+ DWORD dwCurrTC;
+ LPMIDIHDR lpMidiHdr;
+ LPMIDIEVENT me;
+ LPBYTE lpData = 0;
+
+ TRACE("(%p)!\n", lpMidiStrm);
+
+ if (!lpMidiStrm ||
+ (lpwm = (LPWINE_MIDI)MMDRV_Get(lpMidiStrm->hDevice, MMDRV_MIDIOUT, FALSE)) == NULL)
+ goto the_end;
+
+ /* force thread's queue creation */
+ /* Used to be InitThreadInput16(0, 5); */
+ /* but following works also with hack in midiStreamOpen */
+ PeekMessageA(&msg, 0, 0, 0, 0);
+
+ /* FIXME: this next line must be called before midiStreamOut or midiStreamRestart are called */
+ SetEvent(lpMidiStrm->hEvent);
+ TRACE("Ready to go 1\n");
+ /* thread is started in paused mode */
+ SuspendThread(lpMidiStrm->hThread);
+ TRACE("Ready to go 2\n");
+
+ lpMidiStrm->dwStartTicks = 0;
+ lpMidiStrm->dwPulses = 0;
+
+ lpMidiStrm->lpMidiHdr = 0;
+
+ for (;;) {
+ lpMidiHdr = lpMidiStrm->lpMidiHdr;
+ if (!lpMidiHdr) {
+ /* for first message, block until one arrives, then process all that are available */
+ GetMessageA(&msg, 0, 0, 0);
+ do {
+ if (!MMSYSTEM_MidiStream_MessageHandler(lpMidiStrm, lpwm, &msg))
+ goto the_end;
+ } while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE));
+ lpData = 0;
+ continue;
+ }
+
+ if (!lpData)
+ lpData = lpMidiHdr->lpData;
+
+ me = (LPMIDIEVENT)(lpData + lpMidiHdr->dwOffset);
+
+ /* do we have to wait ? */
+ if (me->dwDeltaTime) {
+ lpMidiStrm->dwPositionMS += MMSYSTEM_MidiStream_Convert(lpMidiStrm, me->dwDeltaTime);
+ lpMidiStrm->dwPulses += me->dwDeltaTime;
+
+ dwToGo = lpMidiStrm->dwStartTicks + lpMidiStrm->dwPositionMS;
+
+ TRACE("%ld/%ld/%ld\n", dwToGo, GetTickCount(), me->dwDeltaTime);
+ while ((dwCurrTC = GetTickCount()) < dwToGo) {
+ if (MsgWaitForMultipleObjects(0, NULL, FALSE, dwToGo - dwCurrTC, QS_ALLINPUT) == WAIT_OBJECT_0) {
+ /* got a message, handle it */
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
+ if (!MMSYSTEM_MidiStream_MessageHandler(lpMidiStrm, lpwm, &msg))
+ goto the_end;
+ }
+ lpData = 0;
+ } else {
+ /* timeout, so me->dwDeltaTime is elapsed, can break the while loop */
+ break;
+ }
+ }
+ }
+ switch (MEVT_EVENTTYPE(me->dwEvent & ~MEVT_F_CALLBACK)) {
+ case MEVT_COMMENT:
+ FIXME("NIY: MEVT_COMMENT\n");
+ /* do nothing, skip bytes */
+ break;
+ case MEVT_LONGMSG:
+ FIXME("NIY: MEVT_LONGMSG, aka sending Sysex event\n");
+ break;
+ case MEVT_NOP:
+ break;
+ case MEVT_SHORTMSG:
+ midiOutShortMsg(lpMidiStrm->hDevice, MEVT_EVENTPARM(me->dwEvent));
+ break;
+ case MEVT_TEMPO:
+ lpMidiStrm->dwTempo = MEVT_EVENTPARM(me->dwEvent);
+ break;
+ case MEVT_VERSION:
+ break;
+ default:
+ FIXME("Unknown MEVT (0x%02x)\n", MEVT_EVENTTYPE(me->dwEvent & ~MEVT_F_CALLBACK));
+ break;
+ }
+ if (me->dwEvent & MEVT_F_CALLBACK) {
+ DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
+ (HDRVR)lpMidiStrm->hDevice, MM_MOM_POSITIONCB,
+ lpwm->mod.dwInstance, (LPARAM)lpMidiHdr, 0L);
+ }
+ lpMidiHdr->dwOffset += sizeof(MIDIEVENT) - sizeof(me->dwParms);
+ if (me->dwEvent & MEVT_F_LONG)
+ lpMidiHdr->dwOffset += (MEVT_EVENTPARM(me->dwEvent) + 3) & ~3;
+ if (lpMidiHdr->dwOffset >= lpMidiHdr->dwBufferLength) {
+ /* done with this header */
+ lpMidiHdr->dwFlags |= MHDR_DONE;
+ lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
+
+ lpMidiStrm->lpMidiHdr = (LPMIDIHDR)lpMidiHdr->lpNext;
+ DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
+ (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
+ lpwm->mod.dwInstance, (DWORD)lpMidiHdr, 0L);
+ lpData = 0;
+ }
+ }
+the_end:
+ TRACE("End of thread\n");
+ ExitThread(0);
+ return 0; /* for removing the warning, never executed */
+}
+
+/**************************************************************************
+ * MMSYSTEM_MidiStream_PostMessage [internal]
+ */
+static BOOL MMSYSTEM_MidiStream_PostMessage(WINE_MIDIStream* lpMidiStrm, WORD msg, DWORD pmt1, DWORD pmt2)
+{
+ if (PostThreadMessageA(lpMidiStrm->dwThreadID, msg, pmt1, pmt2)) {
+ DWORD count;
+
+ ReleaseThunkLock(&count);
+ WaitForSingleObject(lpMidiStrm->hEvent, INFINITE);
+ RestoreThunkLock(count);
+ } else {
+ WARN("bad PostThreadMessageA\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**************************************************************************
+ * midiStreamClose [WINMM.@]
+ */
+MMRESULT WINAPI midiStreamClose(HMIDISTRM hMidiStrm)
+{
+ WINE_MIDIStream* lpMidiStrm;
+
+ TRACE("(%08x)!\n", hMidiStrm);
+
+ if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
+ return MMSYSERR_INVALHANDLE;
+
+ midiStreamStop(hMidiStrm);
+ MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WM_QUIT, 0, 0);
+ HeapFree(GetProcessHeap(), 0, lpMidiStrm);
+ CloseHandle(lpMidiStrm->hEvent);
+
+ return midiOutClose((HMIDIOUT)hMidiStrm);
+}
+
+/**************************************************************************
+ * MMSYSTEM_MidiStream_Open [internal]
+ */
+MMRESULT MMSYSTEM_MidiStream_Open(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
+ DWORD cMidi, DWORD dwCallback,
+ DWORD dwInstance, DWORD fdwOpen, BOOL bFrom32)
+{
+ WINE_MIDIStream* lpMidiStrm;
+ MMRESULT ret;
+ MIDIOPENSTRMID mosm;
+ LPWINE_MIDI lpwm;
+ HMIDIOUT hMidiOut;
+
+ TRACE("(%p, %p, %ld, 0x%08lx, 0x%08lx, 0x%08lx)!\n",
+ lphMidiStrm, lpuDeviceID, cMidi, dwCallback, dwInstance, fdwOpen);
+
+ if (cMidi != 1 || lphMidiStrm == NULL || lpuDeviceID == NULL)
+ return MMSYSERR_INVALPARAM;
+
+ lpMidiStrm = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_MIDIStream));
+ if (!lpMidiStrm)
+ return MMSYSERR_NOMEM;
+
+ lpMidiStrm->dwTempo = 500000;
+ lpMidiStrm->dwTimeDiv = 480; /* 480 is 120 quater notes per minute *//* FIXME ??*/
+ lpMidiStrm->dwPositionMS = 0;
+
+ mosm.dwStreamID = (DWORD)lpMidiStrm;
+ /* FIXME: the correct value is not allocated yet for MAPPER */
+ mosm.wDeviceID = *lpuDeviceID;
+ lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &fdwOpen, 1, &mosm, bFrom32);
+ lpMidiStrm->hDevice = hMidiOut;
+ if (lphMidiStrm)
+ *lphMidiStrm = (HMIDISTRM)hMidiOut;
+
+ /* FIXME: is lpuDevice initialized upon entering midiStreamOpen ? */
+ FIXME("*lpuDeviceID=%x\n", *lpuDeviceID);
+ lpwm->mld.uDeviceID = *lpuDeviceID = 0;
+
+ ret = MMDRV_Open(&lpwm->mld, MODM_OPEN, (DWORD)&lpwm->mod, fdwOpen);
+ lpMidiStrm->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
+ lpMidiStrm->wFlags = HIWORD(fdwOpen);
+
+ lpMidiStrm->hThread = CreateThread(NULL, 0, MMSYSTEM_MidiStream_Player,
+ lpMidiStrm, 0, &(lpMidiStrm->dwThreadID));
+
+ if (!lpMidiStrm->hThread) {
+ midiStreamClose((HMIDISTRM)hMidiOut);
+ return MMSYSERR_NOMEM;
+ }
+
+ /* wait for thread to have started, and for its queue to be created */
+ {
+ DWORD count;
+
+ /* (Release|Restore)ThunkLock() is needed when this method is called from 16 bit code,
+ * (meaning the Win16Lock is set), so that it's released and the 32 bit thread running
+ * MMSYSTEM_MidiStreamPlayer can acquire Win16Lock to create its queue.
+ */
+ ReleaseThunkLock(&count);
+ WaitForSingleObject(lpMidiStrm->hEvent, INFINITE);
+ RestoreThunkLock(count);
+ }
+
+ TRACE("=> (%u/%d) hMidi=0x%04x ret=%d lpMidiStrm=%p\n",
+ *lpuDeviceID, lpwm->mld.uDeviceID, *lphMidiStrm, ret, lpMidiStrm);
+ return ret;
+}
+
+/**************************************************************************
+ * midiStreamOpen [WINMM.@]
+ */
+MMRESULT WINAPI midiStreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
+ DWORD cMidi, DWORD dwCallback,
+ DWORD dwInstance, DWORD fdwOpen)
+{
+ return MMSYSTEM_MidiStream_Open(lphMidiStrm, lpuDeviceID, cMidi, dwCallback,
+ dwInstance, fdwOpen, TRUE);
+}
+
+/**************************************************************************
+ * midiStreamOut [WINMM.@]
+ */
+MMRESULT WINAPI midiStreamOut(HMIDISTRM hMidiStrm, LPMIDIHDR lpMidiHdr,
+ UINT cbMidiHdr)
+{
+ WINE_MIDIStream* lpMidiStrm;
+ DWORD ret = MMSYSERR_NOERROR;
+
+ TRACE("(%08x, %p, %u)!\n", hMidiStrm, lpMidiHdr, cbMidiHdr);
+
+ if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
+ ret = MMSYSERR_INVALHANDLE;
+ } else if (!lpMidiHdr) {
+ ret = MMSYSERR_INVALPARAM;
+ } else {
+ if (!PostThreadMessageA(lpMidiStrm->dwThreadID,
+ WINE_MSM_HEADER, cbMidiHdr,
+ (DWORD)lpMidiHdr)) {
+ WARN("bad PostThreadMessageA\n");
+ ret = MMSYSERR_ERROR;
+ }
+ }
+ return ret;
+}
+
+/**************************************************************************
+ * midiStreamPause [WINMM.@]
+ */
+MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
+{
+ WINE_MIDIStream* lpMidiStrm;
+ DWORD ret = MMSYSERR_NOERROR;
+
+ TRACE("(%08x)!\n", hMidiStrm);
+
+ if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
+ ret = MMSYSERR_INVALHANDLE;
+ } else {
+ if (SuspendThread(lpMidiStrm->hThread) == 0xFFFFFFFF) {
+ WARN("bad Suspend (%ld)\n", GetLastError());
+ ret = MMSYSERR_ERROR;
+ }
+ }
+ return ret;
+}
+
+/**************************************************************************
+ * midiStreamPosition [WINMM.@]
+ */
+MMRESULT WINAPI midiStreamPosition(HMIDISTRM hMidiStrm, LPMMTIME lpMMT, UINT cbmmt)
+{
+ WINE_MIDIStream* lpMidiStrm;
+ DWORD ret = MMSYSERR_NOERROR;
+
+ TRACE("(%08x, %p, %u)!\n", hMidiStrm, lpMMT, cbmmt);
+
+ if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
+ ret = MMSYSERR_INVALHANDLE;
+ } else if (lpMMT == NULL || cbmmt != sizeof(MMTIME)) {
+ ret = MMSYSERR_INVALPARAM;
+ } else {
+ switch (lpMMT->wType) {
+ case TIME_MS:
+ lpMMT->u.ms = lpMidiStrm->dwPositionMS;
+ TRACE("=> %ld ms\n", lpMMT->u.ms);
+ break;
+ case TIME_TICKS:
+ lpMMT->u.ticks = lpMidiStrm->dwPulses;
+ TRACE("=> %ld ticks\n", lpMMT->u.ticks);
+ break;
+ default:
+ WARN("Unsupported time type %d\n", lpMMT->wType);
+ lpMMT->wType = TIME_MS;
+ ret = MMSYSERR_INVALPARAM;
+ break;
+ }
+ }
+ return ret;
+}
+
+/**************************************************************************
+ * midiStreamProperty [WINMM.@]
+ */
+MMRESULT WINAPI midiStreamProperty(HMIDISTRM hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
+{
+ WINE_MIDIStream* lpMidiStrm;
+ MMRESULT ret = MMSYSERR_NOERROR;
+
+ TRACE("(%08x, %p, %lx)\n", hMidiStrm, lpPropData, dwProperty);
+
+ if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
+ ret = MMSYSERR_INVALHANDLE;
+ } else if ((dwProperty & (MIDIPROP_GET|MIDIPROP_SET)) == 0) {
+ ret = MMSYSERR_INVALPARAM;
+ } else if (dwProperty & MIDIPROP_TEMPO) {
+ MIDIPROPTEMPO* mpt = (MIDIPROPTEMPO*)lpPropData;
+
+ if (sizeof(MIDIPROPTEMPO) != mpt->cbStruct) {
+ ret = MMSYSERR_INVALPARAM;
+ } else if (dwProperty & MIDIPROP_SET) {
+ lpMidiStrm->dwTempo = mpt->dwTempo;
+ TRACE("Setting tempo to %ld\n", mpt->dwTempo);
+ } else if (dwProperty & MIDIPROP_GET) {
+ mpt->dwTempo = lpMidiStrm->dwTempo;
+ TRACE("Getting tempo <= %ld\n", mpt->dwTempo);
+ }
+ } else if (dwProperty & MIDIPROP_TIMEDIV) {
+ MIDIPROPTIMEDIV* mptd = (MIDIPROPTIMEDIV*)lpPropData;
+
+ if (sizeof(MIDIPROPTIMEDIV) != mptd->cbStruct) {
+ ret = MMSYSERR_INVALPARAM;
+ } else if (dwProperty & MIDIPROP_SET) {
+ lpMidiStrm->dwTimeDiv = mptd->dwTimeDiv;
+ TRACE("Setting time div to %ld\n", mptd->dwTimeDiv);
+ } else if (dwProperty & MIDIPROP_GET) {
+ mptd->dwTimeDiv = lpMidiStrm->dwTimeDiv;
+ TRACE("Getting time div <= %ld\n", mptd->dwTimeDiv);
+ }
+ } else {
+ ret = MMSYSERR_INVALPARAM;
+ }
+
+ return ret;
+}
+
+/**************************************************************************
+ * midiStreamRestart [WINMM.@]
+ */
+MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
+{
+ WINE_MIDIStream* lpMidiStrm;
+ MMRESULT ret = MMSYSERR_NOERROR;
+
+ TRACE("(%08x)!\n", hMidiStrm);
+
+ if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
+ ret = MMSYSERR_INVALHANDLE;
+ } else {
+ DWORD ret;
+
+ /* since we increase the thread suspend count on each midiStreamPause
+ * there may be a need for several midiStreamResume
+ */
+ do {
+ ret = ResumeThread(lpMidiStrm->hThread);
+ } while (ret != 0xFFFFFFFF && ret != 0);
+ if (ret == 0xFFFFFFFF) {
+ WARN("bad Resume (%ld)\n", GetLastError());
+ ret = MMSYSERR_ERROR;
+ } else {
+ lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwPositionMS;
+ }
+ }
+ return ret;
+}
+
+/**************************************************************************
+ * midiStreamStop [WINMM.@]
+ */
+MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
+{
+ WINE_MIDIStream* lpMidiStrm;
+ MMRESULT ret = MMSYSERR_NOERROR;
+
+ TRACE("(%08x)!\n", hMidiStrm);
+
+ if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
+ ret = MMSYSERR_INVALHANDLE;
+ } else {
+ /* in case stream has been paused... FIXME is the current state correct ? */
+ midiStreamRestart(hMidiStrm);
+ MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WINE_MSM_STOP, 0, 0);
+ }
+ return ret;
+}
+
+UINT MMSYSTEM_waveOpen(HANDLE* lphndl, UINT uDeviceID, UINT uType,
+ const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
+ DWORD dwInstance, DWORD dwFlags, BOOL bFrom32)
+{
+ HANDLE handle;
+ LPWINE_MLD wmld;
+ DWORD dwRet = MMSYSERR_NOERROR;
+ WAVEOPENDESC wod;
+
+ TRACE("(%p, %d, %s, %p, %08lX, %08lX, %08lX, %d);\n",
+ lphndl, (int)uDeviceID, (uType==MMDRV_WAVEOUT)?"Out":"In", lpFormat, dwCallback,
+ dwInstance, dwFlags, bFrom32?32:16);
+
+ if (dwFlags & WAVE_FORMAT_QUERY) TRACE("WAVE_FORMAT_QUERY requested !\n");
+
+ if (lpFormat == NULL) return WAVERR_BADFORMAT;
+ if ((dwFlags & WAVE_MAPPED) && (uDeviceID == (UINT)-1))
+ return MMSYSERR_INVALPARAM;
+
+ TRACE("wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u\n",
+ lpFormat->wFormatTag, lpFormat->nChannels, lpFormat->nSamplesPerSec,
+ lpFormat->nAvgBytesPerSec, lpFormat->nBlockAlign, lpFormat->wBitsPerSample, lpFormat->cbSize);
+
+ if ((wmld = MMDRV_Alloc(sizeof(WINE_WAVE), uType, &handle,
+ &dwFlags, &dwCallback, &dwInstance, bFrom32)) == NULL)
+ return MMSYSERR_NOMEM;
+
+ wod.hWave = handle;
+ wod.lpFormat = lpFormat; /* should the struct be copied iso pointer? */
+ wod.dwCallback = dwCallback;
+ wod.dwInstance = dwInstance;
+ wod.dnDevNode = 0L;
+
+ for (;;) {
+ if (dwFlags & WAVE_MAPPED) {
+ wod.uMappedDeviceID = uDeviceID;
+ uDeviceID = WAVE_MAPPER;
+ } else {
+ wod.uMappedDeviceID = -1;
+ }
+ wmld->uDeviceID = uDeviceID;
+
+ dwRet = MMDRV_Open(wmld, (uType == MMDRV_WAVEOUT) ? WODM_OPEN : WIDM_OPEN,
+ (DWORD)&wod, dwFlags);
+
+ if (dwRet != WAVERR_BADFORMAT ||
+ (dwFlags & (WAVE_MAPPED|WAVE_FORMAT_DIRECT)) != 0) break;
+ /* if we ask for a format which isn't supported by the physical driver,
+ * let's try to map it through the wave mapper (except, if we already tried
+ * or user didn't allow us to use acm codecs)
+ */
+ dwFlags |= WAVE_MAPPED;
+ /* we shall loop only one */
+ }
+
+ if ((dwFlags & WAVE_FORMAT_QUERY) || dwRet != MMSYSERR_NOERROR) {
+ MMDRV_Free(handle, wmld);
+ handle = 0;
+ }
+
+ if (lphndl != NULL) *lphndl = handle;
+ TRACE("=> %ld hWave=%04x\n", dwRet, handle);
+
+ return dwRet;
+}
+
+/**************************************************************************
+ * waveOutGetNumDevs [WINMM.@]
+ */
+UINT WINAPI waveOutGetNumDevs(void)
+{
+ return MMDRV_GetNum(MMDRV_WAVEOUT);
+}
+
+/**************************************************************************
+ * waveOutGetDevCapsA [WINMM.@]
+ */
+UINT WINAPI waveOutGetDevCapsA(UINT uDeviceID, LPWAVEOUTCAPSA lpCaps,
+ UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%u %p %u)!\n", uDeviceID, lpCaps, uSize);
+
+ if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
+
+ if ((wmld = MMDRV_Get(uDeviceID, MMDRV_WAVEOUT, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WODM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
+
+}
+
+/**************************************************************************
+ * waveOutGetDevCapsW [WINMM.@]
+ */
+UINT WINAPI waveOutGetDevCapsW(UINT uDeviceID, LPWAVEOUTCAPSW lpCaps,
+ UINT uSize)
+{
+ WAVEOUTCAPSA wocA;
+ UINT ret;
+
+ if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
+
+ ret = waveOutGetDevCapsA(uDeviceID, &wocA, sizeof(wocA));
+
+ if (ret == MMSYSERR_NOERROR) {
+ lpCaps->wMid = wocA.wMid;
+ lpCaps->wPid = wocA.wPid;
+ lpCaps->vDriverVersion = wocA.vDriverVersion;
+ MultiByteToWideChar( CP_ACP, 0, wocA.szPname, -1, lpCaps->szPname,
+ sizeof(lpCaps->szPname)/sizeof(WCHAR) );
+ lpCaps->dwFormats = wocA.dwFormats;
+ lpCaps->wChannels = wocA.wChannels;
+ lpCaps->dwSupport = wocA.dwSupport;
+ }
+ return ret;
+}
+
+/**************************************************************************
+ * WAVE_GetErrorText [internal]
+ */
+static UINT16 WAVE_GetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize)
+{
+ UINT16 ret = MMSYSERR_BADERRNUM;
+
+ if (lpText == NULL) {
+ ret = MMSYSERR_INVALPARAM;
+ } else if (uSize == 0) {
+ ret = MMSYSERR_NOERROR;
+ } else if (
+ /* test has been removed 'coz MMSYSERR_BASE is 0, and gcc did emit
+ * a warning for the test was always true */
+ (/*uError >= MMSYSERR_BASE && */uError <= MMSYSERR_LASTERROR) ||
+ (uError >= WAVERR_BASE && uError <= WAVERR_LASTERROR)) {
+
+ if (LoadStringA(MULTIMEDIA_GetIData()->hWinMM32Instance,
+ uError, lpText, uSize) > 0) {
+ ret = MMSYSERR_NOERROR;
+ }
+ }
+ return ret;
+}
+
+/**************************************************************************
+ * waveOutGetErrorTextA [WINMM.@]
+ */
+UINT WINAPI waveOutGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
+{
+ return WAVE_GetErrorText(uError, lpText, uSize);
+}
+
+/**************************************************************************
+ * waveOutGetErrorTextW [WINMM.@]
+ */
+UINT WINAPI waveOutGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
+{
+ LPSTR xstr = HeapAlloc(GetProcessHeap(), 0, uSize);
+ UINT ret = WAVE_GetErrorText(uError, xstr, uSize);
+
+ MultiByteToWideChar( CP_ACP, 0, xstr, -1, lpText, uSize );
+ HeapFree(GetProcessHeap(), 0, xstr);
+ return ret;
+}
+
+/**************************************************************************
+ * waveOutOpen [WINMM.@]
+ * All the args/structs have the same layout as the win16 equivalents
+ */
+UINT WINAPI waveOutOpen(HWAVEOUT* lphWaveOut, UINT uDeviceID,
+ const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
+ DWORD dwInstance, DWORD dwFlags)
+{
+ return MMSYSTEM_waveOpen(lphWaveOut, uDeviceID, MMDRV_WAVEOUT, lpFormat,
+ dwCallback, dwInstance, dwFlags, TRUE);
+}
+
+/**************************************************************************
+ * waveOutClose [WINMM.@]
+ */
+UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
+{
+ LPWINE_MLD wmld;
+ DWORD dwRet;
+
+ TRACE("(%04X)\n", hWaveOut);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ dwRet = MMDRV_Close(wmld, WODM_CLOSE);
+ MMDRV_Free(hWaveOut, wmld);
+
+ return dwRet;
+}
+
+/**************************************************************************
+ * waveOutPrepareHeader [WINMM.@]
+ */
+UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut,
+ WAVEHDR* lpWaveOutHdr, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
+
+ if (lpWaveOutHdr == NULL) return MMSYSERR_INVALPARAM;
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WODM_PREPARE, (DWORD)lpWaveOutHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * waveOutUnprepareHeader [WINMM.@]
+ */
+UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut,
+ LPWAVEHDR lpWaveOutHdr, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
+
+ if (!(lpWaveOutHdr->dwFlags & WHDR_PREPARED)) {
+ return MMSYSERR_NOERROR;
+ }
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD)lpWaveOutHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * waveOutWrite [WINMM.@]
+ */
+UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr,
+ UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WODM_WRITE, (DWORD)lpWaveOutHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * waveOutBreakLoop [WINMM.@]
+ */
+UINT WINAPI waveOutBreakLoop(HWAVEOUT hWaveOut)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X);\n", hWaveOut);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ return MMDRV_Message(wmld, WODM_BREAKLOOP, 0L, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveOutPause [WINMM.@]
+ */
+UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X);\n", hWaveOut);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ return MMDRV_Message(wmld, WODM_PAUSE, 0L, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveOutReset [WINMM.@]
+ */
+UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X);\n", hWaveOut);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ return MMDRV_Message(wmld, WODM_RESET, 0L, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveOutRestart [WINMM.@]
+ */
+UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X);\n", hWaveOut);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ return MMDRV_Message(wmld, WODM_RESTART, 0L, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveOutGetPosition [WINMM.@]
+ */
+UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, LPMMTIME lpTime,
+ UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %u);\n", hWaveOut, lpTime, uSize);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WODM_GETPOS, (DWORD)lpTime, uSize, TRUE);
+}
+
+/**************************************************************************
+ * waveOutGetPitch [WINMM.@]
+ */
+UINT WINAPI waveOutGetPitch(HWAVEOUT hWaveOut, LPDWORD lpdw)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %08lx);\n", hWaveOut, (DWORD)lpdw);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ return MMDRV_Message(wmld, WODM_GETPITCH, (DWORD)lpdw, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveOutSetPitch [WINMM.@]
+ */
+UINT WINAPI waveOutSetPitch(HWAVEOUT hWaveOut, DWORD dw)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %08lx);\n", hWaveOut, (DWORD)dw);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ return MMDRV_Message(wmld, WODM_SETPITCH, dw, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveOutGetPlaybackRate [WINMM.@]
+ */
+UINT WINAPI waveOutGetPlaybackRate(HWAVEOUT hWaveOut, LPDWORD lpdw)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %08lx);\n", hWaveOut, (DWORD)lpdw);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ return MMDRV_Message(wmld, WODM_GETPLAYBACKRATE, (DWORD)lpdw, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveOutSetPlaybackRate [WINMM.@]
+ */
+UINT WINAPI waveOutSetPlaybackRate(HWAVEOUT hWaveOut, DWORD dw)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %08lx);\n", hWaveOut, (DWORD)dw);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ return MMDRV_Message(wmld, WODM_SETPLAYBACKRATE, dw, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveOutGetVolume [WINMM.@]
+ */
+UINT WINAPI waveOutGetVolume(UINT devid, LPDWORD lpdw)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %08lx);\n", devid, (DWORD)lpdw);
+
+ if ((wmld = MMDRV_Get(devid, MMDRV_WAVEOUT, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WODM_GETVOLUME, (DWORD)lpdw, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveOutSetVolume [WINMM.@]
+ */
+UINT WINAPI waveOutSetVolume(UINT devid, DWORD dw)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %08lx);\n", devid, dw);
+
+ if ((wmld = MMDRV_Get(devid, MMDRV_WAVEOUT, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WODM_SETVOLUME, dw, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveOutGetID [WINMM.@]
+ */
+UINT WINAPI waveOutGetID(HWAVEOUT hWaveOut, UINT* lpuDeviceID)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p);\n", hWaveOut, lpuDeviceID);
+
+ if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ *lpuDeviceID = wmld->uDeviceID;
+ return 0;
+}
+
+/**************************************************************************
+ * waveOutMessage [WINMM.@]
+ */
+DWORD WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage,
+ DWORD dwParam1, DWORD dwParam2)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04x, %u, %ld, %ld)\n", hWaveOut, uMessage, dwParam1, dwParam2);
+
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL) {
+ if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, TRUE)) != NULL) {
+ return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
+ }
+ return MMSYSERR_INVALHANDLE;
+ }
+
+ /* from M$ KB */
+ if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
+ return MMSYSERR_INVALPARAM;
+
+ return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
+}
+
+/**************************************************************************
+ * waveInGetNumDevs [WINMM.@]
+ */
+UINT WINAPI waveInGetNumDevs(void)
+{
+ return MMDRV_GetNum(MMDRV_WAVEIN);
+}
+
+/**************************************************************************
+ * waveInGetDevCapsW [WINMM.@]
+ */
+UINT WINAPI waveInGetDevCapsW(UINT uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize)
+{
+ WAVEINCAPSA wicA;
+ UINT ret = waveInGetDevCapsA(uDeviceID, &wicA, uSize);
+
+ if (ret == MMSYSERR_NOERROR) {
+ lpCaps->wMid = wicA.wMid;
+ lpCaps->wPid = wicA.wPid;
+ lpCaps->vDriverVersion = wicA.vDriverVersion;
+ MultiByteToWideChar( CP_ACP, 0, wicA.szPname, -1, lpCaps->szPname,
+ sizeof(lpCaps->szPname)/sizeof(WCHAR) );
+ lpCaps->dwFormats = wicA.dwFormats;
+ lpCaps->wChannels = wicA.wChannels;
+ }
+
+ return ret;
+}
+
+/**************************************************************************
+ * waveInGetDevCapsA [WINMM.@]
+ */
+UINT WINAPI waveInGetDevCapsA(UINT uDeviceID, LPWAVEINCAPSA lpCaps, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%u %p %u)!\n", uDeviceID, lpCaps, uSize);
+
+ if ((wmld = MMDRV_Get(uDeviceID, MMDRV_WAVEIN, TRUE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WIDM_GETDEVCAPS, (DWORD)lpCaps, uSize, TRUE);
+}
+
+/**************************************************************************
+ * waveInGetErrorTextA [WINMM.@]
+ */
+UINT WINAPI waveInGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
+{
+ return WAVE_GetErrorText(uError, lpText, uSize);
+}
+
+/**************************************************************************
+ * waveInGetErrorTextW [WINMM.@]
+ */
+UINT WINAPI waveInGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
+{
+ LPSTR txt = HeapAlloc(GetProcessHeap(), 0, uSize);
+ UINT ret = WAVE_GetErrorText(uError, txt, uSize);
+
+ MultiByteToWideChar( CP_ACP, 0, txt, -1, lpText, uSize );
+ HeapFree(GetProcessHeap(), 0, txt);
+ return ret;
+}
+
+/**************************************************************************
+ * waveInOpen [WINMM.@]
+ */
+UINT WINAPI waveInOpen(HWAVEIN* lphWaveIn, UINT uDeviceID,
+ const LPWAVEFORMATEX lpFormat, DWORD dwCallback,
+ DWORD dwInstance, DWORD dwFlags)
+{
+ return MMSYSTEM_waveOpen(lphWaveIn, uDeviceID, MMDRV_WAVEIN, lpFormat,
+ dwCallback, dwInstance, dwFlags, TRUE);
+}
+
+/**************************************************************************
+ * waveInClose [WINMM.@]
+ */
+UINT WINAPI waveInClose(HWAVEIN hWaveIn)
+{
+ LPWINE_MLD wmld;
+ DWORD dwRet;
+
+ TRACE("(%04X)\n", hWaveIn);
+
+ if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ dwRet = MMDRV_Message(wmld, WIDM_CLOSE, 0L, 0L, TRUE);
+ MMDRV_Free(hWaveIn, wmld);
+ return dwRet;
+}
+
+/**************************************************************************
+ * waveInPrepareHeader [WINMM.@]
+ */
+UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr,
+ UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
+
+ if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
+ if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ lpWaveInHdr->dwBytesRecorded = 0;
+
+ return MMDRV_Message(wmld, WIDM_PREPARE, (DWORD)lpWaveInHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * waveInUnprepareHeader [WINMM.@]
+ */
+UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr,
+ UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
+
+ if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
+ if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED)) {
+ return MMSYSERR_NOERROR;
+ }
+
+ if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD)lpWaveInHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * waveInAddBuffer [WINMM.@]
+ */
+UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn,
+ WAVEHDR* lpWaveInHdr, UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
+
+ if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
+ if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD)lpWaveInHdr, uSize, TRUE);
+}
+
+/**************************************************************************
+ * waveInReset [WINMM.@]
+ */
+UINT WINAPI waveInReset(HWAVEIN hWaveIn)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X);\n", hWaveIn);
+
+ if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WIDM_RESET, 0L, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveInStart [WINMM.@]
+ */
+UINT WINAPI waveInStart(HWAVEIN hWaveIn)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X);\n", hWaveIn);
+
+ if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WIDM_START, 0L, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveInStop [WINMM.@]
+ */
+UINT WINAPI waveInStop(HWAVEIN hWaveIn)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X);\n", hWaveIn);
+
+ if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld,WIDM_STOP, 0L, 0L, TRUE);
+}
+
+/**************************************************************************
+ * waveInGetPosition [WINMM.@]
+ */
+UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, LPMMTIME lpTime,
+ UINT uSize)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p, %u);\n", hWaveIn, lpTime, uSize);
+
+ if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, WIDM_GETPOS, (DWORD)lpTime, uSize, TRUE);
+}
+
+/**************************************************************************
+ * waveInGetID [WINMM.@]
+ */
+UINT WINAPI waveInGetID(HWAVEIN hWaveIn, UINT* lpuDeviceID)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04X, %p);\n", hWaveIn, lpuDeviceID);
+
+ if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
+
+ if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ *lpuDeviceID = wmld->uDeviceID;
+ return MMSYSERR_NOERROR;
+}
+
+/**************************************************************************
+ * waveInMessage [WINMM.@]
+ */
+DWORD WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage,
+ DWORD dwParam1, DWORD dwParam2)
+{
+ LPWINE_MLD wmld;
+
+ TRACE("(%04x, %u, %ld, %ld)\n", hWaveIn, uMessage, dwParam1, dwParam2);
+
+ /* from M$ KB */
+ if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
+ return MMSYSERR_INVALPARAM;
+
+ if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+
+ return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
+}
+
More information about the wine-patches
mailing list