- added definition of DirectDrawCreateClipper.
- more versatile support of surfaces / better surface description support.
diff --git a/graphics/ddraw.c b/graphics/ddraw.c
index 3a9d787..1969b44 100644
--- a/graphics/ddraw.c
+++ b/graphics/ddraw.c
@@ -282,6 +282,42 @@
DUMP("\n");
}
+static void _dump_DDCOLORKEY(DWORD flagmask) {
+ int i;
+ const struct {
+ DWORD mask;
+ char *name;
+ } flags[] = {
+#define FE(x) { x, #x},
+ FE(DDPF_ALPHAPIXELS)
+ FE(DDPF_ALPHA)
+ FE(DDPF_FOURCC)
+ FE(DDPF_PALETTEINDEXED4)
+ FE(DDPF_PALETTEINDEXEDTO8)
+ FE(DDPF_PALETTEINDEXED8)
+ FE(DDPF_RGB)
+ FE(DDPF_COMPRESSED)
+ FE(DDPF_RGBTOYUV)
+ FE(DDPF_YUV)
+ FE(DDPF_ZBUFFER)
+ FE(DDPF_PALETTEINDEXED1)
+ FE(DDPF_PALETTEINDEXED2)
+ FE(DDPF_ZPIXELS)
+ };
+ for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+ if (flags[i].mask & flagmask)
+ DUMP("%s ",flags[i].name);
+ DUMP("\n");
+}
+
+static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
+ _dump_DDCOLORKEY(pf->dwFlags);
+ DUMP("dwFourCC : %ld\n", pf->dwFourCC);
+ DUMP("RBG bit cbout : %ld\n", pf->x.dwRGBBitCount);
+ DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
+ pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
+}
+
static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
static XVisualInfo *vi;
XVisualInfo vt;
@@ -329,22 +365,20 @@
WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
this,lprect,lpddsd,flags,(DWORD)hnd);
+ /* First, copy the Surface description */
+ *lpddsd = this->s.surface_desc;
+
+ /* If asked only for a part, change the surface pointer */
if (lprect) {
FIXME(ddraw," lprect: %dx%d-%dx%d\n",
lprect->top,lprect->left,lprect->bottom,lprect->right
);
- lpddsd->y.lpSurface = this->s.surface +
- (lprect->top*this->s.lpitch) +
- (lprect->left*(this->s.ddraw->d.depth/8));
+ lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
+ (lprect->top*this->s.surface_desc.lPitch) +
+ (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
} else {
- assert(this->s.surface);
- lpddsd->y.lpSurface = this->s.surface;
+ assert(this->s.surface_desc.y.lpSurface);
}
- lpddsd->dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_LPSURFACE;
- lpddsd->dwWidth = this->s.width;
- lpddsd->dwHeight = this->s.height;
- lpddsd->lPitch = this->s.lpitch;
- _getpixelformat(this->s.ddraw,&(lpddsd->ddpfPixelFormat));
return 0;
}
@@ -364,7 +398,8 @@
return DD_OK;
/* Only redraw the screen when unlocking the buffer that is on screen */
- if ((this->t.xlib.image != NULL) && (this->t.xlib.on_screen)) {
+ if ((this->t.xlib.image != NULL) &&
+ (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
#ifdef HAVE_LIBXXSHM
if (this->s.ddraw->e.xlib.xshm_active)
TSXShmPutImage(display,
@@ -384,10 +419,10 @@
0, 0, 0, 0,
this->t.xlib.image->width,
this->t.xlib.image->height);
- }
if (this->s.palette && this->s.palette->cm)
TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
+ }
return DD_OK;
}
@@ -418,9 +453,9 @@
this->t.dga.fb_height = flipto->t.dga.fb_height;
flipto->t.dga.fb_height = tmp;
- ptmp = this->s.surface;
- this->s.surface = flipto->s.surface;
- flipto->s.surface = ptmp;
+ ptmp = this->s.surface_desc.y.lpSurface;
+ this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
+ flipto->s.surface_desc.y.lpSurface = ptmp;
}
return 0;
#else /* defined(HAVE_LIBXXF86DGA) */
@@ -471,9 +506,9 @@
tmp = this->t.xlib.image;
this->t.xlib.image = flipto->t.xlib.image;
flipto->t.xlib.image = tmp;
- surf = this->s.surface;
- this->s.surface = flipto->s.surface;
- flipto->s.surface = surf;
+ surf = this->s.surface_desc.y.lpSurface;
+ this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
+ flipto->s.surface_desc.y.lpSurface = surf;
}
return 0;
}
@@ -552,11 +587,17 @@
LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
) {
RECT32 xdst,xsrc;
+ DDSURFACEDESC ddesc,sdesc;
int i,j;
- if (TRACE_ON(ddraw)) {
TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
this,rdst,src,rsrc,dwFlags,lpbltfx);
+
+ if (src != NULL)
+ src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
+ this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
+
+ if (TRACE_ON(ddraw)) {
if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
@@ -569,9 +610,9 @@
memcpy(&xdst,rdst,sizeof(xdst));
} else {
xdst.top = 0;
- xdst.bottom = this->s.height;
+ xdst.bottom = ddesc.dwHeight;
xdst.left = 0;
- xdst.right = this->s.width;
+ xdst.right = ddesc.dwWidth;
}
if (rsrc) {
@@ -579,9 +620,9 @@
} else {
if (src) {
xsrc.top = 0;
- xsrc.bottom = src->s.height;
+ xsrc.bottom = sdesc.dwHeight;
xsrc.left = 0;
- xsrc.right = src->s.width;
+ xsrc.right = sdesc.dwWidth;
} else {
memset(&xsrc,0,sizeof(xsrc));
}
@@ -590,10 +631,10 @@
dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
if (dwFlags & DDBLT_COLORFILL) {
- int bpp = this->s.ddraw->d.depth/8;
+ int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
LPBYTE xline,xpixel;
- xline = (LPBYTE)this->s.surface+xdst.top*this->s.lpitch;
+ xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
for (i=xdst.top;i<xdst.bottom;i++) {
xpixel = xline+bpp*xdst.left;
@@ -605,7 +646,7 @@
memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
xpixel += bpp;
}
- xline += this->s.lpitch;
+ xline += ddesc.lPitch;
}
dwFlags &= ~(DDBLT_COLORFILL);
}
@@ -617,22 +658,24 @@
return 0;
}
- if ( (xsrc.top ==0) && (xsrc.bottom ==this->s.height) &&
- (xsrc.left==0) && (xsrc.right ==this->s.width) &&
- (xdst.top ==0) && (xdst.bottom ==this->s.height) &&
- (xdst.left==0) && (xdst.right ==this->s.width) &&
+ if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
+ (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
+ (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
+ (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
!dwFlags
) {
- memcpy(this->s.surface,src->s.surface,this->s.height*this->s.lpitch);
+ memcpy(ddesc.y.lpSurface,
+ sdesc.y.lpSurface,
+ ddesc.dwHeight * ddesc.lPitch);
} else {
- int bpp = this->s.ddraw->d.depth / 8;
+ int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
int height = xsrc.bottom - xsrc.top;
int width = (xsrc.right - xsrc.left) * bpp;
int h;
for (h = 0; h < height; h++) {
- memcpy(this->s.surface + ((h + xdst.top) * this->s.lpitch) + xdst.left * bpp,
- src->s.surface + ((h + xsrc.top) * src->s.lpitch) + xsrc.left * bpp,
+ memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
+ sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
width);
}
}
@@ -640,48 +683,13 @@
if (dwFlags && FIXME_ON(ddraw)) {
FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
}
+
+ this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
+ src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
+
return 0;
}
-static HRESULT WINAPI Xlib_IDirectDrawSurface3_Blt(
- LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
-) {
- HRESULT ret;
-
- /* First, call the "common" blit function */
- ret = IDirectDrawSurface3_Blt(this, rdst, src, rsrc, dwFlags, lpbltfx);
-
- /* Then put the result on screen if blited on main screen buffer */
- if (!this->s.ddraw->e.xlib.paintable)
- return ret;
-
- if ((this->t.xlib.image != NULL) && (this->t.xlib.on_screen)) {
-#ifdef HAVE_LIBXXSHM
- if (this->s.ddraw->e.xlib.xshm_active)
- TSXShmPutImage(display,
- this->s.ddraw->e.xlib.drawable,
- DefaultGCOfScreen(screen),
- this->t.xlib.image,
- 0, 0, 0, 0,
- this->t.xlib.image->width,
- this->t.xlib.image->height,
- False);
- else
-#endif
- TSXPutImage(display,
- this->s.ddraw->e.xlib.drawable,
- DefaultGCOfScreen(screen),
- this->t.xlib.image,
- 0, 0, 0, 0,
- this->t.xlib.image->width,
- this->t.xlib.image->height);
- }
- if (this->s.palette && this->s.palette->cm)
- TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
-
- return ret;
-}
-
static HRESULT WINAPI IDirectDrawSurface3_BltFast(
LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
) {
@@ -698,7 +706,7 @@
/* We need to lock the surfaces, or we won't get refreshes when done */
src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
- bpp = this->s.ddraw->d.depth/8;
+ bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
for (i=0;i<rsrc->bottom-rsrc->top;i++) {
memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
@@ -730,24 +738,22 @@
static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
) {
- if (TRACE_ON(ddraw)) {
TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
this,ddsd);
+
+ /* Simply copy the surface description stored in the object */
+ *ddsd = this->s.surface_desc;
+
+ if (TRACE_ON(ddraw)) {
fprintf(stderr," flags: ");
_dump_DDSD(ddsd->dwFlags);
+ if (ddsd->dwFlags & DDSD_CAPS) {
+ fprintf(stderr, " caps: ");
+ _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
+ }
fprintf(stderr,"\n");
}
- ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
- ddsd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
- ddsd->dwBackBufferCount = 1;
- ddsd->dwHeight = this->s.height;
- ddsd->dwWidth = this->s.width;
- ddsd->lPitch = this->s.lpitch;
- if (this->s.backbuffer)
- ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
- _getpixelformat(this->s.ddraw,&(ddsd->ddpfPixelFormat));
-
return 0;
}
@@ -765,7 +771,7 @@
this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
/* clear out of surface list */
if (this->t.dga.fb_height == -1) {
- HeapFree(GetProcessHeap(),0,this->s.surface);
+ HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
} else {
this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
}
@@ -795,7 +801,7 @@
shmdt(this->t.xlib.shminfo.shmaddr);
} else {
#endif
- HeapFree(GetProcessHeap(),0,this->s.surface);
+ HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
TSXDestroyImage(this->t.xlib.image);
#ifdef HAVE_LIBXXSHM
}
@@ -803,7 +809,7 @@
this->t.xlib.image = 0;
} else {
- HeapFree(GetProcessHeap(),0,this->s.surface);
+ HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
}
if (this->s.palette)
@@ -844,6 +850,8 @@
static HRESULT WINAPI IDirectDrawSurface3_Initialize(
LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
) {
+ TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
+
return DDERR_ALREADYINITIALIZED;
}
@@ -851,7 +859,10 @@
LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
) {
TRACE(ddraw,"(%p)->(%p)\n",this,pf);
- return _getpixelformat(this->s.ddraw,pf);
+
+ *pf = this->s.surface_desc.ddpfPixelFormat;
+
+ return 0;
}
static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
@@ -877,6 +888,9 @@
LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
) {
FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
+
+ /* This hack will be enough for the moment */
+ if (this->s.backbuffer == NULL)
this->s.backbuffer = surf;
return 0;
}
@@ -1140,7 +1154,7 @@
Xlib_IDirectDrawSurface3_Release,
IDirectDrawSurface3_AddAttachedSurface,
IDirectDrawSurface3_AddOverlayDirtyRect,
- Xlib_IDirectDrawSurface3_Blt,
+ IDirectDrawSurface3_Blt,
IDirectDrawSurface3_BltBatch,
IDirectDrawSurface3_BltFast,
IDirectDrawSurface3_DeleteAttachedSurface,
@@ -1177,6 +1191,21 @@
IDirectDrawSurface3_SetSurfaceDesc,
};
+/******************************************************************************
+ * DirectDrawCreateClipper (DDRAW.7)
+ */
+HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
+ LPDIRECTDRAWCLIPPER *lplpDDClipper,
+ LPUNKNOWN pUnkOuter)
+{
+ TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
+
+ *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
+ (*lplpDDClipper)->lpvtbl = &ddclipvt;
+ (*lplpDDClipper)->ref = 1;
+
+ return 0;
+}
/******************************************************************************
* IDirectDrawClipper
@@ -1233,6 +1262,9 @@
) {
int i;
+ TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
+ this,x,start,count,palent);
+
if (!this->cm) /* should not happen */ {
FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
return DDERR_GENERIC;
@@ -1342,6 +1374,8 @@
static HRESULT WINAPI IDirectDrawPalette_Initialize(
LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
) {
+ TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
+
return DDERR_ALREADYINITIALIZED;
}
@@ -1383,6 +1417,9 @@
Xlib_IDirectDrawPalette_SetEntries
};
+/*******************************************************************************
+ * IDirect3D
+ */
static HRESULT WINAPI IDirect3D_QueryInterface(
LPDIRECT3D this,REFIID refiid,LPVOID *obj
) {
@@ -1519,6 +1556,38 @@
*/
static INT32 ddrawXlibThisOffset = 0;
+static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
+ LPDDSURFACEDESC lpddsd,
+ LPDIRECTDRAWSURFACE lpdsf)
+{
+ int bpp;
+
+ /* The surface was already allocated when entering in this function */
+ if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
+ /* No pixel format => use DirectDraw's format */
+ _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
+ lpddsd->dwFlags |= DDSD_PIXELFORMAT;
+ } else {
+ /* To check what the program wants */
+ if (TRACE_ON(ddraw)) {
+ _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
+ }
+ }
+
+ bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
+
+ /* Copy the surface description */
+ lpdsf->s.surface_desc = *lpddsd;
+
+ lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
+ lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
+ lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
+
+ TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
+
+ return 0;
+}
+
static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
) {
@@ -1538,42 +1607,52 @@
this->lpvtbl->fnAddRef(this);
(*lpdsf)->ref = 1;
(*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
- if ( (lpddsd->dwFlags & DDSD_CAPS) &&
- (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
- ) {
+ (*lpdsf)->s.ddraw = this;
+ (*lpdsf)->s.palette = NULL;
+ (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
+
if (!(lpddsd->dwFlags & DDSD_WIDTH))
- lpddsd->dwWidth = this->e.dga.fb_width;
+ lpddsd->dwWidth = this->d.width;
if (!(lpddsd->dwFlags & DDSD_HEIGHT))
- lpddsd->dwHeight = this->e.dga.fb_height;
- (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
- (*lpdsf)->t.dga.fb_height = -1;
- (*lpdsf)->s.lpitch = lpddsd->dwWidth*this->d.depth/8;
- TRACE(ddraw,"using system memory for a primary surface\n");
- } else {
+ lpddsd->dwHeight = this->d.height;
+
+ /* Check if this a 'primary surface' or not */
+ if ((lpddsd->dwFlags & DDSD_CAPS) &&
+ (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
+
+ /* This is THE primary surface => there is DGA-specific code */
+ /* First, store the surface description */
+ (*lpdsf)->s.surface_desc = *lpddsd;
+
+ /* Find a viewport */
for (i=0;i<32;i++)
if (!(this->e.dga.vpmask & (1<<i)))
break;
TRACE(ddraw,"using viewport %d for a primary surface\n",i);
/* if i == 32 or maximum ... return error */
this->e.dga.vpmask|=(1<<i);
- (*lpdsf)->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
+ (*lpdsf)->s.surface_desc.y.lpSurface =
+ this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
(*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
- (*lpdsf)->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
- }
+ (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
+ lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
- lpddsd->lPitch = (*lpdsf)->s.lpitch;
-
- (*lpdsf)->s.width = this->d.width;
- (*lpdsf)->s.height = this->d.height;
- (*lpdsf)->s.ddraw = this;
+ /* Add flags if there were not present */
+ (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
+ (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
+ (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
+ (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
+ _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
(*lpdsf)->s.backbuffer = NULL;
+
if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
LPDIRECTDRAWSURFACE3 back;
if (lpddsd->dwBackBufferCount>1)
FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
- (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
+ (*lpdsf)->s.backbuffer = back =
+ (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
this->lpvtbl->fnAddRef(this);
back->ref = 1;
back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
@@ -1583,16 +1662,29 @@
TRACE(ddraw,"using viewport %d for backbuffer\n",i);
/* if i == 32 or maximum ... return error */
this->e.dga.vpmask|=(1<<i);
- back->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
back->t.dga.fb_height = i*this->e.dga.fb_height;
- back->s.width = this->d.width;
- back->s.height = this->d.height;
+ /* Copy the surface description from the front buffer */
+ back->s.surface_desc = (*lpdsf)->s.surface_desc;
+ /* Change the parameters that are not the same */
+ back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
+ ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
back->s.ddraw = this;
- back->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
back->s.backbuffer = NULL; /* does not have a backbuffer, it is
* one! */
+
+ /* Add relevant info to front and back buffers */
+ (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
+ back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
+ back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
+ back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
+ }
+ } else {
+ /* There is no DGA-specific code here...
+ Go to the common surface creation function */
+ return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
}
+
return 0;
#else /* defined(HAVE_LIBXXF86DGA) */
return E_UNEXPECTED;
@@ -1610,8 +1702,8 @@
ZPixmap,
NULL,
&(lpdsf->t.xlib.shminfo),
- lpdsf->s.width,
- lpdsf->s.height);
+ lpdsf->s.surface_desc.dwWidth,
+ lpdsf->s.surface_desc.dwHeight);
if (img == NULL)
return NULL;
@@ -1636,11 +1728,14 @@
shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
- lpdsf->s.surface = img->data;
+ lpdsf->s.surface_desc.y.lpSurface = img->data;
} else {
#endif
/* Allocate surface memory */
- lpdsf->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpdsf->s.width * lpdsf->s.height *this->d.depth/8);
+ lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
+ lpdsf->s.surface_desc.dwWidth *
+ lpdsf->s.surface_desc.dwHeight *
+ (this->d.depth / 8));
/* In this case, create an XImage */
img =
@@ -1649,17 +1744,17 @@
this->d.depth,
ZPixmap,
0,
- lpdsf->s.surface,
- lpdsf->s.width,
- lpdsf->s.height,
+ lpdsf->s.surface_desc.y.lpSurface,
+ lpdsf->s.surface_desc.dwWidth,
+ lpdsf->s.surface_desc.dwHeight,
32,
- lpdsf->s.width * (this->d.depth / 8)
+ lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8)
);
#ifdef HAVE_LIBXXSHM
}
#endif
- lpdsf->s.lpitch = img->bytes_per_line;
+ lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
return img;
}
@@ -1684,39 +1779,37 @@
(*lpdsf)->s.ddraw = this;
(*lpdsf)->ref = 1;
(*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
+ (*lpdsf)->s.palette = NULL;
+ (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
if (!(lpddsd->dwFlags & DDSD_WIDTH))
lpddsd->dwWidth = this->d.width;
if (!(lpddsd->dwFlags & DDSD_HEIGHT))
lpddsd->dwHeight = this->d.height;
- (*lpdsf)->s.width = lpddsd->dwWidth;
- (*lpdsf)->s.height = lpddsd->dwHeight;
-
+ /* Check if this a 'primary surface' or not */
if ((lpddsd->dwFlags & DDSD_CAPS) &&
- (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)) {
-
- /* Allocate surface memory */
- (*lpdsf)->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
-
- /* No XImage for a offscreen buffer */
- (*lpdsf)->t.xlib.image = NULL;
- (*lpdsf)->t.xlib.on_screen = FALSE;
- (*lpdsf)->s.lpitch = lpddsd->dwWidth * (this->d.depth / 8);
-
- TRACE(ddraw,"using system memory for a primary surface (%p)\n", *lpdsf);
- } else {
+ (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
XImage *img;
TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
+ /* First, store the surface description */
+ (*lpdsf)->s.surface_desc = *lpddsd;
+
/* Create the XImage */
img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
if (img == NULL)
return DDERR_OUTOFMEMORY;
-
(*lpdsf)->t.xlib.image = img;
- (*lpdsf)->t.xlib.on_screen = TRUE;
+
+ /* Add flags if there were not present */
+ (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
+ (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
+ (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
+ (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
+ _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
+ (*lpdsf)->s.backbuffer = NULL;
/* Check for backbuffers */
if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
@@ -1736,9 +1829,8 @@
back->ref = 1;
back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
-
- back->s.width = lpddsd->dwWidth;
- back->s.height = lpddsd->dwHeight;
+ /* Copy the surface description from the front buffer */
+ back->s.surface_desc = (*lpdsf)->s.surface_desc;
/* Create the XImage */
img = create_ximage(this, back);
@@ -1746,10 +1838,19 @@
return DDERR_OUTOFMEMORY;
back->t.xlib.image = img;
- back->t.xlib.on_screen = FALSE;
back->s.backbuffer = NULL; /* does not have a backbuffer, it is
* one! */
+
+ /* Add relevant info to front and back buffers */
+ (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
+ back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
+ back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
+ back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
}
+ } else {
+ /* There is no Xlib-specific code here...
+ Go to the common surface creation function */
+ return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
}
return 0;
@@ -2557,7 +2658,9 @@
ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
}
- } else {
+ }
+ else
+ {
ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
}
diff --git a/include/ddraw.h b/include/ddraw.h
index 8deb38a..1e03f8b 100644
--- a/include/ddraw.h
+++ b/include/ddraw.h
@@ -985,8 +985,8 @@
LPDIRECTDRAWPALETTE palette;
LPDIRECTDRAW2 ddraw;
LPDIRECTDRAWSURFACE3 backbuffer;
- LPVOID surface;
- DWORD lpitch,width,height;
+
+ DDSURFACEDESC surface_desc;
};
struct _dga_directdrawsurface {
@@ -995,7 +995,6 @@
struct _xlib_directdrawsurface {
XImage *image;
- int on_screen;
#ifdef HAVE_LIBXXSHM
XShmSegmentInfo shminfo;
#endif
@@ -1013,7 +1012,8 @@
STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE;
STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE, LPRECT32,DWORD) PURE;
STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE) PURE;
- STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE; STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE;
+ STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE;
+ STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE;
STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE, DWORD) PURE;
STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE FAR *) PURE;
STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE;
@@ -1196,5 +1196,6 @@
HRESULT WINAPI DirectDrawCreate(LPGUID,LPDIRECTDRAW*,LPUNKNOWN);
HRESULT WINAPI DirectDrawEnumerate32A(LPDDENUMCALLBACK32A,LPVOID);
HRESULT WINAPI DirectDrawEnumerate32W(LPDDENUMCALLBACK32W,LPVOID);
+HRESULT WINAPI DirectDrawCreateClipper(DWORD,LPDIRECTDRAWCLIPPER*,LPUNKNOWN);
#define DirectDrawEnumerate WINELIB_NAME_AW(DirectDrawEnumerate)
#endif
diff --git a/relay32/ddraw.spec b/relay32/ddraw.spec
index 151a1c3..46d88b4 100644
--- a/relay32/ddraw.spec
+++ b/relay32/ddraw.spec
@@ -7,7 +7,7 @@
4 stub DDInternalUnlock
5 stdcall DSoundHelp(long long long) DSoundHelp
6 stdcall DirectDrawCreate(ptr ptr ptr) DirectDrawCreate
- 7 stub DirectDrawCreateClipper
+ 7 stdcall DirectDrawCreateClipper(long ptr ptr) DirectDrawCreateClipper
8 stdcall DirectDrawEnumerateA(ptr ptr) DirectDrawEnumerate32A
9 stub DirectDrawEnumerateW
10 stub DllCanUnloadNow