From 52d613dcbeb8d00cf334c0cc46aed7d91eec355e Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 10 Feb 2015 16:34:05 +0100
Subject: dxva2: Implement semi-stub for Direct3DDeviceManager9 interface.

---
 dlls/dxva2/Makefile.in     |   2 +
 dlls/dxva2/devicemanager.c | 212 +++++++++++++++++++++++++++++++++++++++++++++
 dlls/dxva2/dxva2_private.h |  21 +++++
 dlls/dxva2/main.c          |   7 +-
 4 files changed, 240 insertions(+), 2 deletions(-)
 create mode 100644 dlls/dxva2/devicemanager.c
 create mode 100644 dlls/dxva2/dxva2_private.h

diff --git a/dlls/dxva2/Makefile.in b/dlls/dxva2/Makefile.in
index 7b9ef6fe7c0..27c653d3f20 100644
--- a/dlls/dxva2/Makefile.in
+++ b/dlls/dxva2/Makefile.in
@@ -1,4 +1,6 @@
 MODULE = dxva2.dll
+IMPORTS = ole32
 
 C_SRCS = \
+	devicemanager.c \
 	main.c
diff --git a/dlls/dxva2/devicemanager.c b/dlls/dxva2/devicemanager.c
new file mode 100644
index 00000000000..15d78aa7ff0
--- /dev/null
+++ b/dlls/dxva2/devicemanager.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2014 Sebastian Lackner for Pipelight
+ *
+ * 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 <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+
+#include "wine/debug.h"
+
+#define COBJMACROS
+#include "d3d9.h"
+#include "dxva2api.h"
+#include "dxva2_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dxva2);
+
+typedef struct
+{
+    IDirect3DDeviceManager9 IDirect3DDeviceManager9_iface;
+    LONG refCount;
+    UINT token;
+    IDirect3DDevice9 *device;
+} Direct3DDeviceManager9Impl;
+
+static inline Direct3DDeviceManager9Impl *impl_from_Direct3DDeviceManager9( IDirect3DDeviceManager9 *iface )
+{
+    return CONTAINING_RECORD(iface, Direct3DDeviceManager9Impl, IDirect3DDeviceManager9_iface);
+}
+
+/*****************************************************************************
+ * IDirect3DDeviceManager9  interface
+ */
+
+static HRESULT WINAPI Direct3DDeviceManager9_QueryInterface( IDirect3DDeviceManager9 *iface, REFIID riid, LPVOID *ppv )
+{
+    Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+    TRACE("(%p/%p)->(%s, %p)\n", iface, This, debugstr_guid(riid), ppv);
+
+    *ppv = NULL;
+
+    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirect3DDeviceManager9))
+        *ppv = &This->IDirect3DDeviceManager9_iface;
+
+    if (*ppv)
+    {
+        IUnknown_AddRef((IUnknown *)(*ppv));
+        return S_OK;
+    }
+
+    FIXME("No interface for %s\n", debugstr_guid(riid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI Direct3DDeviceManager9_AddRef( IDirect3DDeviceManager9 *iface )
+{
+    Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+    ULONG refCount = InterlockedIncrement(&This->refCount);
+
+    TRACE("(%p)->() AddRef from %d\n", This, refCount - 1);
+
+    return refCount;
+}
+
+static ULONG WINAPI Direct3DDeviceManager9_Release( IDirect3DDeviceManager9 *iface )
+{
+    Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+    ULONG refCount = InterlockedDecrement(&This->refCount);
+
+    TRACE("(%p)->() Release from %d\n", This, refCount + 1);
+
+    if (!refCount)
+    {
+        TRACE("Destroying\n");
+
+        if (This->device)
+            IDirect3DDevice9_Release(This->device);
+
+        CoTaskMemFree(This);
+    }
+
+    return refCount;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_ResetDevice( IDirect3DDeviceManager9 *iface, IDirect3DDevice9 *pDevice, UINT resetToken )
+{
+    Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+    FIXME("(%p)->(%p, %u): semi-stub\n", This, pDevice, resetToken);
+
+    if (This->device)
+        return E_FAIL;
+
+    if (resetToken != This->token)
+        return E_INVALIDARG;
+
+    This->device = pDevice;
+    IDirect3DDevice9_AddRef(This->device);
+
+    /* TODO: Reset the device, verify token ... */
+
+    return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_OpenDeviceHandle( IDirect3DDeviceManager9 *iface, HANDLE *phDevice )
+{
+    Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+    FIXME("(%p)->(%p): semi-stub\n", This, phDevice);
+
+    *phDevice = (HANDLE)This->device;
+    return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_CloseDeviceHandle( IDirect3DDeviceManager9 *iface, HANDLE hDevice )
+{
+    Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+    FIXME("(%p)->(%p): stub\n", This, hDevice);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_TestDevice( IDirect3DDeviceManager9 *iface, HANDLE hDevice )
+{
+    Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+    static int once = 0;
+
+    if (!once++)
+        FIXME("(%p)->(%p): stub\n", This, hDevice);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_LockDevice( IDirect3DDeviceManager9 *iface, HANDLE hDevice, IDirect3DDevice9 **ppDevice, BOOL fBlock )
+{
+    Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+    FIXME("(%p)->(%p, %p, %d): semi-stub\n", This, hDevice, ppDevice, fBlock);
+
+    *ppDevice = (IDirect3DDevice9 *)hDevice;
+    return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_UnlockDevice( IDirect3DDeviceManager9 *iface, HANDLE hDevice, BOOL fSaveState )
+{
+    Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+    FIXME("(%p)->(%p, %d): stub\n", This, hDevice, fSaveState);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI Direct3DDeviceManager9_GetVideoService( IDirect3DDeviceManager9 *iface, HANDLE hDevice, REFIID riid, void **ppService )
+{
+    Direct3DDeviceManager9Impl *This = impl_from_Direct3DDeviceManager9(iface);
+
+    FIXME("(%p)->(%p, %p, %p): stub\n", This, hDevice, riid, ppService);
+
+    return E_NOTIMPL;
+}
+
+static const IDirect3DDeviceManager9Vtbl Direct3DDeviceManager9_VTable =
+{
+    Direct3DDeviceManager9_QueryInterface,
+    Direct3DDeviceManager9_AddRef,
+    Direct3DDeviceManager9_Release,
+    Direct3DDeviceManager9_ResetDevice,
+    Direct3DDeviceManager9_OpenDeviceHandle,
+    Direct3DDeviceManager9_CloseDeviceHandle,
+    Direct3DDeviceManager9_TestDevice,
+    Direct3DDeviceManager9_LockDevice,
+    Direct3DDeviceManager9_UnlockDevice,
+    Direct3DDeviceManager9_GetVideoService
+};
+
+HRESULT devicemanager_create( UINT *resetToken, void **ppv )
+{
+    Direct3DDeviceManager9Impl *devicemanager;
+
+    if (!resetToken || !ppv)
+        return E_INVALIDARG;
+
+    *ppv = NULL;
+
+    devicemanager = CoTaskMemAlloc(sizeof(Direct3DDeviceManager9Impl));
+    if (!devicemanager)
+        return E_OUTOFMEMORY;
+
+    devicemanager->IDirect3DDeviceManager9_iface.lpVtbl = &Direct3DDeviceManager9_VTable;
+    devicemanager->refCount = 1;
+    devicemanager->token    = 0xdeadbeef; /* FIXME: provide some better value? */
+    devicemanager->device   = NULL;
+
+    *resetToken = devicemanager->token;
+    *ppv        = devicemanager;
+    return S_OK;
+}
diff --git a/dlls/dxva2/dxva2_private.h b/dlls/dxva2/dxva2_private.h
new file mode 100644
index 00000000000..d6e59fc6da8
--- /dev/null
+++ b/dlls/dxva2/dxva2_private.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2014 Michael Müller for Pipelight
+ *
+ * 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 "dxva2api.h"
+
+extern HRESULT devicemanager_create( UINT *resetToken, void **ppv ) DECLSPEC_HIDDEN;
diff --git a/dlls/dxva2/main.c b/dlls/dxva2/main.c
index 782f0dfa3d4..df8f2030104 100644
--- a/dlls/dxva2/main.c
+++ b/dlls/dxva2/main.c
@@ -19,8 +19,11 @@
 #include <stdarg.h>
 #include "windef.h"
 #include "winbase.h"
+
+#define INITGUID
 #include "d3d9.h"
 #include "dxva2api.h"
+#include "dxva2_private.h"
 #include "physicalmonitorenumerationapi.h"
 #include "lowlevelmonitorconfigurationapi.h"
 #include "highlevelmonitorconfigurationapi.h"
@@ -39,9 +42,9 @@ BOOL WINAPI CapabilitiesRequestAndCapabilitiesReply( HMONITOR monitor, LPSTR buf
 
 HRESULT WINAPI DXVA2CreateDirect3DDeviceManager9( UINT *resetToken, IDirect3DDeviceManager9 **dxvManager )
 {
-    FIXME("(%p, %p): stub\n", resetToken, dxvManager);
+    TRACE("(%p, %p)\n", resetToken, dxvManager);
 
-    return E_NOTIMPL;
+    return devicemanager_create( resetToken, (void **)dxvManager );
 }
 
 HRESULT WINAPI DXVA2CreateVideoService( IDirect3DDevice9 *device, REFIID riid, void **ppv )
-- 
2.11.0

