WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
/* The configured default surface */
-WINED3DSURFTYPE DefaultSurfaceType = SURFACE_OPENGL;
+enum wined3d_surface_type DefaultSurfaceType = WINED3D_SURFACE_TYPE_OPENGL;
static struct list global_ddraw_list = LIST_INIT(global_ddraw_list);
/* value of ForceRefreshRate */
DWORD force_refresh_rate = 0;
+/* Structure for converting DirectDrawEnumerateA to DirectDrawEnumerateExA */
+struct callback_info
+{
+ LPDDENUMCALLBACKA callback;
+ void *context;
+};
+
+/* Enumeration callback for converting DirectDrawEnumerateA to DirectDrawEnumerateExA */
+static HRESULT CALLBACK enum_callback(GUID *guid, char *description, char *driver_name,
+ void *context, HMONITOR monitor)
+{
+ const struct callback_info *info = context;
+
+ return info->callback(guid, description, driver_name, info->context);
+}
+
/* Handle table functions */
BOOL ddraw_handle_table_init(struct ddraw_handle_table *t, UINT initial_size)
{
IUnknown *UnkOuter,
REFIID iid)
{
- WINED3DDEVTYPE devicetype;
- IDirectDrawImpl *This;
+ enum wined3d_device_type device_type;
+ struct ddraw *ddraw;
HRESULT hr;
TRACE("driver_guid %s, ddraw %p, outer_unknown %p, interface_iid %s.\n",
* WineD3D always uses OpenGL for D3D rendering. One could make it request
* indirect rendering
*/
- devicetype = WINED3DDEVTYPE_REF;
+ device_type = WINED3D_DEVICE_TYPE_REF;
}
else if(guid == (GUID *) DDCREATE_HARDWAREONLY)
{
- devicetype = WINED3DDEVTYPE_HAL;
+ device_type = WINED3D_DEVICE_TYPE_HAL;
}
else
{
- devicetype = 0;
+ device_type = 0;
}
/* DDraw doesn't support aggregation, according to msdn */
return CLASS_E_NOAGGREGATION;
/* DirectDraw creation comes here */
- This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl));
- if(!This)
+ ddraw = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ddraw));
+ if (!ddraw)
{
ERR("Out of memory when creating DirectDraw\n");
return E_OUTOFMEMORY;
}
- hr = ddraw_init(This, devicetype);
+ hr = ddraw_init(ddraw, device_type);
if (FAILED(hr))
{
WARN("Failed to initialize ddraw object, hr %#x.\n", hr);
- HeapFree(GetProcessHeap(), 0, This);
+ HeapFree(GetProcessHeap(), 0, ddraw);
return hr;
}
- hr = IDirectDraw7_QueryInterface(&This->IDirectDraw7_iface, iid, DD);
- IDirectDraw7_Release(&This->IDirectDraw7_iface);
- if (SUCCEEDED(hr)) list_add_head(&global_ddraw_list, &This->ddraw_list_entry);
- else WARN("Failed to query interface %s from ddraw object %p.\n", debugstr_guid(iid), This);
+ hr = IDirectDraw7_QueryInterface(&ddraw->IDirectDraw7_iface, iid, DD);
+ IDirectDraw7_Release(&ddraw->IDirectDraw7_iface);
+ if (SUCCEEDED(hr))
+ list_add_head(&global_ddraw_list, &ddraw->ddraw_list_entry);
+ else
+ WARN("Failed to query interface %s from ddraw object %p.\n", debugstr_guid(iid), ddraw);
return hr;
}
* Arguments, return values: See DDRAW_Create
*
***********************************************************************/
-HRESULT WINAPI DECLSPEC_HOTPATCH
-DirectDrawCreate(GUID *GUID,
- LPDIRECTDRAW *DD,
- IUnknown *UnkOuter)
+HRESULT WINAPI DECLSPEC_HOTPATCH DirectDrawCreate(GUID *driver_guid, IDirectDraw **ddraw, IUnknown *outer)
{
HRESULT hr;
- TRACE("driver_guid %s, ddraw %p, outer_unknown %p.\n",
- debugstr_guid(GUID), DD, UnkOuter);
+ TRACE("driver_guid %s, ddraw %p, outer %p.\n",
+ debugstr_guid(driver_guid), ddraw, outer);
wined3d_mutex_lock();
- hr = DDRAW_Create(GUID, (void **) DD, UnkOuter, &IID_IDirectDraw);
+ hr = DDRAW_Create(driver_guid, (void **)ddraw, outer, &IID_IDirectDraw);
wined3d_mutex_unlock();
if (SUCCEEDED(hr))
{
- hr = IDirectDraw_Initialize(*DD, GUID);
- if (FAILED(hr))
- IDirectDraw_Release(*DD);
+ if (FAILED(hr = IDirectDraw_Initialize(*ddraw, driver_guid)))
+ IDirectDraw_Release(*ddraw);
}
return hr;
*
*
***********************************************************************/
-HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACKA Callback, void *Context)
+HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACKA callback, void *context)
{
- TRACE("callback %p, context %p.\n", Callback, Context);
+ struct callback_info info;
- TRACE(" Enumerating default DirectDraw HAL interface\n");
- /* We only have one driver */
- __TRY
- {
- static CHAR driver_desc[] = "DirectDraw HAL",
- driver_name[] = "display";
-
- Callback(NULL, driver_desc, driver_name, Context);
- }
- __EXCEPT_PAGE_FAULT
- {
- return DDERR_INVALIDPARAMS;
- }
- __ENDTRY
+ TRACE("callback %p, context %p.\n", callback, context);
- TRACE(" End of enumeration\n");
- return DD_OK;
+ info.callback = callback;
+ info.context = context;
+ return DirectDrawEnumerateExA(enum_callback, &info, 0x0);
}
/***********************************************************************
* The Flag member is not supported right now.
*
***********************************************************************/
-HRESULT WINAPI DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA Callback, void *Context, DWORD Flags)
+HRESULT WINAPI DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA callback, void *context, DWORD flags)
{
- TRACE("callback %p, context %p, flags %#x.\n", Callback, Context, Flags);
+ struct wined3d *wined3d;
+
+ TRACE("callback %p, context %p, flags %#x.\n", callback, context, flags);
- if (Flags & ~(DDENUM_ATTACHEDSECONDARYDEVICES |
+ if (flags & ~(DDENUM_ATTACHEDSECONDARYDEVICES |
DDENUM_DETACHEDSECONDARYDEVICES |
DDENUM_NONDISPLAYDEVICES))
return DDERR_INVALIDPARAMS;
- if (Flags)
- FIXME("flags 0x%08x not handled\n", Flags);
+ if (flags)
+ FIXME("flags 0x%08x not handled\n", flags);
- TRACE("Enumerating default DirectDraw HAL interface\n");
+ TRACE("Enumerating ddraw interfaces\n");
+ if (!(wined3d = wined3d_create(7, WINED3D_LEGACY_DEPTH_BIAS)))
+ {
+ if (!(wined3d = wined3d_create(7, WINED3D_LEGACY_DEPTH_BIAS | WINED3D_NO3D)))
+ {
+ WARN("Failed to create a wined3d object.\n");
+ return E_FAIL;
+ }
+
+ WARN("Created a wined3d object without 3D support.\n");
+ }
- /* We only have one driver by now */
__TRY
{
+ /* QuickTime expects the description "DirectDraw HAL" */
static CHAR driver_desc[] = "DirectDraw HAL",
driver_name[] = "display";
-
- /* QuickTime expects the description "DirectDraw HAL" */
- Callback(NULL, driver_desc, driver_name, Context, 0);
+ struct wined3d_adapter_identifier adapter_id;
+ HRESULT hr = S_OK;
+ UINT adapter = 0;
+ BOOL cont_enum;
+
+ /* The Battle.net System Checker expects both a NULL device and a GUID-based device */
+ TRACE("Default interface: DirectDraw HAL\n");
+ cont_enum = callback(NULL, driver_desc, driver_name, context, 0);
+ for (adapter = 0; SUCCEEDED(hr) && cont_enum; adapter++)
+ {
+ char DriverName[512] = "";
+
+ /* The Battle.net System Checker expects the GetAdapterIdentifier DeviceName to match the
+ * Driver Name, so obtain the DeviceName and GUID from D3D. */
+ memset(&adapter_id, 0x0, sizeof(adapter_id));
+ adapter_id.device_name = DriverName;
+ adapter_id.device_name_size = sizeof(DriverName);
+ wined3d_mutex_lock();
+ hr = wined3d_get_adapter_identifier(wined3d, adapter, 0x0, &adapter_id);
+ wined3d_mutex_unlock();
+ if (SUCCEEDED(hr))
+ {
+ TRACE("Interface %d: %s\n", adapter, wine_dbgstr_guid(&adapter_id.device_identifier));
+ cont_enum = callback(&adapter_id.device_identifier, driver_desc,
+ adapter_id.device_name, context, 0);
+ }
+ }
}
__EXCEPT_PAGE_FAULT
{
+ wined3d_decref(wined3d);
return DDERR_INVALIDPARAMS;
}
__ENDTRY;
+ wined3d_decref(wined3d);
TRACE("End of enumeration\n");
return DD_OK;
}
{ &CLSID_DirectDrawClipper, CF_CreateDirectDrawClipper }
};
-
-/******************************************************************************
- * DirectDraw ClassFactory implementation
- ******************************************************************************/
-typedef struct
+struct ddraw_class_factory
{
IClassFactory IClassFactory_iface;
LONG ref;
HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID iid, LPVOID *ppObj);
-} IClassFactoryImpl;
+};
-static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
+static inline struct ddraw_class_factory *impl_from_IClassFactory(IClassFactory *iface)
{
- return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
+ return CONTAINING_RECORD(iface, struct ddraw_class_factory, IClassFactory_iface);
}
/*******************************************************************************
* Failure: E_NOINTERFACE
*
*******************************************************************************/
-static HRESULT WINAPI IDirectDrawClassFactoryImpl_QueryInterface(IClassFactory *iface, REFIID riid,
- void **obj)
+static HRESULT WINAPI ddraw_class_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **out)
{
- IClassFactoryImpl *This = impl_from_IClassFactory(iface);
-
- TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj);
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
if (IsEqualGUID(riid, &IID_IUnknown)
|| IsEqualGUID(riid, &IID_IClassFactory))
{
IClassFactory_AddRef(iface);
- *obj = This;
+ *out = iface;
return S_OK;
}
- WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),obj);
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
return E_NOINTERFACE;
}
* The new refcount
*
*******************************************************************************/
-static ULONG WINAPI IDirectDrawClassFactoryImpl_AddRef(IClassFactory *iface)
+static ULONG WINAPI ddraw_class_factory_AddRef(IClassFactory *iface)
{
- IClassFactoryImpl *This = impl_from_IClassFactory(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
+ struct ddraw_class_factory *factory = impl_from_IClassFactory(iface);
+ ULONG ref = InterlockedIncrement(&factory->ref);
- TRACE("%p increasing refcount to %u.\n", This, ref);
+ TRACE("%p increasing refcount to %u.\n", factory, ref);
return ref;
}
* The new refcount
*
*******************************************************************************/
-static ULONG WINAPI IDirectDrawClassFactoryImpl_Release(IClassFactory *iface)
+static ULONG WINAPI ddraw_class_factory_Release(IClassFactory *iface)
{
- IClassFactoryImpl *This = impl_from_IClassFactory(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
+ struct ddraw_class_factory *factory = impl_from_IClassFactory(iface);
+ ULONG ref = InterlockedDecrement(&factory->ref);
- TRACE("%p decreasing refcount to %u.\n", This, ref);
+ TRACE("%p decreasing refcount to %u.\n", factory, ref);
- if (ref == 0)
- HeapFree(GetProcessHeap(), 0, This);
+ if (!ref)
+ HeapFree(GetProcessHeap(), 0, factory);
return ref;
}
* ???
*
*******************************************************************************/
-static HRESULT WINAPI IDirectDrawClassFactoryImpl_CreateInstance(IClassFactory *iface,
- IUnknown *UnkOuter, REFIID riid, void **obj)
+static HRESULT WINAPI ddraw_class_factory_CreateInstance(IClassFactory *iface,
+ IUnknown *outer_unknown, REFIID riid, void **out)
{
- IClassFactoryImpl *This = impl_from_IClassFactory(iface);
+ struct ddraw_class_factory *factory = impl_from_IClassFactory(iface);
- TRACE("iface %p, outer_unknown %p, riid %s, object %p.\n",
- iface, UnkOuter, debugstr_guid(riid), obj);
+ TRACE("iface %p, outer_unknown %p, riid %s, out %p.\n",
+ iface, outer_unknown, debugstr_guid(riid), out);
- return This->pfnCreateInstance(UnkOuter, riid, obj);
+ return factory->pfnCreateInstance(outer_unknown, riid, out);
}
/*******************************************************************************
* S_OK, because it's a stub
*
*******************************************************************************/
-static HRESULT WINAPI IDirectDrawClassFactoryImpl_LockServer(IClassFactory *iface, BOOL dolock)
+static HRESULT WINAPI ddraw_class_factory_LockServer(IClassFactory *iface, BOOL dolock)
{
FIXME("iface %p, dolock %#x stub!\n", iface, dolock);
*******************************************************************************/
static const IClassFactoryVtbl IClassFactory_Vtbl =
{
- IDirectDrawClassFactoryImpl_QueryInterface,
- IDirectDrawClassFactoryImpl_AddRef,
- IDirectDrawClassFactoryImpl_Release,
- IDirectDrawClassFactoryImpl_CreateInstance,
- IDirectDrawClassFactoryImpl_LockServer
+ ddraw_class_factory_QueryInterface,
+ ddraw_class_factory_AddRef,
+ ddraw_class_factory_Release,
+ ddraw_class_factory_CreateInstance,
+ ddraw_class_factory_LockServer
};
/*******************************************************************************
*/
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
+ struct ddraw_class_factory *factory;
unsigned int i;
- IClassFactoryImpl *factory;
TRACE("rclsid %s, riid %s, object %p.\n",
debugstr_guid(rclsid), debugstr_guid(riid), ppv);
DDSURFACEDESC2 *desc,
void *context)
{
- IDirectDrawSurfaceImpl *Impl = impl_from_IDirectDrawSurface7(surf);
+ struct ddraw_surface *Impl = impl_from_IDirectDrawSurface7(surf);
ULONG ref7, ref4, ref3, ref2, ref1, gamma_count, iface_count;
ref7 = IDirectDrawSurface7_Release(surf); /* For the EnumSurfaces */
- IDirectDrawSurface4_AddRef(&Impl->IDirectDrawSurface4_iface);
- ref4 = IDirectDrawSurface4_Release(&Impl->IDirectDrawSurface4_iface);
- IDirectDrawSurface3_AddRef(&Impl->IDirectDrawSurface3_iface);
- ref3 = IDirectDrawSurface3_Release(&Impl->IDirectDrawSurface3_iface);
- IDirectDrawSurface2_AddRef(&Impl->IDirectDrawSurface2_iface);
- ref2 = IDirectDrawSurface2_Release(&Impl->IDirectDrawSurface2_iface);
- IDirectDrawSurface_AddRef(&Impl->IDirectDrawSurface_iface);
- ref1 = IDirectDrawSurface_Release(&Impl->IDirectDrawSurface_iface);
- IDirectDrawGammaControl_AddRef(&Impl->IDirectDrawGammaControl_iface);
- gamma_count = IDirectDrawGammaControl_Release(&Impl->IDirectDrawGammaControl_iface);
+ ref4 = Impl->ref4;
+ ref3 = Impl->ref3;
+ ref2 = Impl->ref2;
+ ref1 = Impl->ref1;
+ gamma_count = Impl->gamma_count;
+
WARN("Surface %p has an reference counts of 7: %u 4: %u 3: %u 2: %u 1: %u gamma: %u\n",
Impl, ref7, ref4, ref3, ref2, ref1, gamma_count);
TRACE("(%p,%x,%p)\n", hInstDLL, Reason, lpv);
if (Reason == DLL_PROCESS_ATTACH)
{
+ static HMODULE ddraw_self;
char buffer[MAX_PATH+10];
DWORD size = sizeof(buffer);
HKEY hkey = 0;
if (!strcmp(buffer,"gdi"))
{
TRACE("Defaulting to GDI surfaces\n");
- DefaultSurfaceType = SURFACE_GDI;
+ DefaultSurfaceType = WINED3D_SURFACE_TYPE_GDI;
}
else if (!strcmp(buffer,"opengl"))
{
TRACE("Defaulting to opengl surfaces\n");
- DefaultSurfaceType = SURFACE_OPENGL;
+ DefaultSurfaceType = WINED3D_SURFACE_TYPE_OPENGL;
}
else
{
RegCloseKey( hkey );
}
+ /* Prevent the ddraw module from being unloaded. When switching to
+ * exclusive mode, we replace the window proc of the ddraw window. If
+ * an application would unload ddraw from the WM_DESTROY handler for
+ * that window, it would return to unmapped memory and die. Apparently
+ * this is supposed to work on Windows. We should probably use
+ * GET_MODULE_HANDLE_EX_FLAG_PIN for this, but that's not currently
+ * implemented. */
+ if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const WCHAR *)&ddraw_self, &ddraw_self))
+ ERR("Failed to get own module handle.\n");
+
instance = hInstDLL;
DisableThreadLibraryCalls(hInstDLL);
}
/* We remove elements from this loop */
LIST_FOR_EACH_SAFE(entry, entry2, &global_ddraw_list)
{
+ struct ddraw *ddraw = LIST_ENTRY(entry, struct ddraw, ddraw_list_entry);
HRESULT hr;
DDSURFACEDESC2 desc;
int i;
- IDirectDrawImpl *ddraw = LIST_ENTRY(entry, IDirectDrawImpl, ddraw_list_entry);
WARN("DDraw %p has a refcount of %d\n", ddraw, ddraw->ref7 + ddraw->ref4 + ddraw->ref3 + ddraw->ref2 + ddraw->ref1);
IDirectDraw4_AddRef(&ddraw->IDirectDraw4_iface);
IDirectDraw7_AddRef(&ddraw->IDirectDraw7_iface);
- if (ddraw->wined3d_swapchain)
- ddraw_destroy_swapchain(ddraw);
-
/* Does a D3D device exist? Destroy it
* TODO: Destroy all Vertex buffers, Lights, Materials
* and execute buffers too
while(IDirect3DDevice7_Release(&ddraw->d3ddevice->IDirect3DDevice7_iface));
}
+ /* Destroy the swapchain after any 3D device. The 3D device
+ * cleanup code needs a swapchain. Specifically, it tries to
+ * set the current render target to the front buffer. */
+ if (ddraw->wined3d_swapchain)
+ ddraw_destroy_swapchain(ddraw);
+
/* Try to release the objects
* Do an EnumSurfaces to find any hanging surfaces
*/