/*
 * Copyright 2007 Andras Kovacs
 *
 * 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 "dxgitype.idl";

cpp_quote("#if 0")
typedef HANDLE HMONITOR;
typedef struct _LUID {
    DWORD LowPart;
    LONG HighPart;
} LUID, *PLUID;
cpp_quote("#endif")

typedef UINT DXGI_USAGE;
const DXGI_USAGE DXGI_USAGE_SHADER_INPUT            = 0x10L;
const DXGI_USAGE DXGI_USAGE_RENDER_TARGET_OUTPUT    = 0x20L;
const DXGI_USAGE DXGI_USAGE_BACK_BUFFER             = 0x40L;
const DXGI_USAGE DXGI_USAGE_SHARED                  = 0x80L;
const DXGI_USAGE DXGI_USAGE_READ_ONLY               = 0x100L;

typedef enum DXGI_SWAP_EFFECT {
    DXGI_SWAP_EFFECT_DISCARD    = 0,
    DXGI_SWAP_EFFECT_SEQUENTIAL = 1,
} DXGI_SWAP_EFFECT;

typedef struct DXGI_SURFACE_DESC {
    UINT Width;
    UINT Height;
    DXGI_FORMAT Format;
    DXGI_SAMPLE_DESC SampleDesc;
} DXGI_SURFACE_DESC;

typedef struct DXGI_MAPPED_RECT {
    INT Pitch;
    BYTE *pBits;
} DXGI_MAPPED_RECT;

typedef struct DXGI_OUTPUT_DESC {
    WCHAR DeviceName[32];
    RECT DesktopCoordinates;
    BOOL AttachedToDesktop;
    DXGI_MODE_ROTATION Rotation;
    HMONITOR Monitor;
} DXGI_OUTPUT_DESC;

typedef struct DXGI_FRAME_STATISTICS {
    UINT PresentCount;
    UINT PresentRefreshCount;
    UINT SyncRefreshCount;
    LARGE_INTEGER SyncQPCTime;
    LARGE_INTEGER SyncGPUTime;
} DXGI_FRAME_STATISTICS;

typedef struct DXGI_ADAPTER_DESC {
    WCHAR Description[128];
    UINT VendorId;
    UINT DeviceId;
    UINT SubSysId;
    UINT Revision;
    SIZE_T DedicatedVideoMemory;
    SIZE_T DedicatedSystemMemory;
    SIZE_T SharedSystemMemory;
    LUID AdapterLuid;
} DXGI_ADAPTER_DESC;

typedef struct DXGI_SWAP_CHAIN_DESC {
    DXGI_MODE_DESC BufferDesc;
    DXGI_SAMPLE_DESC SampleDesc;
    DXGI_USAGE BufferUsage;
    UINT BufferCount;
    HWND OutputWindow;
    BOOL Windowed;
    DXGI_SWAP_EFFECT SwapEffect;
    UINT Flags;
} DXGI_SWAP_CHAIN_DESC;

[
    object,
    local,
    uuid(aec22fb8-76f3-4639-9be0-28eb43a67a2e)
]
interface IDXGIObject : IUnknown
{
    HRESULT SetPrivateData(
        [in] REFGUID guid,
        [in] UINT data_size,
        [in] const void *data
    );
    HRESULT SetPrivateDataInterface(
        [in] REFGUID guid,
        [in] const IUnknown *object
    );
    HRESULT GetPrivateData(
        [in] REFGUID guid,
        [in, out] UINT *data_size,
        [out] void *data
    );
    HRESULT GetParent(
        [in] REFIID riid,
        [out] void **parent
    );
}

[
    object,
    local,
    uuid(3d3e0379-f9de-4d58-bb6c-18d62992f1a6)
]
interface IDXGIDeviceSubObject : IDXGIObject
{
    HRESULT GetDevice(
        [in] REFIID riid,
        [out] void **device
    );
}

[
    object,
    local,
    uuid(cafcb56c-6ac3-4889-bf47-9e23bbd260ec)
]
interface IDXGISurface : IDXGIDeviceSubObject
{
    HRESULT GetDesc(
        [out] DXGI_SURFACE_DESC *desc
    );
    HRESULT Map(
        [out] DXGI_MAPPED_RECT *mapped_rect,
        [in] UINT flags
    );
    HRESULT Unmap(
    );
}

[
    object,
    local,
    uuid(ae02eedb-c735-4690-8d52-5a8dc20213aa)
]
interface IDXGIOutput : IDXGIObject
{
    HRESULT GetDesc(
        [out] DXGI_OUTPUT_DESC *desc
    );
    HRESULT GetDisplayModeList(
        [in] DXGI_FORMAT format,
        [in] UINT flags,
        [in, out] UINT *mode_count,
        [out] DXGI_MODE_DESC *desc
    );
    HRESULT FindClosestMatchingMode(
        [in] const DXGI_MODE_DESC *mode,
        [out] DXGI_MODE_DESC *closest_match,
        [in] IUnknown *device
    );
    HRESULT WaitForVBlank(
    );
    HRESULT TakeOwnership(
        [in] IUnknown *device,
        [in] BOOL exclusive
    );
    void ReleaseOwnership(
    );
    HRESULT GetGammaControlCapabilities(
        [out] DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps
    );
    HRESULT SetGammaControl(
        [in] const DXGI_GAMMA_CONTROL *gamma_control
    );
    HRESULT GetGammaControl(
        [out] DXGI_GAMMA_CONTROL *gamma_control
    );
    HRESULT SetDisplaySurface(
        [in] IDXGISurface *surface
    );
    HRESULT GetDisplaySurfaceData(
        [in] IDXGISurface *surface
    );
    HRESULT GetFrameStatistics(
        [out] DXGI_FRAME_STATISTICS *stats
    );
}

[
    object,
    local,
    uuid(2411e7e1-12ac-4ccf-bd14-9798e8534dc0)
]
interface IDXGIAdapter : IDXGIObject
{
    HRESULT EnumOutputs(
        [in] UINT output_idx,
        [in, out] IDXGIOutput **output
    );
    HRESULT GetDesc(
        [out] DXGI_ADAPTER_DESC *desc
    );
    HRESULT CheckInterfaceSupport(
        [in] REFGUID guid,
        [out] LARGE_INTEGER *umd_version
    );
}

[
    object,
    local,
    uuid(310d36a0-d2e7-4c0a-aa04-6a9d23b8886a)
]
interface IDXGISwapChain : IDXGIDeviceSubObject
{
    HRESULT Present(
        [in] UINT sync_interval,
        [in] UINT flags
    );
    HRESULT GetBuffer(
        [in] UINT buffer_idx,
        [in] REFIID riid,
        [in, out] void **surface
    );
    HRESULT SetFullscreenState(
        [in] BOOL fullscreen,
        [in] IDXGIOutput *target
    );
    HRESULT GetFullscreenState(
        [out] BOOL *fullscreen,
        [out] IDXGIOutput **target
    );
    HRESULT GetDesc(
        [out] DXGI_SWAP_CHAIN_DESC *desc
    );
    HRESULT ResizeBuffers(
        [in] UINT buffer_count,
        [in] UINT width,
        [in] UINT height,
        [in] DXGI_FORMAT format,
        [in] UINT flags
    );
    HRESULT ResizeTarget(
        [in] const DXGI_MODE_DESC target_mode_desc
    );
    HRESULT GetContainingOutput(
        [out] IDXGIOutput **output
    );
    HRESULT GetFrameStatistics(
        [out] DXGI_FRAME_STATISTICS *stats
    );
    HRESULT GetLastPresentCount(
        [out] UINT *last_present_count
    );
}

[
    object,
    local,
    uuid(7b7166ec-21c7-44ae-b21a-c9ae321ae369)
]
interface IDXGIFactory : IDXGIObject
{
    HRESULT EnumAdapters(
        [in] UINT adapter_idx,
        [out] IDXGIAdapter **adapter
    );
    HRESULT MakeWindowAssociation(
        [in] HWND window,
        [in] UINT flags
    );
    HRESULT GetWindowAssociation(
        [in] HWND *window
    );
    HRESULT CreateSwapChain(
        [in] IUnknown *device,
        [in] DXGI_SWAP_CHAIN_DESC *desc,
        [out] IDXGISwapChain **swapchain
    );
    HRESULT CreateSoftwareAdapter(
        [in] HMODULE swrast,
        [out] IDXGIAdapter **adapter
    );
}

[local] HRESULT CreateDXGIFactory(REFIID riid, void **factory);
