DDraw: Double buffered primary surfaces can only be created in EXLUSIVE mode

Stefan Dösinger stefandoesinger at gmx.at
Sat Sep 9 06:35:50 CDT 2006


My test(included in this patch) shows that DDSCAPS_FLIP capable surfaces can 
only be created when the DDSCL_EXCLUSIVE flag is set. Otherwise 
DDERR_NOEXCLUSIVEMODE is returned, and no surface created.
-------------- next part --------------
From 0047b2c9380610436764d52d5fd8c04bd4b135bc Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Stefan_D=F6singer?= <stefan at codeweavers.com>
Date: Sat, 9 Sep 2006 11:18:35 +0200
Subject: [PATCH] DDraw: DDSCAPS_FLIP surfaces can only be created in DDSCL_EXCLUSIVE mode
---
 dlls/ddraw/ddcomimpl.h        |    2 +-
 dlls/ddraw/ddraw.c            |    8 ++++++++
 dlls/ddraw/tests/ddrawmodes.c |   15 +++++++++++++++
 3 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/dlls/ddraw/ddcomimpl.h b/dlls/ddraw/ddcomimpl.h
index 594d541..553d29f 100644
--- a/dlls/ddraw/ddcomimpl.h
+++ b/dlls/ddraw/ddcomimpl.h
@@ -45,7 +45,7 @@ #define ICOM_THIS_FROM(impltype, ifacena
 
 /* Given an object and interface name, returns a pointer to that interface. */
 #define ICOM_INTERFACE(implobj, iface) \
-	(&((implobj)->ICOM_VFIELD_MULTI_NAME(iface)))
+	(implobj == NULL ? NULL :&((implobj)->ICOM_VFIELD_MULTI_NAME(iface)))
 
 #define ICOM_INIT_INTERFACE(implobj, ifacename, vtblname) \
 	do { \
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 0890ffc..b49ca8f 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -2210,6 +2210,14 @@ IDirectDrawImpl_CreateSurface(IDirectDra
         DDSD->dwFlags &= ~DDSD_LPSURFACE;
     }
 
+    if((DDSD->ddsCaps.dwCaps & (DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE)) == (DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE) &&
+       !(This->cooperative_level & DDSCL_EXCLUSIVE))
+    {
+        TRACE("(%p): Attempt to create a flipable primary surface without DDSCL_EXCLUSIVE set\n", This);
+        *Surf = NULL;
+        return DDERR_NOEXCLUSIVEMODE;
+    }
+
     if (Surf == NULL)
     {
         FIXME("(%p) You want to get back a surface? Don't give NULL ptrs!\n", This);
diff --git a/dlls/ddraw/tests/ddrawmodes.c b/dlls/ddraw/tests/ddrawmodes.c
index 4b2bf17..fd00bb6 100644
--- a/dlls/ddraw/tests/ddrawmodes.c
+++ b/dlls/ddraw/tests/ddrawmodes.c
@@ -222,6 +222,15 @@ static void testdisplaymodes(void)
 static void testcooperativelevels_normal(void)
 {
     HRESULT rc;
+    DDSURFACEDESC surfacedesc;
+    IDirectDrawSurface *surface = (IDirectDrawSurface *) 0xdeadbeef;
+
+    memset(&surfacedesc, 0, sizeof(surfacedesc));
+    surfacedesc.dwSize = sizeof(surfacedesc);
+    surfacedesc.ddpfPixelFormat.dwSize = sizeof(surfacedesc.ddpfPixelFormat);
+    surfacedesc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
+    surfacedesc.dwBackBufferCount = 1;
+    surfacedesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
 
     /* Do some tests with DDSCL_NORMAL mode */
 
@@ -229,6 +238,12 @@ static void testcooperativelevels_normal
         hwnd, DDSCL_NORMAL);
     ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_NORMAL) returned: %lx\n",rc);
 
+    /* Try creating a double buffered primary in normal mode */
+    rc = IDirectDraw_CreateSurface(lpDD, &surfacedesc, &surface, NULL);
+    ok(rc == DDERR_NOEXCLUSIVEMODE, "IDirectDraw_CreateSurface returned %08lx\n", rc);
+    ok(surface == NULL, "Returned surface pointer is %p\n", surface);
+    if(surface) IDirectDrawSurface_Release(surface);
+
     /* Set the focus window */
     rc = IDirectDraw_SetCooperativeLevel(lpDD,
         hwnd, DDSCL_SETFOCUSWINDOW);
-- 
1.4.1.1



More information about the wine-patches mailing list