Author: janderwald Date: Fri Oct 15 02:24:35 2010 New Revision: 49151
URL: http://svn.reactos.org/svn/reactos?rev=49151&view=rev Log: [WDMAUD_KERNEL] - Implement registering event routine which gets called when a topology node (volume / mute node) changes - Implement fetching event changes [MMIXER] - Implement support routines which get called when a topology node changes its state - Volume changes / mute on/off changes should now be broadcasted again to all listening applications
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h trunk/reactos/lib/drivers/sound/mmixer/controls.c trunk/reactos/lib/drivers/sound/mmixer/mixer.c trunk/reactos/lib/drivers/sound/mmixer/mmixer.h trunk/reactos/lib/drivers/sound/mmixer/priv.h trunk/reactos/lib/drivers/sound/mmixer/sup.c
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wd... ============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mmixer.c [iso-8859-1] Fri Oct 15 02:24:35 2010 @@ -318,6 +318,53 @@ 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 @@ } }
- 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 @@ 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)); }
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wd... ============================================================================== --- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] Fri Oct 15 02:24:35 2010 @@ -38,6 +38,14 @@ typedef struct { LIST_ENTRY Entry; + ULONG NotificationType; + ULONG Value; + HANDLE hMixer; +}EVENT_ENTRY, *PEVENT_ENTRY; + +typedef struct +{ + LIST_ENTRY Entry; UNICODE_STRING SymbolicLink; }SYSAUDIO_ENTRY, *PSYSAUDIO_ENTRY;
Modified: trunk/reactos/lib/drivers/sound/mmixer/controls.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/co... ============================================================================== --- trunk/reactos/lib/drivers/sound/mmixer/controls.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/sound/mmixer/controls.c [iso-8859-1] Fri Oct 15 02:24:35 2010 @@ -1086,20 +1086,22 @@ 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)); + IN PVOID MixerEventContext, + IN PMIXER_EVENT MixerEventRoutine) +{ + //KSE_NODE Property; + PEVENT_NOTIFICATION_ENTRY EventData; + //ULONG BytesReturned; + //MIXER_STATUS Status; + + 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 @@ 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; } +
Modified: trunk/reactos/lib/drivers/sound/mmixer/mixer.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/mi... ============================================================================== --- trunk/reactos/lib/drivers/sound/mmixer/mixer.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/sound/mmixer/mixer.c [iso-8859-1] Fri Oct 15 02:24:35 2010 @@ -76,7 +76,7 @@ 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 @@ return Status; }
+ /* get mixer info */ MixerInfo = (LPMIXER_INFO)MMixerGetMixerInfoByIndex(MixerContext, MixerId); if (!MixerInfo) { @@ -99,11 +100,8 @@ 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 @@ 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;
Modified: trunk/reactos/lib/drivers/sound/mmixer/mmixer.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/mm... ============================================================================== --- trunk/reactos/lib/drivers/sound/mmixer/mmixer.h [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/sound/mmixer/mmixer.h [iso-8859-1] Fri Oct 15 02:24:35 2010 @@ -48,7 +48,10 @@ 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 @@ MMixerOpen( IN PMIXER_CONTEXT MixerContext, IN ULONG MixerId, - IN PVOID MixerEvent, + IN PVOID MixerEventContext, IN PMIXER_EVENT MixerEventRoutine, OUT PHANDLE MixerHandle);
Modified: trunk/reactos/lib/drivers/sound/mmixer/priv.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/pr... ============================================================================== --- trunk/reactos/lib/drivers/sound/mmixer/priv.h [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/sound/mmixer/priv.h [iso-8859-1] Fri Oct 15 02:24:35 2010 @@ -61,13 +61,6 @@ PTOPOLOGY_NODE TopologyNodes;
}TOPOLOGY, *PTOPOLOGY; - - -typedef struct -{ - KSEVENTDATA EventData; - LIST_ENTRY Entry; -}EVENT_ITEM, *LPEVENT_ITEM;
typedef struct { @@ -141,6 +134,14 @@ 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 @@ 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 @@ 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 @@ IN PULONG Pins);
MIXER_STATUS -MMixerAddEvents( - IN PMIXER_CONTEXT MixerContext, - IN OUT LPMIXER_INFO MixerInfo); +MMixerAddEvent( + IN PMIXER_CONTEXT MixerContext, + IN OUT LPMIXER_INFO MixerInfo, + IN PVOID MixerEvent, + IN PMIXER_EVENT MixerEventRoutine);
/* topology.c */
Modified: trunk/reactos/lib/drivers/sound/mmixer/sup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/su... ============================================================================== --- trunk/reactos/lib/drivers/sound/mmixer/sup.c [iso-8859-1] (original) +++ trunk/reactos/lib/drivers/sound/mmixer/sup.c [iso-8859-1] Fri Oct 15 02:24:35 2010 @@ -233,10 +233,38 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ MixerData->hDeviceInterfaceKey = hKey; MixerData->Topology = NULL;
- - InsertTailList(&MixerList->MixerData, &MixerData->Entry); MixerList->MixerDataCount++; return MM_STATUS_SUCCESS;