/*
 * Copyright (C) 2005 Mike McCormack
 *
 * 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
 */

import "oaidl.idl";

typedef struct SENS_QOCINFO
{
    DWORD dwSize;
    DWORD dwFlags;
    DWORD dwOutSpeed;
    DWORD dwInSpeed;
} SENS_QOCINFO, *LPSENS_QOCINFO;

[
  object,
  uuid(d597bab1-5b9f-11d1-8dd2-00aa004abd5e),
  pointer_default(unique)
]
interface ISensNetwork : IDispatch
{
    HRESULT ConnectionMade(
        [in] BSTR bstrConnection,
        [in] ULONG ulType,
        [in] LPSENS_QOCINFO lpQOCInfo );
    HRESULT ConnectionMadeNoQOCInfo(
        [in] BSTR bstrConnection,
        [in] ULONG ulType );
    HRESULT ConnectionLost(
        [in] BSTR bstrConnection,
        [in] ULONG ulType );
    HRESULT DestinationReachable(
        [in] BSTR bstrDestination,
        [in] BSTR bstrConnection,
        [in] ULONG ulType,
        [in] LPSENS_QOCINFO lpQOCInfo );
    HRESULT DestinationReachableNoQOCInfo(
        [in] BSTR bstrDestination,
        [in] BSTR bstrConnection,
        [in] ULONG ulType );
}

[
  object,
  uuid(d597bab2-5b9f-11d1-8dd2-00aa004abd5e),
  pointer_default(unique)
]
interface ISensOnNow : IDispatch
{
    HRESULT OnAcPower( void );
    HRESULT OnBatteryPower(
        [in] DWORD dwBatteryLifePercent );
    HRESULT BatteryLow(
        [in] DWORD dwBatteryLifePercent );
}

[
  object,
  uuid(d597bab3-5b9f-11d1-8dd2-00aa004abd5e),
  pointer_default(unique)
]
interface ISensLogon : IDispatch
{
    HRESULT Logon(
        [in] BSTR bstrUserName );
    HRESULT Logoff(
        [in] BSTR bstrUserName );
    HRESULT StartShell(
        [in] BSTR bstrUserName );
    HRESULT DisplayLock(
        [in] BSTR bstrUserName );
    HRESULT DisplayUnlock(
        [in] BSTR bstrUserName );
    HRESULT StartScreenSaver(
        [in] BSTR bstrUserName );
    HRESULT StopScreenSaver(
        [in] BSTR bstrUserName );
}

[
  object,
  uuid(d597bab4-5b9f-11d1-8dd2-00aa004abd5e),
  pointer_default(unique)
]
interface ISensLogon2 : IDispatch
{
    HRESULT Logon(
        [in] BSTR bstrUserName,
        [in] DWORD dwSessionId );
    HRESULT Logoff(
        [in] BSTR bstrUserName,
        [in] DWORD dwSessionId );
    HRESULT SessionDisconnect(
        [in] BSTR bstrUserName,
        [in] DWORD dwSessionId );
    HRESULT SessionReconnect(
        [in] BSTR bstrUserName,
        [in] DWORD dwSessionId );
    HRESULT PostShell(
        [in] BSTR bstrUserName,
        [in] DWORD dwSessionId );
}
