From 968580c136320619fb6939cff287cac1eb5f7baf Mon Sep 17 00:00:00 2001
From: Marcus Meissner <marcus@jet.franken.de>
Date: Fri, 23 Jun 2000 16:52:53 +0000
Subject: [PATCH] Use correct bpp for the X side of the surface XImages.
 Cleaned up Xlib_Surface_Release so it is a bit more readable. use
 VirtualAlloc for conversion-programside buffer to simplify handling.

---
 dlls/ddraw/ddraw/x11.c     | 16 ++++++-------
 dlls/ddraw/ddraw_private.h |  2 +-
 dlls/ddraw/dsurface/x11.c  | 49 +++++++++++++++-----------------------
 3 files changed, 28 insertions(+), 39 deletions(-)

diff --git a/dlls/ddraw/ddraw/x11.c b/dlls/ddraw/ddraw/x11.c
index 1db62d57849..cc3c4d8f4b5 100644
--- a/dlls/ddraw/ddraw/x11.c
+++ b/dlls/ddraw/ddraw/x11.c
@@ -270,6 +270,7 @@ static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lp
     DDPRIVATE(This);
     void *img_data;
     int bpp = PFGET_BPP(This->d.directdraw_pixelformat);
+    int screen_bpp = PFGET_BPP(This->d.screen_pixelformat);
     
 #ifdef HAVE_LIBXXSHM
     if (ddpriv->xshm_active)
@@ -288,14 +289,15 @@ static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lp
 	);
 
 	if (This->d.pixel_convert != NULL)
-	    img_data = HeapAlloc(
-		GetProcessHeap(),
-		HEAP_ZERO_MEMORY,
+	    img_data = VirtualAlloc(
+		NULL,
 		lpdsf->s.surface_desc.dwWidth *
 		lpdsf->s.surface_desc.dwHeight *
-		bpp
+		screen_bpp,
+		MEM_RESERVE | MEM_COMMIT,
+		PAGE_READWRITE
 	    );
-	else
+        else
 	    img_data = lpdsf->s.surface_desc.u1.lpSurface;
 
 	/* In this case, create an XImage */
@@ -308,13 +310,11 @@ static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lp
 	    lpdsf->s.surface_desc.dwWidth,
 	    lpdsf->s.surface_desc.dwHeight,
 	    32,
-	    lpdsf->s.surface_desc.dwWidth*bpp
+	    lpdsf->s.surface_desc.dwWidth*screen_bpp
 	);
 #ifdef HAVE_LIBXXSHM
     }
 #endif
-    /* assert(bpp*lpdsf->s.surface_desc.dwWidth == img->bytes_per_line); */
-
     if (This->d.pixel_convert != NULL)
 	lpdsf->s.surface_desc.lPitch = bpp*lpdsf->s.surface_desc.dwWidth;
     else
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 593a78fcb97..76faeb41e78 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -361,7 +361,7 @@ extern void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This);
 /* Get DDSCAPS of surface (shortcutmacro) */
 #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
 /* Get the number of bytes per pixel for a given surface */
-#define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8))
+#define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:((pf.u.dwRGBBitCount+7)/8))
 #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
 
 typedef struct {
diff --git a/dlls/ddraw/dsurface/x11.c b/dlls/ddraw/dsurface/x11.c
index b3697645c27..0b4585285d9 100644
--- a/dlls/ddraw/dsurface/x11.c
+++ b/dlls/ddraw/dsurface/x11.c
@@ -337,42 +337,31 @@ ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
 
     IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
 
-    if (dspriv->image != NULL) {
-	if (This->s.ddraw->d.pixel_convert != NULL) {
-	    /* In pixel conversion mode, there are 2 buffers to release. */
-	    VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE);
+    /* This frees the program-side surface. In some cases it had been
+     * allocated with MEM_SYSTEM, so it does not get 'really' freed
+     */
+    VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE);
 
+    /* Now free the XImages and the respective screen-side surfaces */
+    if (dspriv->image != NULL) {
+	if (dspriv->image->data != This->s.surface_desc.u1.lpSurface)
+	    VirtualFree(dspriv->image->data, 0, MEM_RELEASE);
 #ifdef HAVE_LIBXXSHM
-	    if (ddpriv->xshm_active) {
-		TSXShmDetach(display, &(dspriv->shminfo));
-		TSXDestroyImage(dspriv->image);
-		shmdt(dspriv->shminfo.shmaddr);
-	    } else
+	if (ddpriv->xshm_active) {
+	    TSXShmDetach(display, &(dspriv->shminfo));
+	    TSXDestroyImage(dspriv->image);
+	    shmdt(dspriv->shminfo.shmaddr);
+	} else 
 #endif
-	    {
-		HeapFree(GetProcessHeap(),0,dspriv->image->data);
-		dspriv->image->data = NULL;
-		TSXDestroyImage(dspriv->image);
-	    }
-	} else {
+	{
+	    /* normal X Image memory was never allocated by X, but always by 
+	     * ourselves -> Don't let X free our imagedata.
+	     */
 	    dspriv->image->data = NULL;
-
-#ifdef HAVE_LIBXXSHM
-	    if (ddpriv->xshm_active) {
-		VirtualFree(dspriv->image->data, 0, MEM_RELEASE);
-		TSXShmDetach(display, &(dspriv->shminfo));
-		TSXDestroyImage(dspriv->image);
-		shmdt(dspriv->shminfo.shmaddr);
-	    } else
-#endif
-	    {
-		VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE);
-		TSXDestroyImage(dspriv->image);
-	    }
+	    TSXDestroyImage(dspriv->image);
 	}
 	dspriv->image = 0;
-    } else
-	VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE);
+    }
 
     if (This->s.palette)
 	IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
-- 
GitLab