/*
 * Core Audio audio policy definitions
 *
 * Copyright 2009 Maarten Lankhorst
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 */

cpp_quote("#ifndef __audiopolicy_h__")
cpp_quote("#define __audiopolicy_h__")

import "oaidl.idl";
import "ocidl.idl";
import "propidl.idl";
import "audiosessiontypes.h";
import "audioclient.idl";

interface IAudioSessionEvents;
interface IAudioSessionControl;
interface IAudioSessionControl2;
interface IAudioSessionManager;
interface IAudioVolumeDuckNotification;
interface IAudioSessionNotification;
interface IAudioSessionEnumerator;
interface IAudioSessionManager2;

typedef enum AudioSessionDisconnectReason /*[local]*/
{
    DisconnectReasonDeviceRemoval = 0,
    DisconnectReasonServerShutdown,
    DisconnectReasonFormatChanged,
    DisconnectReasonSessionLogoff,
    DisconnectReasonSessionDisconnected,
    DisconnectReasonExclusiveModeOverride,
} AudioSessionDisconnectReason;

[
    local,
    uuid(24918acc-64b3-37c1-8ca9-74a66e9957a8),
    pointer_default(unique),
    object
]
interface IAudioSessionEvents : IUnknown
{
    HRESULT OnDisplayNameChanged(
        [string,in] LPCWSTR NewDisplayName,
        [in] LPCGUID EventContext
    );
    HRESULT OnIconPathChanged(
        [string,in] LPCWSTR NewIconPath,
        [in] LPCGUID EventContext
    );
    HRESULT OnSimpleVolumeChanged(
        [in] float NewVolume,
        [in] BOOL NewMute,
        [in] LPCGUID EventContext
    );
    HRESULT OnChannelVolumeChanged(
        [in] DWORD ChannelCount,
        [size_is(ChannelCount),in] float *NewChannelVolumeArray,
        [in] DWORD ChangedChannel,
        [in] LPCGUID EventContext
    );
    HRESULT OnGroupingParamChanged(
        [in] LPCGUID NewGroupingParam,
        [in] LPCGUID EventContext
    );
    HRESULT OnStateChanged(
        [in] AudioSessionState NewState
    );
    HRESULT OnSessionDisconnected(
        [in] AudioSessionDisconnectReason DisconnectReason
    );
}

[
    local,
    uuid(f4b1a599-7266-4319-a8ca-e70acb11e8cd),
    pointer_default(unique),
    object
]
interface IAudioSessionControl : IUnknown
{
    HRESULT GetState(
        [out] AudioSessionState *pRetVal
    );
    HRESULT GetDisplayName(
        [string,out] LPWSTR *pRetVal
    );
    HRESULT SetDisplayName(
        [string,in] LPCWSTR DisplayName,
        [unique,in] LPCGUID EventContext
    );
    HRESULT GetIconPath(
        [string,out] LPWSTR *pRetVal
    );
    HRESULT SetIconPath(
        [string,in] LPCWSTR Value,
        [unique,in] LPCGUID EventContext
    );
    HRESULT GetGroupingParam(
        [out] GUID *pRetVal
    );
    HRESULT SetGroupingParam(
        [in] GUID *Override,
        [unique,in] LPCGUID EventContext
    );
    HRESULT RegisterAudioSessionNotification(
        [in] IAudioSessionEvents *NewNotifications
    );
    HRESULT UnregisterAudioSessionNotification(
        [in] IAudioSessionEvents *NewNotifications
    );
}

[
    local,
    uuid(bfb7ff88-7239-4fc9-8fa2-07c950be9c6d),
    pointer_default(unique),
    object
]
interface IAudioSessionControl2 : IAudioSessionControl
{
    HRESULT GetSessionIdentifier(
        [string,out] LPWSTR *pRetVal
    );
    HRESULT GetSessionInstanceIdentifier(
        [string,out] LPWSTR *pRetVal
    );
    HRESULT GetProcessId(
        [out] DWORD *pRetVal
    );
    HRESULT IsSystemSoundsSession(void);
    HRESULT SetDuckingPreferences(
        [in] BOOL optOut
    );
};

[
    local,
    uuid(bfa971f1-4d5e-40bb-935e-967039bfbee4),
    pointer_default(unique),
    object
]
interface IAudioSessionManager : IUnknown
{
    HRESULT GetAudioSessionControl(
        [in] LPCGUID AudioSessionGuid,
        [in] DWORD StreamFlags,
        [out] IAudioSessionControl **SessionControl
    );
    HRESULT GetSimpleAudioVolume(
        [in] LPCGUID AudioSessionGuid,
        [in] DWORD StreamFlags,
        [out] ISimpleAudioVolume **AudioVolume
    );
};

[
    local,
    uuid(c3b284d4-6d39-4359-b3cf-b56ddb3bb39c),
    pointer_default(unique),
    object
]
interface IAudioVolumeDuckNotification : IUnknown
{
    HRESULT OnVolumeDuckNotification(
        [in] LPCWSTR sessionID,
        [in] UINT32 countCommunicationSessions
    );
    HRESULT OnVolumeUnduckNotification(
        [in] LPCWSTR sessionID
    );
};

[
    local,
    uuid(641dd20b-4d41-49cc-aba3-174b9477bb08),
    pointer_default(unique),
    object
]
interface IAudioSessionNotification : IUnknown
{
    HRESULT OnSessionCreated(
        [in] IAudioSessionControl *NewSession
    );
};

[
    local,
    uuid(e2f5bb11-0570-40ca-acdd-3aa01277dee8),
    pointer_default(unique),
    object
]
interface IAudioSessionEnumerator : IUnknown
{
    HRESULT GetCount(
        [out] INT *SessionCount
    );
    HRESULT GetSession(
        [in] INT SessionCount,
        [out] IAudioSessionControl **Session
    );
};

[
    local,
    uuid(77aa99a0-1bd6-484f-8bc7-2c654c9a9b6f),
    pointer_default(unique),
    object
]
interface IAudioSessionManager2 : IAudioSessionManager
{
    HRESULT GetSessionEnumerator(
        [retval,out] IAudioSessionEnumerator **SessionEnum
    );
    HRESULT RegisterSessionNotification(
        [in] IAudioSessionNotification *SessionNotification
    );
    HRESULT UnregisterSessionNotification(
        [in] IAudioSessionNotification *SessionNotification
    );
    HRESULT RegisterDuckNotification(
        [string,in] LPCWSTR sessionID,
        [in] IAudioVolumeDuckNotification *duckNotification
    );
    HRESULT UnregisterDuckNotification(
        [in] IAudioVolumeDuckNotification *duckNotification
    );
};

cpp_quote("#endif /*__audiopolicy_h__*/")
