/*
 * Copyright 2014 Jacek Caban for CodeWeavers
 *
 * 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 "dxgi.idl";

typedef enum _DXGI_OFFER_RESOURCE_PRIORITY {
    DXGI_OFFER_RESOURCE_PRIORITY_LOW = 1,
    DXGI_OFFER_RESOURCE_PRIORITY_NORMAL,
    DXGI_OFFER_RESOURCE_PRIORITY_HIGH
} DXGI_OFFER_RESOURCE_PRIORITY;

typedef enum DXGI_ALPHA_MODE {
    DXGI_ALPHA_MODE_UNSPECIFIED = 0,
    DXGI_ALPHA_MODE_PREMULTIPLIED = 1,
    DXGI_ALPHA_MODE_STRAIGHT = 2,
    DXGI_ALPHA_MODE_IGNORE = 3,
    DXGI_ALPHA_MODE_FORCE_DWORD = 0xffffffff
} DXGI_ALPHA_MODE;

[
    object,
    uuid(05008617-fbfd-4051-a790-144884b4f6a9),
    local,
    pointer_default(unique)
]
interface IDXGIDevice2 : IDXGIDevice1
{
    HRESULT OfferResources(
            [in] UINT NumResources,
            [in, size_is(NumResources)] IDXGIResource *const *ppResources,
            [in] DXGI_OFFER_RESOURCE_PRIORITY Priority);

    HRESULT ReclaimResources(
            [in] UINT NumResources,
            [in, size_is(NumResources)] IDXGIResource *const *ppResources,
            [out, size_is(NumResources)] BOOL *pDiscarded);

    HRESULT EnqueueSetEvent(
            [in] HANDLE hEvent);
}

typedef enum DXGI_SCALING {
    DXGI_SCALING_STRETCH = 0,
    DXGI_SCALING_NONE = 1
} DXGI_SCALING;

typedef struct DXGI_SWAP_CHAIN_DESC1 {
    UINT Width;
    UINT Height;
    DXGI_FORMAT Format;
    BOOL Stereo;
    DXGI_SAMPLE_DESC SampleDesc;
    DXGI_USAGE BufferUsage;
    UINT BufferCount;
    DXGI_SCALING Scaling;
    DXGI_SWAP_EFFECT SwapEffect;
    DXGI_ALPHA_MODE AlphaMode;
    UINT Flags;
} DXGI_SWAP_CHAIN_DESC1;

typedef struct DXGI_SWAP_CHAIN_FULLSCREEN_DESC {
    DXGI_RATIONAL RefreshRate;
    DXGI_MODE_SCANLINE_ORDER ScanlineOrdering;
    DXGI_MODE_SCALING Scaling;
    BOOL Windowed;
} DXGI_SWAP_CHAIN_FULLSCREEN_DESC;

typedef struct DXGI_PRESENT_PARAMETERS {
    UINT DirtyRectsCount;
    RECT *pDirtyRects;
    RECT *pScrollRect;
    POINT *pScrollOffset;
} DXGI_PRESENT_PARAMETERS;

[
    object,
    uuid(790a45f7-0d42-4876-983a-0a55cfe6f4aa),
    local,
    pointer_default(unique)
]
interface IDXGISwapChain1 : IDXGISwapChain
{
    HRESULT GetDesc1(
            [out] DXGI_SWAP_CHAIN_DESC1 *pDesc);

    HRESULT GetFullscreenDesc(
            [out] DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pDesc);

    HRESULT GetHwnd(
            [out] HWND *pHwnd);

    HRESULT GetCoreWindow(
            [in] REFIID refiid,
            [out] void **ppUnk);

    HRESULT Present1(
            [in] UINT SyncInterval,
            [in] UINT PresentFlags,
            [in] const DXGI_PRESENT_PARAMETERS *pPresentParameters);

    BOOL IsTemporaryMonoSupported();

    HRESULT GetRestrictToOutput(
            [out] IDXGIOutput **ppRestrictToOutput);

    HRESULT SetBackgroundColor(
            [in] const DXGI_RGBA *pColor);

    HRESULT GetBackgroundColor(
            [out] DXGI_RGBA *pColor);

    HRESULT SetRotation(
            [in] DXGI_MODE_ROTATION Rotation);

    HRESULT GetRotation(
            [out] DXGI_MODE_ROTATION *pRotation);
}

[
    object,
    uuid(50c83a1c-e072-4c48-87b0-3630fa36a6d0),
    local,
    pointer_default(unique)
]
interface IDXGIFactory2 : IDXGIFactory1
{
    BOOL IsWindowedStereoEnabled();

    HRESULT CreateSwapChainForHwnd(
            [in]  IUnknown *pDevice,
            [in]  HWND hWnd,
            [in]  const DXGI_SWAP_CHAIN_DESC1 *pDesc,
            [in]  const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc,
            [in]  IDXGIOutput *pRestrictToOutput,
            [out] IDXGISwapChain1 **ppSwapChain);

    HRESULT CreateSwapChainForCoreWindow(
            [in]  IUnknown *pDevice,
            [in]  IUnknown *pWindow,
            [in]  const DXGI_SWAP_CHAIN_DESC1 *pDesc,
            [in]  IDXGIOutput *pRestrictToOutput,
            [out] IDXGISwapChain1 **ppSwapChain);

    HRESULT GetSharedResourceAdapterLuid(
            [in]  HANDLE hResource,
            [out] LUID *pLuid);

    HRESULT RegisterOcclusionStatusWindow(
            [in]  HWND WindowHandle,
            [in]  UINT wMsg,
            [out] DWORD *pdwCookie);

    HRESULT RegisterStereoStatusEvent(
            [in]  HANDLE hEvent,
            [out] DWORD *pdwCookie);

    void UnregisterStereoStatus(
            [in]  DWORD dwCookie);

    HRESULT RegisterStereoStatusWindow(
            [in]  HWND WindowHandle,
            [in]  UINT wMsg,
            [out] DWORD *pdwCookie);

    HRESULT RegisterOcclusionStatusEvent(
            [in]  HANDLE hEvent,
            [out] DWORD *pdwCookie);

    void UnregisterOcclusionStatus(
            [in]  DWORD dwCookie);

    HRESULT CreateSwapChainForComposition(
            [in]  IUnknown *pDevice,
            [in]  const DXGI_SWAP_CHAIN_DESC1 *pDesc,
            [in]  IDXGIOutput *pRestrictToOutput,
            [out] IDXGISwapChain1 **ppSwapChain);
}
