diff --git a/reactos/lib/drivers/sound/mmixer/controls.c b/reactos/lib/drivers/sound/mmixer/controls.c index 09477edc574..0b2e499f1d8 100644 --- a/reactos/lib/drivers/sound/mmixer/controls.c +++ b/reactos/lib/drivers/sound/mmixer/controls.c @@ -853,6 +853,7 @@ MMixerInitializeFilter( // initialize line list InitializeListHead(&MixerInfo->LineList); + InitializeListHead(&MixerInfo->EventList); // now allocate an array which will receive the indices of the pin // which has a ADC / DAC nodetype in its path @@ -1075,3 +1076,79 @@ MMixerSetupFilter( // done return Status; } + + +MIXER_STATUS +MMixerAddEvent( + IN PMIXER_CONTEXT MixerContext, + IN OUT LPMIXER_INFO MixerInfo, + IN ULONG NodeId) +{ + KSE_NODE Property; + LPEVENT_ITEM EventData; + ULONG BytesReturned; + MIXER_STATUS Status; + + EventData = (LPEVENT_ITEM)MixerContext->AllocEventData(sizeof(LIST_ENTRY)); + if (!EventData) + { + // not enough memory + return MM_STATUS_NO_MEMORY; + } + + /* setup request */ + Property.Event.Set = KSEVENTSETID_AudioControlChange; + Property.Event.Flags = KSEVENT_TYPE_TOPOLOGY|KSEVENT_TYPE_ENABLE; + Property.Event.Id = KSEVENT_CONTROL_CHANGE; + + Property.NodeId = NodeId; + Property.Reserved = 0; + + Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSP_NODE), (PVOID)EventData, sizeof(KSEVENTDATA), &BytesReturned); + if (Status != MM_STATUS_SUCCESS) + { + // failed to add event + MixerContext->FreeEventData(EventData); + return Status; + } + + //store event + InsertTailList(&MixerInfo->EventList, &EventData->Entry); + return Status; +} + +MIXER_STATUS +MMixerAddEvents( + IN PMIXER_CONTEXT MixerContext, + IN OUT LPMIXER_INFO MixerInfo) +{ + PKSMULTIPLE_ITEM NodeTypes; + ULONG Index; + MIXER_STATUS Status; + LPGUID Guid; + + // get filter node types + Status = MMixerGetFilterTopologyProperty(MixerContext, MixerInfo->hMixer, KSPROPERTY_TOPOLOGY_NODES, &NodeTypes); + + if (Status != MM_STATUS_SUCCESS) + { + // failed + return Status; + } + + for(Index = 0; Index < NodeTypes->Count; Index++) + { + Guid = MMixerGetNodeType(NodeTypes, Index); + if (IsEqualGUID(&KSNODETYPE_VOLUME, Guid) || IsEqualGUID(&KSNODETYPE_MUTE, Guid)) + { + //add an event for volume / mute controls + //TODO: extra control types + MMixerAddEvent(MixerContext, MixerInfo, Index); + } + } + + // free node types + MixerContext->Free(NodeTypes); + + return MM_STATUS_SUCCESS; +} diff --git a/reactos/lib/drivers/sound/mmixer/mixer.c b/reactos/lib/drivers/sound/mmixer/mixer.c index d66116ae593..a05f2a77122 100644 --- a/reactos/lib/drivers/sound/mmixer/mixer.c +++ b/reactos/lib/drivers/sound/mmixer/mixer.c @@ -100,6 +100,9 @@ MMixerOpen( // FIXME // handle event notification + Status = MMixerAddEvents(MixerContext, MixerInfo); + + // store result *MixerHandle = (HANDLE)MixerInfo; @@ -163,7 +166,7 @@ MMixerGetLineInfo( return MM_STATUS_INVALID_PARAMETER; } - MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLine->dwSource); + MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLine->dwSource * 0x10000); if (MixerLineSrc) { DPRINT("Line %u Name %S\n", MixerLineSrc->Line.dwSource, MixerLineSrc->Line.szName); @@ -422,7 +425,8 @@ MMixerInitialize( return MM_STATUS_INVALID_PARAMETER; } - if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free || !MixerContext->Open || + if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free || !MixerContext->Open || + !MixerContext->AllocEventData || !MixerContext->FreeEventData || !MixerContext->Close || !MixerContext->OpenKey || !MixerContext->QueryKeyValue || !MixerContext->CloseKey) { // invalid parameter diff --git a/reactos/lib/drivers/sound/mmixer/mmixer.h b/reactos/lib/drivers/sound/mmixer/mmixer.h index d5c0a468526..fa7183da71d 100644 --- a/reactos/lib/drivers/sound/mmixer/mmixer.h +++ b/reactos/lib/drivers/sound/mmixer/mmixer.h @@ -69,6 +69,12 @@ typedef MIXER_STATUS(*PMIXER_OPEN_KEY)( IN ULONG DesiredAccess, OUT PHANDLE OutKey); +typedef PVOID (*PMIXER_ALLOC_EVENT_DATA)( + IN ULONG ExtraBytes); + +typedef VOID (*PMIXER_FREE_EVENT_DATA)( + IN PVOID EventData); + typedef struct { ULONG SizeOfStruct; @@ -83,6 +89,8 @@ typedef struct PMIXER_OPEN_KEY OpenKey; PMIXER_QUERY_KEY_VALUE QueryKeyValue; PMIXER_CLOSEKEY CloseKey; + PMIXER_ALLOC_EVENT_DATA AllocEventData; + PMIXER_FREE_EVENT_DATA FreeEventData; }MIXER_CONTEXT, *PMIXER_CONTEXT; MIXER_STATUS diff --git a/reactos/lib/drivers/sound/mmixer/priv.h b/reactos/lib/drivers/sound/mmixer/priv.h index 0cdbd8ce353..5b582d6fe94 100644 --- a/reactos/lib/drivers/sound/mmixer/priv.h +++ b/reactos/lib/drivers/sound/mmixer/priv.h @@ -15,9 +15,15 @@ #include "mmixer.h" #include - +#define YDEBUG #include +typedef struct +{ + KSEVENTDATA EventData; + LIST_ENTRY Entry; +}EVENT_ITEM, *LPEVENT_ITEM; + typedef struct { LIST_ENTRY Entry; @@ -25,6 +31,7 @@ typedef struct HANDLE hMixer; LIST_ENTRY LineList; ULONG ControlId; + LIST_ENTRY EventList; }MIXER_INFO, *LPMIXER_INFO; typedef struct @@ -268,4 +275,9 @@ MMixerInitializeWaveInfo( IN ULONG bWaveIn, IN ULONG PinId); +MIXER_STATUS +MMixerAddEvents( + IN PMIXER_CONTEXT MixerContext, + IN OUT LPMIXER_INFO MixerInfo); + #endif diff --git a/reactos/lib/drivers/sound/mmixer/sup.c b/reactos/lib/drivers/sound/mmixer/sup.c index 7bb46f3f501..f35d16744e5 100644 --- a/reactos/lib/drivers/sound/mmixer/sup.c +++ b/reactos/lib/drivers/sound/mmixer/sup.c @@ -29,6 +29,7 @@ const GUID KSPROPSETID_Audio = {0x45FFAAA0L, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSEVENTSETID_AudioControlChange = {0xE85E9698L, 0xFA2F, 0x11D1, {0x95, 0xBD, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; MIXER_STATUS MMixerVerifyContext( @@ -37,7 +38,8 @@ MMixerVerifyContext( if (MixerContext->SizeOfStruct != sizeof(MIXER_CONTEXT)) return MM_STATUS_INVALID_PARAMETER; - if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free || !MixerContext->Open || + if (!MixerContext->Alloc || !MixerContext->Control || !MixerContext->Free || !MixerContext->Open || + !MixerContext->AllocEventData || !MixerContext->FreeEventData || !MixerContext->Close || !MixerContext->OpenKey || !MixerContext->QueryKeyValue || !MixerContext->CloseKey) return MM_STATUS_INVALID_PARAMETER; @@ -129,7 +131,7 @@ MMixerGetSourceMixerLineByLineId( while(Entry != &MixerInfo->LineList) { MixerLineSrc = (LPMIXERLINE_EXT)CONTAINING_RECORD(Entry, MIXERLINE_EXT, Entry); - DPRINT("dwLineID %x dwLineID %x\n", MixerLineSrc->Line.dwLineID, dwLineID); + DPRINT("dwLineID %x dwLineID %x MixerLineSrc %p\n", MixerLineSrc->Line.dwLineID, dwLineID, MixerLineSrc); if (MixerLineSrc->Line.dwLineID == dwLineID) return MixerLineSrc;