diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c b/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c index 397bf994ef2..72e7776ce9d 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c @@ -318,6 +318,53 @@ FreeEventData(IN PVOID EventData) FreeItem(Data); } +VOID +EventCallback( + IN PVOID MixerEventContext, + IN HANDLE hMixer, + IN ULONG NotificationType, + IN ULONG Value) +{ + PWDMAUD_CLIENT ClientInfo; + PEVENT_ENTRY Entry; + ULONG Index; + + /* get client context */ + ClientInfo = (PWDMAUD_CLIENT)MixerEventContext; + + /* now search for the mixer which originated the request */ + for(Index = 0; Index < ClientInfo->NumPins; Index++) + { + if (ClientInfo->hPins[Index].Handle == hMixer && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE) + { + if (ClientInfo->hPins[Index].NotifyEvent) + { + /* allocate event entry */ + Entry = AllocateItem(NonPagedPool, sizeof(EVENT_ENTRY)); + if (!Entry) + { + /* no memory */ + break; + } + + /* setup event entry */ + Entry->NotificationType = NotificationType; + Entry->Value = Value; + Entry->hMixer = hMixer; + + /* insert entry */ + InsertTailList(&ClientInfo->MixerEventList, &Entry->Entry); + + /* now notify the client */ + KeSetEvent(ClientInfo->hPins[Index].NotifyEvent, 0, FALSE); + } + /* done */ + break; + } + } +} + + NTSTATUS WdmAudMixerInitialize( IN PDEVICE_OBJECT DeviceObject) @@ -378,7 +425,7 @@ WdmAudControlOpenMixer( } } - if (MMixerOpen(&MixerContext, DeviceInfo->DeviceIndex, EventObject, NULL /* FIXME */, &hMixer) != MM_STATUS_SUCCESS) + if (MMixerOpen(&MixerContext, DeviceInfo->DeviceIndex, ClientInfo, EventCallback, &hMixer) != MM_STATUS_SUCCESS) { ObDereferenceObject(EventObject); DPRINT1("Failed to open mixer\n"); @@ -511,7 +558,39 @@ WdmAudGetMixerEvent( IN PWDMAUD_DEVICE_INFO DeviceInfo, IN PWDMAUD_CLIENT ClientInfo) { - UNIMPLEMENTED + PLIST_ENTRY Entry; + PEVENT_ENTRY EventEntry; + + /* enumerate event list and check if there is a new event */ + Entry = ClientInfo->MixerEventList.Flink; + + while(Entry != &ClientInfo->MixerEventList) + { + /* grab event entry */ + EventEntry = (PEVENT_ENTRY)CONTAINING_RECORD(Entry, EVENT_ENTRY, Entry); + + if (EventEntry->hMixer == DeviceInfo->hDevice) + { + /* found an entry */ + DeviceInfo->u.MixerEvent.hMixer = EventEntry->hMixer; + DeviceInfo->u.MixerEvent.NotificationType = EventEntry->NotificationType; + DeviceInfo->u.MixerEvent.Value = EventEntry->Value; + + /* remove entry from list */ + RemoveEntryList(&EventEntry->Entry); + + /* free event entry */ + FreeItem(EventEntry); + + /* done */ + return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); + } + + /* move to next */ + Entry = Entry->Flink; + } + + /* no event entry available */ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO)); } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 0258c8e6691..dff0d8f75fb 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -35,6 +35,14 @@ typedef struct LIST_ENTRY MixerEventList; }WDMAUD_CLIENT, *PWDMAUD_CLIENT; +typedef struct +{ + LIST_ENTRY Entry; + ULONG NotificationType; + ULONG Value; + HANDLE hMixer; +}EVENT_ENTRY, *PEVENT_ENTRY; + typedef struct { LIST_ENTRY Entry; diff --git a/reactos/lib/drivers/sound/mmixer/controls.c b/reactos/lib/drivers/sound/mmixer/controls.c index 543fb1e99b6..887066989b2 100644 --- a/reactos/lib/drivers/sound/mmixer/controls.c +++ b/reactos/lib/drivers/sound/mmixer/controls.c @@ -1086,20 +1086,22 @@ MIXER_STATUS MMixerAddEvent( IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, - IN ULONG NodeId) + IN PVOID MixerEventContext, + IN PMIXER_EVENT MixerEventRoutine) { - KSE_NODE Property; - LPEVENT_ITEM EventData; - ULONG BytesReturned; - MIXER_STATUS Status; + //KSE_NODE Property; + PEVENT_NOTIFICATION_ENTRY EventData; + //ULONG BytesReturned; + //MIXER_STATUS Status; - EventData = (LPEVENT_ITEM)MixerContext->AllocEventData(sizeof(LIST_ENTRY)); + EventData = (PEVENT_NOTIFICATION_ENTRY)MixerContext->AllocEventData(sizeof(EVENT_NOTIFICATION_ENTRY)); if (!EventData) { /* not enough memory */ return MM_STATUS_NO_MEMORY; } +#if 0 /* setup request */ Property.Event.Set = KSEVENTSETID_AudioControlChange; Property.Event.Flags = KSEVENT_TYPE_TOPOLOGY|KSEVENT_TYPE_ENABLE; @@ -1115,45 +1117,14 @@ MMixerAddEvent( MixerContext->FreeEventData(EventData); return Status; } +#endif + + /* initialize notification entry */ + EventData->MixerEventContext = MixerEventContext; + EventData->MixerEventRoutine; /* 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: support 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 9b317ce6b75..cd6b0a08a7d 100644 --- a/reactos/lib/drivers/sound/mmixer/mixer.c +++ b/reactos/lib/drivers/sound/mmixer/mixer.c @@ -76,7 +76,7 @@ MIXER_STATUS MMixerOpen( IN PMIXER_CONTEXT MixerContext, IN ULONG MixerId, - IN PVOID MixerEvent, + IN PVOID MixerEventContext, IN PMIXER_EVENT MixerEventRoutine, OUT PHANDLE MixerHandle) { @@ -92,6 +92,7 @@ MMixerOpen( return Status; } + /* get mixer info */ MixerInfo = (LPMIXER_INFO)MMixerGetMixerInfoByIndex(MixerContext, MixerId); if (!MixerInfo) { @@ -99,11 +100,8 @@ MMixerOpen( return MM_STATUS_INVALID_PARAMETER; } - /* FIXME - * handle event notification - */ - - Status = MMixerAddEvents(MixerContext, MixerInfo); + /* add the event */ + Status = MMixerAddEvent(MixerContext, MixerInfo, MixerEventContext, MixerEventRoutine); /* store result */ @@ -396,10 +394,10 @@ MMixerGetControlDetails( switch(MixerControl->dwControlType) { case MIXERCONTROL_CONTROLTYPE_MUTE: - Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo->hMixer, NodeId, MixerLine->Line.dwLineID, MixerControlDetails, FALSE); + Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, NodeId, MixerLine->Line.dwLineID, MixerControlDetails, FALSE); break; case MIXERCONTROL_CONTROLTYPE_VOLUME: - Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo->hMixer, NodeId, FALSE, MixerControl, MixerControlDetails, MixerLine); + Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, FALSE, MixerControl, MixerControlDetails, MixerLine); break; default: Status = MM_STATUS_NOT_IMPLEMENTED; diff --git a/reactos/lib/drivers/sound/mmixer/mmixer.h b/reactos/lib/drivers/sound/mmixer/mmixer.h index 0cfc4acdc07..c7abbb69a52 100644 --- a/reactos/lib/drivers/sound/mmixer/mmixer.h +++ b/reactos/lib/drivers/sound/mmixer/mmixer.h @@ -48,7 +48,10 @@ typedef MIXER_STATUS(*PMIXER_CLOSEKEY)( IN HANDLE hKey); typedef VOID (*PMIXER_EVENT)( - IN PVOID MixerEvent); + IN PVOID MixerEventContext, + IN HANDLE hMixer, + IN ULONG NotificationType, + IN ULONG Value); typedef VOID (*PMIXER_COPY)( IN PVOID Dst, @@ -130,7 +133,7 @@ MIXER_STATUS MMixerOpen( IN PMIXER_CONTEXT MixerContext, IN ULONG MixerId, - IN PVOID MixerEvent, + IN PVOID MixerEventContext, IN PMIXER_EVENT MixerEventRoutine, OUT PHANDLE MixerHandle); diff --git a/reactos/lib/drivers/sound/mmixer/priv.h b/reactos/lib/drivers/sound/mmixer/priv.h index 489bd983bde..1cf339108c9 100644 --- a/reactos/lib/drivers/sound/mmixer/priv.h +++ b/reactos/lib/drivers/sound/mmixer/priv.h @@ -62,13 +62,6 @@ typedef struct }TOPOLOGY, *PTOPOLOGY; - -typedef struct -{ - KSEVENTDATA EventData; - LIST_ENTRY Entry; -}EVENT_ITEM, *LPEVENT_ITEM; - typedef struct { LIST_ENTRY Entry; @@ -141,6 +134,14 @@ typedef struct LIST_ENTRY WaveOutList; }MIXER_LIST, *PMIXER_LIST; +typedef struct +{ + LIST_ENTRY Entry; + PVOID MixerEventContext; + PMIXER_EVENT MixerEventRoutine; + +}EVENT_NOTIFICATION_ENTRY, *PEVENT_NOTIFICATION_ENTRY; + #define DESTINATION_LINE 0xFFFF0000 ULONG @@ -262,7 +263,7 @@ MMixerGetMixerControlById( MIXER_STATUS MMixerSetGetMuteControlDetails( IN PMIXER_CONTEXT MixerContext, - IN HANDLE hMixer, + IN LPMIXER_INFO MixerInfo, IN ULONG NodeId, IN ULONG dwLineID, IN LPMIXERCONTROLDETAILS MixerControlDetails, @@ -271,7 +272,7 @@ MMixerSetGetMuteControlDetails( MIXER_STATUS MMixerSetGetVolumeControlDetails( IN PMIXER_CONTEXT MixerContext, - IN HANDLE hMixer, + IN LPMIXER_INFO MixerInfo, IN ULONG NodeId, IN ULONG bSet, LPMIXERCONTROLW MixerControl, @@ -324,9 +325,11 @@ MMixerInitializeWaveInfo( IN PULONG Pins); MIXER_STATUS -MMixerAddEvents( +MMixerAddEvent( IN PMIXER_CONTEXT MixerContext, - IN OUT LPMIXER_INFO MixerInfo); + IN OUT LPMIXER_INFO MixerInfo, + IN PVOID MixerEvent, + IN PMIXER_EVENT MixerEventRoutine); /* topology.c */ diff --git a/reactos/lib/drivers/sound/mmixer/sup.c b/reactos/lib/drivers/sound/mmixer/sup.c index 90aee6e934f..a557cf97465 100644 --- a/reactos/lib/drivers/sound/mmixer/sup.c +++ b/reactos/lib/drivers/sound/mmixer/sup.c @@ -233,10 +233,38 @@ MMixerGetVolumeControlIndex( return VolumeData->InputSteppingDelta * (VolumeData->ValuesCount-1); } +VOID +MMixerNotifyControlChange( + IN PMIXER_CONTEXT MixerContext, + IN LPMIXER_INFO MixerInfo, + IN ULONG NotificationType, + IN ULONG Value) +{ + PLIST_ENTRY Entry; + PEVENT_NOTIFICATION_ENTRY NotificationEntry; + + /* enumerate list and add a notification entry */ + Entry = MixerInfo->LineList.Flink; + while(Entry != &MixerInfo->EventList) + { + /* get notification entry offset */ + NotificationEntry = (PEVENT_NOTIFICATION_ENTRY)CONTAINING_RECORD(Entry, EVENT_NOTIFICATION_ENTRY, Entry); + + if (NotificationEntry->MixerEventRoutine) + { + /* now perform the callback */ + NotificationEntry->MixerEventRoutine(NotificationEntry->MixerEventContext, (HANDLE)MixerInfo, NotificationType, Value); + } + + /* move to next notification entry */ + Entry = Entry->Flink; + } +} + MIXER_STATUS MMixerSetGetMuteControlDetails( IN PMIXER_CONTEXT MixerContext, - IN HANDLE hMixer, + IN LPMIXER_INFO MixerInfo, IN ULONG NodeId, IN ULONG dwLineID, IN LPMIXERCONTROLDETAILS MixerControlDetails, @@ -257,7 +285,7 @@ MMixerSetGetMuteControlDetails( Value = Input->fValue; /* set control details */ - Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value); + Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value); if (Status != MM_STATUS_SUCCESS) return Status; @@ -270,7 +298,8 @@ MMixerSetGetMuteControlDetails( } else { - /* FIXME notify wdmaud clients MM_MIXM_LINE_CHANGE dwLineID */ + /* notify wdmaud clients MM_MIXM_LINE_CHANGE dwLineID */ + MMixerNotifyControlChange(MixerContext, MixerInfo, MM_MIXM_LINE_CHANGE, dwLineID); } return Status; @@ -279,7 +308,7 @@ MMixerSetGetMuteControlDetails( MIXER_STATUS MMixerSetGetVolumeControlDetails( IN PMIXER_CONTEXT MixerContext, - IN HANDLE hMixer, + IN LPMIXER_INFO MixerInfo, IN ULONG NodeId, IN ULONG bSet, LPMIXERCONTROLW MixerControl, @@ -322,12 +351,12 @@ MMixerSetGetVolumeControlDetails( if (bSet) { /* TODO */ - Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 0, &Value); - Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 1, &Value); + Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 0, &Value); + Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 1, &Value); } else { - Status = MMixerSetGetControlDetails(MixerContext, hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, Channel, &Value); + Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, Channel, &Value); } if (!bSet) @@ -339,6 +368,7 @@ MMixerSetGetVolumeControlDetails( else { /* notify clients of a line change MM_MIXM_CONTROL_CHANGE with MixerControl->dwControlID */ + MMixerNotifyControlChange(MixerContext, MixerInfo, MM_MIXM_CONTROL_CHANGE, MixerControl->dwControlID); } return Status; } @@ -407,8 +437,6 @@ MMixerCreateMixerData( MixerData->hDeviceInterfaceKey = hKey; MixerData->Topology = NULL; - - InsertTailList(&MixerList->MixerData, &MixerData->Entry); MixerList->MixerDataCount++; return MM_STATUS_SUCCESS;