From 9ed19bc61a05d5f92ef29027f1733a3cf739fb37 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 11 Sep 2009 19:01:14 +0200 Subject: [PATCH] dxgi: Implement IDXGIAdapter::EnumOutputs(). Just a single output for each adapter so far, wined3d doesn't do multihead yet. --- dlls/dxgi/Makefile.in | 1 + dlls/dxgi/adapter.c | 32 +++++- dlls/dxgi/dxgi_main.c | 16 ++- dlls/dxgi/dxgi_private.h | 12 ++- dlls/dxgi/output.c | 224 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 280 insertions(+), 5 deletions(-) create mode 100644 dlls/dxgi/output.c diff --git a/dlls/dxgi/Makefile.in b/dlls/dxgi/Makefile.in index f30910dc3e..7ad2ac2681 100644 --- a/dlls/dxgi/Makefile.in +++ b/dlls/dxgi/Makefile.in @@ -11,6 +11,7 @@ C_SRCS = \ device.c \ dxgi_main.c \ factory.c \ + output.c \ surface.c \ swapchain.c \ utils.c diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c index 2bc5fcc8d6..1efbec9e45 100644 --- a/dlls/dxgi/adapter.c +++ b/dlls/dxgi/adapter.c @@ -65,6 +65,7 @@ static ULONG STDMETHODCALLTYPE dxgi_adapter_Release(IWineDXGIAdapter *iface) if (!refcount) { + IDXGIOutput_Release(This->output); HeapFree(GetProcessHeap(), 0, This); } @@ -111,9 +112,22 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetParent(IWineDXGIAdapter *iface, static HRESULT STDMETHODCALLTYPE dxgi_adapter_EnumOutputs(IWineDXGIAdapter *iface, UINT output_idx, IDXGIOutput **output) { - FIXME("iface %p, output_idx %u, output %p stub!\n", iface, output_idx, output); + struct dxgi_adapter *This = (struct dxgi_adapter *)iface; - return E_NOTIMPL; + TRACE("iface %p, output_idx %u, output %p.\n", iface, output_idx, output); + + if (output_idx > 0) + { + *output = NULL; + return DXGI_ERROR_NOT_FOUND; + } + + *output = This->output; + IDXGIOutput_AddRef(*output); + + TRACE("Returning output %p.\n", output); + + return S_OK; } static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc(IWineDXGIAdapter *iface, DXGI_ADAPTER_DESC *desc) @@ -161,10 +175,22 @@ static const struct IWineDXGIAdapterVtbl dxgi_adapter_vtbl = dxgi_adapter_get_ordinal, }; -void dxgi_adapter_init(struct dxgi_adapter *adapter, IDXGIFactory *parent, UINT ordinal) +HRESULT dxgi_adapter_init(struct dxgi_adapter *adapter, IDXGIFactory *parent, UINT ordinal) { + struct dxgi_output *output; + adapter->vtbl = &dxgi_adapter_vtbl; adapter->parent = parent; adapter->refcount = 1; adapter->ordinal = ordinal; + + output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*output)); + if (!output) + { + return E_OUTOFMEMORY; + } + dxgi_output_init(output); + adapter->output = (IDXGIOutput *)output; + + return S_OK; } diff --git a/dlls/dxgi/dxgi_main.c b/dlls/dxgi/dxgi_main.c index 876a85c444..fcc6c07b24 100644 --- a/dlls/dxgi/dxgi_main.c +++ b/dlls/dxgi/dxgi_main.c @@ -129,7 +129,21 @@ HRESULT WINAPI CreateDXGIFactory(REFIID riid, void **factory) goto fail; } - dxgi_adapter_init(adapter, (IDXGIFactory *)object, i); + hr = dxgi_adapter_init(adapter, (IDXGIFactory *)object, i); + if (FAILED(hr)) + { + UINT j; + + ERR("Failed to initialize adapter, hr %#x.\n", hr); + + HeapFree(GetProcessHeap(), 0, adapter); + for (j = 0; j < i; ++j) + { + IDXGIAdapter_Release(object->adapters[j]); + } + goto fail; + } + object->adapters[i] = (IDXGIAdapter *)adapter; } diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h index a5b62b8e6c..a29778c0f0 100644 --- a/dlls/dxgi/dxgi_private.h +++ b/dlls/dxgi/dxgi_private.h @@ -63,6 +63,15 @@ struct dxgi_device IWineDXGIFactory *factory; }; +/* IDXGIOutput */ +struct dxgi_output +{ + const struct IDXGIOutputVtbl *vtbl; + LONG refcount; +}; + +void dxgi_output_init(struct dxgi_output *output); + /* IDXGIAdapter */ struct dxgi_adapter { @@ -70,9 +79,10 @@ struct dxgi_adapter IDXGIFactory *parent; LONG refcount; UINT ordinal; + IDXGIOutput *output; }; -void dxgi_adapter_init(struct dxgi_adapter *adapter, IDXGIFactory *parent, UINT ordinal); +HRESULT dxgi_adapter_init(struct dxgi_adapter *adapter, IDXGIFactory *parent, UINT ordinal); /* IDXGISwapChain */ extern const struct IDXGISwapChainVtbl dxgi_swapchain_vtbl; diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c new file mode 100644 index 0000000000..c3f8289a67 --- /dev/null +++ b/dlls/dxgi/output.c @@ -0,0 +1,224 @@ +/* + * Copyright 2009 Henri Verbeet 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 + */ + +#include "config.h" +#include "wine/port.h" + +#include "dxgi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxgi); + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_QueryInterface(IDXGIOutput *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IDXGIOutput) + || IsEqualGUID(riid, &IID_IDXGIObject) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE dxgi_output_AddRef(IDXGIOutput *iface) +{ + struct dxgi_output *This = (struct dxgi_output *)iface; + ULONG refcount = InterlockedIncrement(&This->refcount); + + TRACE("%p increasing refcount to %u.\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE dxgi_output_Release(IDXGIOutput *iface) +{ + struct dxgi_output *This = (struct dxgi_output *)iface; + ULONG refcount = InterlockedDecrement(&This->refcount); + + TRACE("%p decreasing refcount to %u.\n", This, refcount); + + if (!refcount) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +/* IDXGIObject methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetPrivateData(IDXGIOutput *iface, + REFGUID guid, UINT data_size, const void *data) +{ + FIXME("iface %p, guid %s, data_size %u, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetPrivateDataInterface(IDXGIOutput *iface, + REFGUID guid, const IUnknown *object) +{ + FIXME("iface %p, guid %s, object %p stub!\n", iface, debugstr_guid(guid), object); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetPrivateData(IDXGIOutput *iface, + REFGUID guid, UINT *data_size, void *data) +{ + FIXME("iface %p, guid %s, data_size %p, data %p stub!\n", iface, debugstr_guid(guid), data_size, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetParent(IDXGIOutput *iface, + REFIID riid, void **parent) +{ + FIXME("iface %p, riid %s, parent %p stub!\n", iface, debugstr_guid(riid), parent); + + return E_NOTIMPL; +} + +/* IDXGIOutput methods */ + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetDesc(IDXGIOutput *iface, DXGI_OUTPUT_DESC *desc) +{ + FIXME("iface %p, desc %p stub!\n", iface, desc); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput *iface, + DXGI_FORMAT format, UINT flags, UINT *mode_count, DXGI_MODE_DESC *desc) +{ + FIXME("iface %p, format %s, flags %#x, mode_count %p, desc %p stub!\n", + iface, debug_dxgi_format(format), flags, mode_count, desc); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_FindClosestMatchingMode(IDXGIOutput *iface, + const DXGI_MODE_DESC *mode, DXGI_MODE_DESC *closest_match, IUnknown *device) +{ + FIXME("iface %p, mode %p, closest_match %p, device %p stub!\n", iface, mode, closest_match, device); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_WaitForVBlank(IDXGIOutput *iface) +{ + FIXME("iface %p stub!\n", iface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_TakeOwnership(IDXGIOutput *iface, IUnknown *device, BOOL exclusive) +{ + FIXME("iface %p, device %p, exclusive %d stub!\n", iface, device, exclusive); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE dxgi_output_ReleaseOwnership(IDXGIOutput *iface) +{ + FIXME("iface %p stub!\n", iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControlCapabilities(IDXGIOutput *iface, + DXGI_GAMMA_CONTROL_CAPABILITIES *gamma_caps) +{ + FIXME("iface %p, gamma_caps %p stub!\n", iface, gamma_caps); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetGammaControl(IDXGIOutput *iface, + const DXGI_GAMMA_CONTROL *gamma_control) +{ + FIXME("iface %p, gamma_control %p stub!\n", iface, gamma_control); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetGammaControl(IDXGIOutput *iface, DXGI_GAMMA_CONTROL *gamma_control) +{ + FIXME("iface %p, gamma_control %p stub!\n", iface, gamma_control); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_SetDisplaySurface(IDXGIOutput *iface, IDXGISurface *surface) +{ + FIXME("iface %p, surface %p stub!\n", iface, surface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplaySurfaceData(IDXGIOutput *iface, IDXGISurface *surface) +{ + FIXME("iface %p, surface %p stub!\n", iface, surface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE dxgi_output_GetFrameStatistics(IDXGIOutput *iface, DXGI_FRAME_STATISTICS *stats) +{ + FIXME("iface %p, stats %p stub!\n", iface, stats); + + return E_NOTIMPL; +} + +static const struct IDXGIOutputVtbl dxgi_output_vtbl = +{ + dxgi_output_QueryInterface, + dxgi_output_AddRef, + dxgi_output_Release, + /* IDXGIObject methods */ + dxgi_output_SetPrivateData, + dxgi_output_SetPrivateDataInterface, + dxgi_output_GetPrivateData, + dxgi_output_GetParent, + /* IDXGIOutput methods */ + dxgi_output_GetDesc, + dxgi_output_GetDisplayModeList, + dxgi_output_FindClosestMatchingMode, + dxgi_output_WaitForVBlank, + dxgi_output_TakeOwnership, + dxgi_output_ReleaseOwnership, + dxgi_output_GetGammaControlCapabilities, + dxgi_output_SetGammaControl, + dxgi_output_GetGammaControl, + dxgi_output_SetDisplaySurface, + dxgi_output_GetDisplaySurfaceData, + dxgi_output_GetFrameStatistics, +}; + +void dxgi_output_init(struct dxgi_output *output) +{ + output->vtbl = &dxgi_output_vtbl; + output->refcount = 1; +}