📄 winmm.c
字号:
return MMDRV_Message(&lpwm->mld, MXDM_GETCONTROLDETAILS, (DWORD_PTR)lpmcdW,
fdwDetails, TRUE);
}
/**************************************************************************
* mixerGetControlDetailsA [WINMM.@]
*/
UINT WINAPI mixerGetControlDetailsA(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdA,
DWORD fdwDetails)
{
DWORD ret = MMSYSERR_NOTENABLED;
TRACE("(%p, %p, %08lx)\n", hmix, lpmcdA, fdwDetails);
if (lpmcdA == NULL || lpmcdA->cbStruct != sizeof(*lpmcdA))
return MMSYSERR_INVALPARAM;
switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
case MIXER_GETCONTROLDETAILSF_VALUE:
/* can savely use A structure as it is, no string inside */
ret = mixerGetControlDetailsW(hmix, lpmcdA, fdwDetails);
break;
case MIXER_GETCONTROLDETAILSF_LISTTEXT:
{
MIXERCONTROLDETAILS_LISTTEXTA *pDetailsA = (MIXERCONTROLDETAILS_LISTTEXTA *)lpmcdA->paDetails;
MIXERCONTROLDETAILS_LISTTEXTW *pDetailsW;
int size = max(1, lpmcdA->cChannels) * sizeof(MIXERCONTROLDETAILS_LISTTEXTW);
unsigned int i;
if (lpmcdA->u.cMultipleItems != 0) {
size *= lpmcdA->u.cMultipleItems;
}
pDetailsW = HeapAlloc(GetProcessHeap(), 0, size);
lpmcdA->paDetails = pDetailsW;
lpmcdA->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTW);
/* set up lpmcd->paDetails */
ret = mixerGetControlDetailsW(hmix, lpmcdA, fdwDetails);
/* copy from lpmcd->paDetails back to paDetailsW; */
if (ret == MMSYSERR_NOERROR) {
for (i = 0; i < lpmcdA->u.cMultipleItems * lpmcdA->cChannels; i++) {
pDetailsA->dwParam1 = pDetailsW->dwParam1;
pDetailsA->dwParam2 = pDetailsW->dwParam2;
WideCharToMultiByte( CP_ACP, 0, pDetailsW->szName, -1,
pDetailsA->szName,
sizeof(pDetailsA->szName), NULL, NULL );
pDetailsA++;
pDetailsW++;
}
pDetailsA -= lpmcdA->u.cMultipleItems * lpmcdA->cChannels;
pDetailsW -= lpmcdA->u.cMultipleItems * lpmcdA->cChannels;
}
HeapFree(GetProcessHeap(), 0, pDetailsW);
lpmcdA->paDetails = pDetailsA;
lpmcdA->cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTA);
}
break;
default:
ERR("Unsupported fdwDetails=0x%08lx\n", fdwDetails);
}
return ret;
}
/**************************************************************************
* mixerGetLineControlsA [WINMM.@]
*/
UINT WINAPI mixerGetLineControlsA(HMIXEROBJ hmix, LPMIXERLINECONTROLSA lpmlcA,
DWORD fdwControls)
{
MIXERLINECONTROLSW mlcW;
DWORD ret;
unsigned int i;
TRACE("(%p, %p, %08lx)\n", hmix, lpmlcA, fdwControls);
if (lpmlcA == NULL || lpmlcA->cbStruct != sizeof(*lpmlcA) ||
lpmlcA->cbmxctrl != sizeof(MIXERCONTROLA))
return MMSYSERR_INVALPARAM;
mlcW.cbStruct = sizeof(mlcW);
mlcW.dwLineID = lpmlcA->dwLineID;
mlcW.u.dwControlID = lpmlcA->u.dwControlID;
mlcW.u.dwControlType = lpmlcA->u.dwControlType;
/* Debugging on Windows shows for MIXER_GETLINECONTROLSF_ONEBYTYPE only,
the control count is assumed to be 1 - This is relied upon by a game,
"Dynomite Deluze" */
if (MIXER_GETLINECONTROLSF_ONEBYTYPE == fdwControls) {
mlcW.cControls = 1;
} else {
mlcW.cControls = lpmlcA->cControls;
}
mlcW.cbmxctrl = sizeof(MIXERCONTROLW);
mlcW.pamxctrl = HeapAlloc(GetProcessHeap(), 0,
mlcW.cControls * mlcW.cbmxctrl);
ret = mixerGetLineControlsW(hmix, &mlcW, fdwControls);
if (ret == MMSYSERR_NOERROR) {
lpmlcA->dwLineID = mlcW.dwLineID;
lpmlcA->u.dwControlID = mlcW.u.dwControlID;
lpmlcA->u.dwControlType = mlcW.u.dwControlType;
lpmlcA->cControls = mlcW.cControls;
for (i = 0; i < mlcW.cControls; i++) {
lpmlcA->pamxctrl[i].cbStruct = sizeof(MIXERCONTROLA);
lpmlcA->pamxctrl[i].dwControlID = mlcW.pamxctrl[i].dwControlID;
lpmlcA->pamxctrl[i].dwControlType = mlcW.pamxctrl[i].dwControlType;
lpmlcA->pamxctrl[i].fdwControl = mlcW.pamxctrl[i].fdwControl;
lpmlcA->pamxctrl[i].cMultipleItems = mlcW.pamxctrl[i].cMultipleItems;
WideCharToMultiByte( CP_ACP, 0, mlcW.pamxctrl[i].szShortName, -1,
lpmlcA->pamxctrl[i].szShortName,
sizeof(lpmlcA->pamxctrl[i].szShortName), NULL, NULL );
WideCharToMultiByte( CP_ACP, 0, mlcW.pamxctrl[i].szName, -1,
lpmlcA->pamxctrl[i].szName,
sizeof(lpmlcA->pamxctrl[i].szName), NULL, NULL );
/* sizeof(lpmlcA->pamxctrl[i].Bounds) ==
* sizeof(mlcW.pamxctrl[i].Bounds) */
memcpy(&lpmlcA->pamxctrl[i].Bounds, &mlcW.pamxctrl[i].Bounds,
sizeof(mlcW.pamxctrl[i].Bounds));
/* sizeof(lpmlcA->pamxctrl[i].Metrics) ==
* sizeof(mlcW.pamxctrl[i].Metrics) */
memcpy(&lpmlcA->pamxctrl[i].Metrics, &mlcW.pamxctrl[i].Metrics,
sizeof(mlcW.pamxctrl[i].Metrics));
}
}
HeapFree(GetProcessHeap(), 0, mlcW.pamxctrl);
return ret;
}
/**************************************************************************
* mixerGetLineControlsW [WINMM.@]
*/
UINT WINAPI mixerGetLineControlsW(HMIXEROBJ hmix, LPMIXERLINECONTROLSW lpmlcW,
DWORD fdwControls)
{
LPWINE_MIXER lpwm;
UINT uRet = MMSYSERR_NOERROR;
TRACE("(%p, %p, %08lx)\n", hmix, lpmlcW, fdwControls);
if ((uRet = MIXER_GetDev(hmix, fdwControls, &lpwm)) != MMSYSERR_NOERROR)
return uRet;
if (lpmlcW == NULL || lpmlcW->cbStruct != sizeof(*lpmlcW))
return MMSYSERR_INVALPARAM;
return MMDRV_Message(&lpwm->mld, MXDM_GETLINECONTROLS, (DWORD_PTR)lpmlcW,
fdwControls, TRUE);
}
/**************************************************************************
* mixerGetLineInfoW [WINMM.@]
*/
UINT WINAPI mixerGetLineInfoW(HMIXEROBJ hmix, LPMIXERLINEW lpmliW, DWORD fdwInfo)
{
LPWINE_MIXER lpwm;
UINT uRet = MMSYSERR_NOERROR;
TRACE("(%p, %p, %08lx)\n", hmix, lpmliW, fdwInfo);
if ((uRet = MIXER_GetDev(hmix, fdwInfo, &lpwm)) != MMSYSERR_NOERROR)
return uRet;
return MMDRV_Message(&lpwm->mld, MXDM_GETLINEINFO, (DWORD_PTR)lpmliW,
fdwInfo, TRUE);
}
/**************************************************************************
* mixerGetLineInfoA [WINMM.@]
*/
UINT WINAPI mixerGetLineInfoA(HMIXEROBJ hmix, LPMIXERLINEA lpmliA,
DWORD fdwInfo)
{
MIXERLINEW mliW;
UINT ret;
TRACE("(%p, %p, %08lx)\n", hmix, lpmliA, fdwInfo);
if (lpmliA == NULL || lpmliA->cbStruct != sizeof(*lpmliA))
return MMSYSERR_INVALPARAM;
mliW.cbStruct = sizeof(mliW);
switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
case MIXER_GETLINEINFOF_COMPONENTTYPE:
mliW.dwComponentType = lpmliA->dwComponentType;
break;
case MIXER_GETLINEINFOF_DESTINATION:
mliW.dwDestination = lpmliA->dwDestination;
break;
case MIXER_GETLINEINFOF_LINEID:
mliW.dwLineID = lpmliA->dwLineID;
break;
case MIXER_GETLINEINFOF_SOURCE:
mliW.dwDestination = lpmliA->dwDestination;
mliW.dwSource = lpmliA->dwSource;
break;
case MIXER_GETLINEINFOF_TARGETTYPE:
mliW.Target.dwType = lpmliA->Target.dwType;
mliW.Target.wMid = lpmliA->Target.wMid;
mliW.Target.wPid = lpmliA->Target.wPid;
mliW.Target.vDriverVersion = lpmliA->Target.vDriverVersion;
MultiByteToWideChar( CP_ACP, 0, lpmliA->Target.szPname, -1, mliW.Target.szPname, sizeof(mliW.Target.szPname));
break;
default:
WARN("Unsupported fdwControls=0x%08lx\n", fdwInfo);
return MMSYSERR_INVALFLAG;
}
ret = mixerGetLineInfoW(hmix, &mliW, fdwInfo);
lpmliA->dwDestination = mliW.dwDestination;
lpmliA->dwSource = mliW.dwSource;
lpmliA->dwLineID = mliW.dwLineID;
lpmliA->fdwLine = mliW.fdwLine;
lpmliA->dwUser = mliW.dwUser;
lpmliA->dwComponentType = mliW.dwComponentType;
lpmliA->cChannels = mliW.cChannels;
lpmliA->cConnections = mliW.cConnections;
lpmliA->cControls = mliW.cControls;
WideCharToMultiByte( CP_ACP, 0, mliW.szShortName, -1, lpmliA->szShortName,
sizeof(lpmliA->szShortName), NULL, NULL);
WideCharToMultiByte( CP_ACP, 0, mliW.szName, -1, lpmliA->szName,
sizeof(lpmliA->szName), NULL, NULL );
lpmliA->Target.dwType = mliW.Target.dwType;
lpmliA->Target.dwDeviceID = mliW.Target.dwDeviceID;
lpmliA->Target.wMid = mliW.Target.wMid;
lpmliA->Target.wPid = mliW.Target.wPid;
lpmliA->Target.vDriverVersion = mliW.Target.vDriverVersion;
WideCharToMultiByte( CP_ACP, 0, mliW.Target.szPname, -1, lpmliA->Target.szPname,
sizeof(lpmliA->Target.szPname), NULL, NULL );
return ret;
}
/**************************************************************************
* mixerSetControlDetails [WINMM.@]
*/
UINT WINAPI mixerSetControlDetails(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcd,
DWORD fdwDetails)
{
LPWINE_MIXER lpwm;
UINT uRet = MMSYSERR_NOERROR;
TRACE("(%p, %p, %08lx)\n", hmix, lpmcd, fdwDetails);
if ((uRet = MIXER_GetDev(hmix, fdwDetails, &lpwm)) != MMSYSERR_NOERROR)
return uRet;
return MMDRV_Message(&lpwm->mld, MXDM_SETCONTROLDETAILS, (DWORD_PTR)lpmcd,
fdwDetails, TRUE);
}
/**************************************************************************
* mixerMessage [WINMM.@]
*/
DWORD WINAPI mixerMessage(HMIXER hmix, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR 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_PTR uDeviceID, LPAUXCAPSW lpCaps, UINT uSize)
{
LPWINE_MLD wmld;
TRACE("(%04X, %p, %d) !\n", uDeviceID, lpCaps, uSize);
if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
return MMSYSERR_INVALHANDLE;
return MMDRV_Message(wmld, AUXDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize, TRUE);
}
/**************************************************************************
* auxGetDevCapsA [WINMM.@]
*/
UINT WINAPI auxGetDevCapsA(UINT_PTR uDeviceID, LPAUXCAPSA lpCaps, UINT uSize)
{
AUXCAPSW acW;
UINT ret;
if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
ret = auxGetDevCapsW(uDeviceID, &acW, sizeof(acW));
if (ret == MMSYSERR_NOERROR) {
AUXCAPSA acA;
acA.wMid = acW.wMid;
acA.wPid = acW.wPid;
acA.vDriverVersion = acW.vDriverVersion;
WideCharToMultiByte( CP_ACP, 0, acW.szPname, -1, acA.szPname,
sizeof(acA.szPname), NULL, NULL );
acA.wTechnology = acW.wTechnology;
acA.dwSupport = acW.dwSupport;
memcpy(lpCaps, &acA, min(uSize, sizeof(acA)));
}
return ret;
}
/**************************************************************************
* auxGetVolume [WINMM.@]
*/
UINT WINAPI auxGetVolume(UINT uDeviceID, DWORD* lpdwVolume)
{
LPWINE_MLD wmld;
TRACE("(%04X, %p) !\n", uDeviceID, lpdwVolume);
if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
return MMSYSERR_INVALHANDLE;
return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD_PTR)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((HANDLE)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
return MMSYSERR_INVALHANDLE;
return MMDRV_Message(wmld, AUXDM_SETVOLUME, dwVolume, 0L, TRUE);
}
/**************************************************************************
* auxOutMessage [WINMM.@]
*/
UINT WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD_PTR dw1, DWORD_PTR dw2)
{
LPWINE_MLD wmld;
if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
return MMSYSERR_INVALHANDLE;
return MMDRV_Message(wmld, uMessage, dw1, dw2, TRUE);
}
/**************************************************************************
* midiOutGetNumDevs [WINMM.@]
*/
UINT WINAPI midiOutGetNumDevs(void)
{
return MMDRV_GetNum(MMDRV_MIDIOUT);
}
/**************************************************************************
* midiOutGetDevCapsW [WINMM.@]
*/
UINT WINAPI midiOutGetDevCapsW(UINT_PTR uDeviceID, LPMIDIOUTCAPSW lpCaps,
UINT uSize)
{
LPWINE_MLD wmld;
TRACE("(%u, %p, %u);\n", uDeviceID, lpCaps, uSize);
if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_MIDIOUT, TRUE)) == NULL)
return MMSYSERR_INVALHANDLE;
return MMDRV_Message(wmld, MODM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize, TRUE);
}
/**************************************************************************
* midiOutGetDevCapsA [WINMM.@]
*/
UINT WINAPI midiOutGetDevCapsA(UINT_PTR uDeviceID, LPMIDIOUTCAPSA lpCaps,
UINT uSize)
{
MIDIOUTCAPSW mocW;
UINT ret;
if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
ret = midiOutGetDevCapsW(uDeviceID, &mocW, sizeof(mocW));
if (ret == MMSYSERR_NOERROR) {
MIDIOUTCAPSA mocA;
mocA.wMid = mocW.wMid;
mocA.wPid = mocW.wPid;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -