Commit f48db828 authored by Marcus Meissner's avatar Marcus Meissner Committed by Alexandre Julliard

Implemented chains of surfaces. This allows an unlimited number

of backbuffers, and other attached surfaces (zbuffers, alpha buffers, whatever).
parent e00114c4
...@@ -193,7 +193,6 @@ int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2I ...@@ -193,7 +193,6 @@ int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2I
surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4); surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
#else #else
/* First get the correct visual */ /* First get the correct visual */
TRACE("Backbuffer : %d\n", surface->s.backbuffer == NULL);
/* if (surface->s.backbuffer == NULL) /* if (surface->s.backbuffer == NULL)
attributeList[3] = None; */ attributeList[3] = None; */
ENTER_GL(); ENTER_GL();
...@@ -216,8 +215,13 @@ int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2I ...@@ -216,8 +215,13 @@ int is_OpenGL(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevice2I
/* Now override the surface's Flip method (if in double buffering) */ /* Now override the surface's Flip method (if in double buffering) */
surface->s.d3d_device = (void *) odev; surface->s.d3d_device = (void *) odev;
if (surface->s.backbuffer != NULL) {
surface->s.backbuffer->s.d3d_device = (void *) odev; int i;
struct _surface_chain *chain = surface->s.chain;
for (i=0;i<chain->nrofsurfaces;i++)
if (chain->surfaces[i]->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_FLIP)
chain->surfaces[i]->s.d3d_device = (void *) odev;
}
#endif #endif
odev->rs.src = GL_ONE; odev->rs.src = GL_ONE;
odev->rs.dst = GL_ZERO; odev->rs.dst = GL_ZERO;
...@@ -1253,7 +1257,6 @@ int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevi ...@@ -1253,7 +1257,6 @@ int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevi
surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4); surface->s.surface_desc.dwWidth * surface->s.surface_desc.dwHeight * 4);
#else #else
/* First get the correct visual */ /* First get the correct visual */
TRACE("Backbuffer : %d\n", surface->s.backbuffer == NULL);
/* if (surface->s.backbuffer == NULL) /* if (surface->s.backbuffer == NULL)
attributeList[3] = None; */ attributeList[3] = None; */
ENTER_GL(); ENTER_GL();
...@@ -1273,8 +1276,13 @@ int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevi ...@@ -1273,8 +1276,13 @@ int is_OpenGL_dx3(REFCLSID rguid, IDirectDrawSurfaceImpl* surface, IDirect3DDevi
/* Now override the surface's Flip method (if in double buffering) */ /* Now override the surface's Flip method (if in double buffering) */
surface->s.d3d_device = (void *) odev; surface->s.d3d_device = (void *) odev;
if (surface->s.backbuffer != NULL) {
surface->s.backbuffer->s.d3d_device = (void *) odev; int i;
struct _surface_chain *chain = surface->s.chain;
for (i=0;i<chain->nrofsurfaces;i++)
if (chain->surfaces[i]->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_FLIP)
chain->surfaces[i]->s.d3d_device = (void *) odev;
}
#endif #endif
odev->rs.src = GL_ONE; odev->rs.src = GL_ONE;
odev->rs.dst = GL_ZERO; odev->rs.dst = GL_ZERO;
......
...@@ -73,6 +73,10 @@ DEFAULT_DEBUG_CHANNEL(ddraw) ...@@ -73,6 +73,10 @@ DEFAULT_DEBUG_CHANNEL(ddraw)
*/ */
#define RESTORE_SIGNALS #define RESTORE_SIGNALS
/* 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 */ /* Get the number of bytes per pixel for a given surface */
#define GET_BPP(desc) (desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ? \ #define GET_BPP(desc) (desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ? \
1 : \ 1 : \
...@@ -609,6 +613,7 @@ static void _dump_surface_desc(DDSURFACEDESC *lpddsd) { ...@@ -609,6 +613,7 @@ static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
* DDS and DDS2 use those functions. (Function calls did not change (except * DDS and DDS2 use those functions. (Function calls did not change (except
* using different DirectDrawSurfaceX version), just added flags and functions) * using different DirectDrawSurfaceX version), just added flags and functions)
*/ */
static HRESULT WINAPI IDirectDrawSurface4Impl_Lock( static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
) { ) {
...@@ -688,8 +693,7 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock( ...@@ -688,8 +693,7 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
return DD_OK; return DD_OK;
/* Only redraw the screen when unlocking the buffer that is on screen */ /* Only redraw the screen when unlocking the buffer that is on screen */
if ((This->t.xlib.image != NULL) && if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
(This->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
Xlib_copy_surface_on_screen(This); Xlib_copy_surface_on_screen(This);
if (This->s.palette && This->s.palette->cm) if (This->s.palette && This->s.palette->cm)
...@@ -699,91 +703,119 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock( ...@@ -699,91 +703,119 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
return DD_OK; return DD_OK;
} }
static IDirectDrawSurface4Impl* _common_find_flipto(
IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
) {
int i,j,flipable=0;
struct _surface_chain *chain = This->s.chain;
/* if there was no override flipto, look for current backbuffer */
if (!flipto) {
/* walk the flip chain looking for backbuffer */
for (i=0;i<chain->nrofsurfaces;i++) {
if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
flipable++;
if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
flipto = chain->surfaces[i];
}
/* sanity checks ... */
if (!flipto) {
if (flipable>1) {
for (i=0;i<chain->nrofsurfaces;i++)
if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
break;
if (i==chain->nrofsurfaces) {
/* we do not have a frontbuffer either */
for (i=0;i<chain->nrofsurfaces;i++)
if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
break;
}
for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
int k = j % chain->nrofsurfaces;
if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
flipto = chain->surfaces[k];
break;
}
}
}
}
if (!flipto)
flipto = This;
}
}
/* clear all front and backbuffers */
for (i=0;i<chain->nrofsurfaces;i++)
SDDSCAPS(chain->surfaces[i])&=~(DDSCAPS_FRONTBUFFER|DDSCAPS_BACKBUFFER);
/* set current backbuffer to frontbuffer */
SDDSCAPS(flipto) |= DDSCAPS_FRONTBUFFER;
SDDSCAPS(flipto) &= ~DDSCAPS_BACKBUFFER;
/* find next backbuffer starting from current frontbuffer */
for (i=0;i<chain->nrofsurfaces;i++)
if (chain->surfaces[i]==flipto)
break;
for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
int k = j%chain->nrofsurfaces;
if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
SDDSCAPS(chain->surfaces[k])|= DDSCAPS_BACKBUFFER;
break;
}
}
return flipto;
}
#ifdef HAVE_LIBXXF86DGA #ifdef HAVE_LIBXXF86DGA
static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip( static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
) { ) {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto; IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
if (!iflipto) {
if (This->s.backbuffer)
iflipto = This->s.backbuffer;
else
iflipto = This;
}
TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
if (iflipto->s.palette && iflipto->s.palette->cm) { TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm); iflipto = _common_find_flipto(This,iflipto);
}
while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
}
if (iflipto!=This) {
int tmp;
LPVOID ptmp;
tmp = This->t.dga.fb_height; /* and flip! */
This->t.dga.fb_height = iflipto->t.dga.fb_height; TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
iflipto->t.dga.fb_height = tmp; if (iflipto->s.palette && iflipto->s.palette->cm)
TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
ptmp = This->s.surface_desc.y.lpSurface; }
This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface; return DD_OK;
iflipto->s.surface_desc.y.lpSurface = ptmp;
}
return DD_OK;
} }
#endif /* defined(HAVE_LIBXXF86DGA) */ #endif /* defined(HAVE_LIBXXF86DGA) */
static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip( static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
) { ) {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto; IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags); TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
iflipto = _common_find_flipto(This,iflipto);
#ifdef HAVE_MESAGL #ifdef HAVE_MESAGL
if ((This->s.d3d_device != NULL) || if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
((This->s.backbuffer != NULL) && (This->s.backbuffer->s.d3d_device != NULL))) {
TRACE(" - OpenGL flip\n"); TRACE(" - OpenGL flip\n");
ENTER_GL(); ENTER_GL();
glXSwapBuffers(display, glXSwapBuffers(display, This->s.ddraw->d.drawable);
This->s.ddraw->d.drawable);
LEAVE_GL(); LEAVE_GL();
return DD_OK; return DD_OK;
} }
#endif /* defined(HAVE_MESAGL) */ #endif /* defined(HAVE_MESAGL) */
if (!This->s.ddraw->d.paintable) if (!This->s.ddraw->d.paintable)
return DD_OK; return DD_OK;
if (!iflipto) { Xlib_copy_surface_on_screen(iflipto);
if (This->s.backbuffer) if (iflipto->s.palette && iflipto->s.palette->cm)
iflipto = This->s.backbuffer; TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
else return DD_OK;
iflipto = This;
}
Xlib_copy_surface_on_screen(iflipto);
if (iflipto->s.palette && iflipto->s.palette->cm) {
TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
}
if (iflipto!=This) {
XImage *tmp;
LPVOID *surf;
tmp = This->t.xlib.image;
This->t.xlib.image = iflipto->t.xlib.image;
iflipto->t.xlib.image = tmp;
surf = This->s.surface_desc.y.lpSurface;
This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
iflipto->s.surface_desc.y.lpSurface = surf;
}
return DD_OK;
} }
/* The IDirectDrawSurface4::SetPalette method attaches the specified /* The IDirectDrawSurface4::SetPalette method attaches the specified
* DirectDrawPalette object to a surface. The surface uses this palette for all * DirectDrawPalette object to a surface. The surface uses this palette for all
* subsequent operations. The palette change takes place immediately. * subsequent operations. The palette change takes place immediately.
...@@ -835,15 +867,6 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette( ...@@ -835,15 +867,6 @@ static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
if( This->s.palette != NULL ) if( This->s.palette != NULL )
IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette ); IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
This->s.palette = ipal; This->s.palette = ipal;
/* I think that we need to attach it to all backbuffers...*/
if( This->s.backbuffer ) {
if( This->s.backbuffer->s.palette )
IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
This->s.backbuffer->s.palette = ipal;
if( ipal )
IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
}
/* Perform the refresh */ /* Perform the refresh */
TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm); TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
} }
...@@ -868,15 +891,6 @@ static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette( ...@@ -868,15 +891,6 @@ static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
if( This->s.palette != NULL ) if( This->s.palette != NULL )
IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette ); IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
This->s.palette = ipal; This->s.palette = ipal;
/* I think that we need to attach it to all backbuffers...*/
if( This->s.backbuffer ) {
if( This->s.backbuffer->s.palette )
IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
This->s.backbuffer->s.palette = ipal;
if ( ipal )
IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
}
TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm); TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
} }
return DD_OK; return DD_OK;
...@@ -1260,152 +1274,149 @@ static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps( ...@@ -1260,152 +1274,149 @@ static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc( static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
) { ) {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
TRACE("(%p)->GetSurfaceDesc(%p)\n", TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
This,ddsd);
/* Simply copy the surface description stored in the object */ /* Simply copy the surface description stored in the object */
*ddsd = This->s.surface_desc; *ddsd = This->s.surface_desc;
if (TRACE_ON(ddraw)) { if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
_dump_surface_desc(ddsd);
}
return DD_OK; return DD_OK;
} }
static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) { static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
TRACE("(%p)->() incrementing from %lu.\n", This, This->ref ); TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
return ++(This->ref);
return ++(This->ref);
} }
#ifdef HAVE_LIBXXF86DGA #ifdef HAVE_LIBXXF86DGA
static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) { static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
if (!--(This->ref)) { TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
/* clear out of surface list */
if (This->t.dga.fb_height == -1) {
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));
}
/* Free the backbuffer */ if (--(This->ref))
if (This->s.backbuffer) return This->ref;
IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
/* Free the DIBSection (if any) */ IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
if (This->s.hdc != 0) { /* clear out of surface list */
SelectObject(This->s.hdc, This->s.holdbitmap); if (This->t.dga.fb_height == -1)
DeleteDC(This->s.hdc); HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
DeleteObject(This->s.DIBsection); else
} This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
HeapFree(GetProcessHeap(),0,This); /* Free the DIBSection (if any) */
return 0; if (This->s.hdc != 0) {
} SelectObject(This->s.hdc, This->s.holdbitmap);
return This->ref; DeleteDC(This->s.hdc);
DeleteObject(This->s.DIBsection);
}
HeapFree(GetProcessHeap(),0,This);
return 0;
} }
#endif /* defined(HAVE_LIBXXF86DGA) */ #endif /* defined(HAVE_LIBXXF86DGA) */
static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) { static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
if (!--(This->ref)) { TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
if (--(This->ref))
return This->ref;
if( This->s.backbuffer ) IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
if (This->t.xlib.image != NULL) { if (This->t.xlib.image != NULL) {
if (This->s.ddraw->d.pixel_convert != NULL) { if (This->s.ddraw->d.pixel_convert != NULL) {
/* In pixel conversion mode, there are two buffers to release... */ /* In pixel conversion mode, there are 2 buffers to release. */
HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface); HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
#ifdef HAVE_LIBXXSHM #ifdef HAVE_LIBXXSHM
if (This->s.ddraw->e.xlib.xshm_active) { if (This->s.ddraw->e.xlib.xshm_active) {
TSXShmDetach(display, &(This->t.xlib.shminfo)); TSXShmDetach(display, &(This->t.xlib.shminfo));
TSXDestroyImage(This->t.xlib.image); TSXDestroyImage(This->t.xlib.image);
shmdt(This->t.xlib.shminfo.shmaddr); shmdt(This->t.xlib.shminfo.shmaddr);
} else { } else {
#endif #endif
HeapFree(GetProcessHeap(),0,This->t.xlib.image->data); HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
This->t.xlib.image->data = NULL; This->t.xlib.image->data = NULL;
TSXDestroyImage(This->t.xlib.image); TSXDestroyImage(This->t.xlib.image);
#ifdef HAVE_LIBXXSHM #ifdef HAVE_LIBXXSHM
} }
#endif #endif
} else {
} else { This->t.xlib.image->data = NULL;
This->t.xlib.image->data = NULL;
#ifdef HAVE_LIBXXSHM #ifdef HAVE_LIBXXSHM
if (This->s.ddraw->e.xlib.xshm_active) { if (This->s.ddraw->e.xlib.xshm_active) {
TSXShmDetach(display, &(This->t.xlib.shminfo)); TSXShmDetach(display, &(This->t.xlib.shminfo));
TSXDestroyImage(This->t.xlib.image); TSXDestroyImage(This->t.xlib.image);
shmdt(This->t.xlib.shminfo.shmaddr); shmdt(This->t.xlib.shminfo.shmaddr);
} else { } else {
#endif #endif
HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface); HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
TSXDestroyImage(This->t.xlib.image); TSXDestroyImage(This->t.xlib.image);
#ifdef HAVE_LIBXXSHM #ifdef HAVE_LIBXXSHM
} }
#endif #endif
} }
This->t.xlib.image = 0;
This->t.xlib.image = 0;
} else { } else {
HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface); HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
} }
if (This->s.palette) if (This->s.palette)
IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette); IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
/* Free the DIBSection (if any) */ /* Free the DIBSection (if any) */
if (This->s.hdc != 0) { if (This->s.hdc != 0) {
SelectObject(This->s.hdc, This->s.holdbitmap); SelectObject(This->s.hdc, This->s.holdbitmap);
DeleteDC(This->s.hdc); DeleteDC(This->s.hdc);
DeleteObject(This->s.DIBsection); DeleteObject(This->s.DIBsection);
} }
HeapFree(GetProcessHeap(),0,This); HeapFree(GetProcessHeap(),0,This);
return 0; return 0;
}
return This->ref;
} }
static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface( static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
) { ) {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
TRACE("(%p)->GetAttachedSurface(%p,%p)\n", int i,found = 0,xstart;
This, lpddsd, lpdsf); struct _surface_chain *chain;
if (TRACE_ON(ddraw)) {
TRACE(" caps ");
_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
DPRINTF("\n");
}
if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) { TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
FIXME("whoops, can only handle backbuffers for now\n"); if (TRACE_ON(ddraw)) {
return E_FAIL; TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
} }
chain = This->s.chain;
if (!chain)
return DDERR_NOTFOUND;
/* FIXME: should handle more than one backbuffer */ for (i=0;i<chain->nrofsurfaces;i++)
*lpdsf = (LPDIRECTDRAWSURFACE4)This->s.backbuffer; if (chain->surfaces[i] == This)
break;
if( This->s.backbuffer )
IDirectDrawSurface4_AddRef( (IDirectDrawSurface4*)This->s.backbuffer );
return DD_OK; xstart = i;
for (i=0;i<chain->nrofsurfaces;i++) {
if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
#if 0
if (found) /* may not find the same caps twice, (doc) */
return DDERR_INVALIDPARAMS;/*FIXME: correct? */
#endif
found = (i+1)+xstart;
}
}
if (!found)
return DDERR_NOTFOUND;
*lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
/* FIXME: AddRef? */
TRACE("found %p\n",*lpdsf);
return DD_OK;
} }
static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize( static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
...@@ -1424,12 +1435,7 @@ static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat( ...@@ -1424,12 +1435,7 @@ static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
TRACE("(%p)->(%p)\n",This,pf); TRACE("(%p)->(%p)\n",This,pf);
*pf = This->s.surface_desc.ddpfPixelFormat; *pf = This->s.surface_desc.ddpfPixelFormat;
if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
if (TRACE_ON(ddraw)) {
_dump_pixelformat(pf);
DPRINTF("\n");
}
return DD_OK; return DD_OK;
} }
...@@ -1458,215 +1464,229 @@ static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper( ...@@ -1458,215 +1464,229 @@ static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface( static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
) { ) {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
FIXME("(%p)->(%p),stub!\n",This,surf); IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
int i;
struct _surface_chain *chain;
IDirectDrawSurface4_AddRef(iface); IDirectDrawSurface4_AddRef(iface);
/* This hack will be enough for the moment */ FIXME("(%p)->(%p)\n",This,surf);
if (This->s.backbuffer == NULL) chain = This->s.chain;
This->s.backbuffer = (IDirectDrawSurface4Impl*)surf;
return DD_OK; if (chain) {
for (i=0;i<chain->nrofsurfaces;i++)
if (chain->surfaces[i] == isurf)
FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
} else {
chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
chain->nrofsurfaces = 1;
chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
chain->surfaces[0] = This;
This->s.chain = chain;
}
if (chain->surfaces)
chain->surfaces = HeapReAlloc(
GetProcessHeap(),
0,
chain->surfaces,
sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
);
else
chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
isurf->s.chain = chain;
chain->surfaces[chain->nrofsurfaces++] = isurf;
return DD_OK;
} }
static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) { static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
DDSURFACEDESC desc; DDSURFACEDESC desc;
BITMAPINFO *b_info; BITMAPINFO *b_info;
UINT usage; UINT usage;
FIXME("(%p)->GetDC(%p)\n",This,lphdc);
/* Creates a DIB Section of the same size / format as the surface */ FIXME("(%p)->GetDC(%p)\n",This,lphdc);
IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
if (This->s.hdc == 0) { /* Creates a DIB Section of the same size / format as the surface */
switch (desc.ddpfPixelFormat.x.dwRGBBitCount) { IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
case 16:
case 32: if (This->s.hdc == 0) {
switch (desc.ddpfPixelFormat.x.dwRGBBitCount) {
case 16:
case 32:
#if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */ #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD)); b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
break; break;
#endif #endif
case 24: case 24:
b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER)); b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
break; break;
default: default:
b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.x.dwRGBBitCount)); sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.x.dwRGBBitCount));
break; break;
} }
b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
b_info->bmiHeader.biWidth = desc.dwWidth; b_info->bmiHeader.biWidth = desc.dwWidth;
b_info->bmiHeader.biHeight = desc.dwHeight; b_info->bmiHeader.biHeight = desc.dwHeight;
b_info->bmiHeader.biPlanes = 1; b_info->bmiHeader.biPlanes = 1;
b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.x.dwRGBBitCount; b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.x.dwRGBBitCount;
#if 0 #if 0
if ((desc.ddpfPixelFormat.x.dwRGBBitCount != 16) && if ((desc.ddpfPixelFormat.x.dwRGBBitCount != 16) &&
(desc.ddpfPixelFormat.x.dwRGBBitCount != 32)) (desc.ddpfPixelFormat.x.dwRGBBitCount != 32))
#endif #endif
b_info->bmiHeader.biCompression = BI_RGB; b_info->bmiHeader.biCompression = BI_RGB;
#if 0 #if 0
else else
b_info->bmiHeader.biCompression = BI_BITFIELDS; b_info->bmiHeader.biCompression = BI_BITFIELDS;
#endif #endif
b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.x.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight; b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.x.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
b_info->bmiHeader.biXPelsPerMeter = 0; b_info->bmiHeader.biXPelsPerMeter = 0;
b_info->bmiHeader.biYPelsPerMeter = 0; b_info->bmiHeader.biYPelsPerMeter = 0;
b_info->bmiHeader.biClrUsed = 0; b_info->bmiHeader.biClrUsed = 0;
b_info->bmiHeader.biClrImportant = 0; b_info->bmiHeader.biClrImportant = 0;
switch (desc.ddpfPixelFormat.x.dwRGBBitCount) { switch (desc.ddpfPixelFormat.x.dwRGBBitCount) {
case 16: case 16:
case 32: case 32:
#if 0 #if 0
{ {
DWORD *masks = (DWORD *) &(b_info->bmiColors); DWORD *masks = (DWORD *) &(b_info->bmiColors);
usage = 0; usage = 0;
masks[0] = desc.ddpfPixelFormat.y.dwRBitMask; masks[0] = desc.ddpfPixelFormat.y.dwRBitMask;
masks[1] = desc.ddpfPixelFormat.z.dwGBitMask; masks[1] = desc.ddpfPixelFormat.z.dwGBitMask;
masks[2] = desc.ddpfPixelFormat.xx.dwBBitMask; masks[2] = desc.ddpfPixelFormat.xx.dwBBitMask;
} break; }
break;
#endif #endif
case 24:
case 24: /* Nothing to do */
/* Nothing to do */ usage = DIB_RGB_COLORS;
usage = DIB_RGB_COLORS; break;
break;
default: {
int i;
/* Fill the palette */
usage = DIB_RGB_COLORS;
if (This->s.palette == NULL) { default: {
ERR("Bad palette !!!\n"); int i;
} else {
RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
PALETTEENTRY *pent = (PALETTEENTRY *) &(This->s.palette->palents);
for (i = 0; i < (2 << desc.ddpfPixelFormat.x.dwRGBBitCount); i++) {
rgb[i].rgbBlue = pent[i].peBlue;
rgb[i].rgbRed = pent[i].peRed;
rgb[i].rgbGreen = pent[i].peGreen;
}
}
} break;
}
This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
b_info,
usage,
&(This->s.bitmap_data),
(HANDLE)0,
0);
EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
TRACE("DIBSection at : %p\n", This->s.bitmap_data);
/* b_info is not useful anymore */
HeapFree(GetProcessHeap(), 0, b_info);
/* Create the DC */
This->s.hdc = CreateCompatibleDC(0);
This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
}
/* Copy our surface in the DIB section */
if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch) {
memcpy(This->s.bitmap_data, desc.y.lpSurface, desc.lPitch * desc.dwHeight);
} else {
/* TODO */
FIXME("This case has to be done :/\n");
}
TRACE("HDC : %08lx\n", (DWORD) This->s.hdc); /* Fill the palette */
*lphdc = This->s.hdc; usage = DIB_RGB_COLORS;
return DD_OK;
}
static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
ICOM_THIS(IDirectDrawSurface4Impl,iface);
FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
TRACE("Copying DIBSection at : %p\n", This->s.bitmap_data); if (This->s.palette == NULL) {
ERR("Bad palette !!!\n");
/* Copy the DIB section to our surface */ } else {
if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) { RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
memcpy(This->s.surface_desc.y.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight); PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
} else {
/* TODO */ for (i=0;i<(1<<desc.ddpfPixelFormat.x.dwRGBBitCount);i++) {
FIXME("This case has to be done :/\n"); rgb[i].rgbBlue = pent[i].peBlue;
rgb[i].rgbRed = pent[i].peRed;
rgb[i].rgbGreen = pent[i].peGreen;
}
}
}
break;
} }
This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
b_info,
usage,
&(This->s.bitmap_data),
0,
0
);
EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
TRACE("DIBSection at : %p\n", This->s.bitmap_data);
/* Unlock the surface */ /* b_info is not useful anymore */
IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.y.lpSurface); HeapFree(GetProcessHeap(), 0, b_info);
return DD_OK; /* Create the DC */
This->s.hdc = CreateCompatibleDC(0);
This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
}
/* Copy our surface in the DIB section */
if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
memcpy(This->s.bitmap_data,desc.y.lpSurface,desc.lPitch*desc.dwHeight);
else
/* TODO */
FIXME("This case has to be done :/\n");
TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
*lphdc = This->s.hdc;
return DD_OK;
} }
static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) { static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
char xrefiid[50];
WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj); TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
/* Copy the DIB section to our surface */
/* All DirectDrawSurface versions (1, 2, 3 and 4) use if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
* the same interface. And IUnknown does that too of course. memcpy(This->s.surface_desc.y.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
*/ } else {
if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) || /* TODO */
!memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) || FIXME("This case has to be done :/\n");
!memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) || }
!memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) || /* Unlock the surface */
!memcmp(&IID_IUnknown,refiid,sizeof(IID)) IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.y.lpSurface);
) { return DD_OK;
*obj = This; }
IDirectDrawSurface4_AddRef(iface);
TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj); static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
ICOM_THIS(IDirectDrawSurface4Impl,iface);
return S_OK; char xrefiid[50];
}
else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID))) WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
{ TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
/* Texture interface */
*obj = d3dtexture2_create(This); /* All DirectDrawSurface versions (1, 2, 3 and 4) use
IDirectDrawSurface4_AddRef(iface); * the same interface. And IUnknown does that too of course.
*/
TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj); if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
!memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
return S_OK; !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
} !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID))) !memcmp(&IID_IUnknown,refiid,sizeof(IID))
{ ) {
/* Texture interface */ *obj = This;
*obj = d3dtexture_create(This);
IDirectDrawSurface4_AddRef(iface);
TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
return S_OK;
}
else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj))
{
/* It is the OpenGL Direct3D Device */
IDirectDrawSurface4_AddRef(iface); IDirectDrawSurface4_AddRef(iface);
TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj); TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
return S_OK;
return S_OK; }
} else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
{
/* Texture interface */
*obj = d3dtexture2_create(This);
IDirectDrawSurface4_AddRef(iface);
TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
return S_OK;
}
else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
{
/* Texture interface */
*obj = d3dtexture_create(This);
IDirectDrawSurface4_AddRef(iface);
FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid); TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
return OLE_E_ENUM_NOMORE;
return S_OK;
}
else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
/* It is the OpenGL Direct3D Device */
IDirectDrawSurface4_AddRef(iface);
TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
return S_OK;
}
FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
return OLE_E_ENUM_NOMORE;
} }
static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) { static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
...@@ -1676,17 +1696,17 @@ static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) ...@@ -1676,17 +1696,17 @@ static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface)
} }
static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) { static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
FIXME("(%p)->(%p,%p),stub!\n",This,context,esfcb); int i;
struct _surface_chain *chain = This->s.chain;
/* For the moment, only enumerating the back buffer */
if (This->s.backbuffer != NULL) { TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
TRACE("Enumerating back-buffer (%p)\n", This->s.backbuffer); for (i=0;i<chain->nrofsurfaces;i++) {
if (esfcb((LPDIRECTDRAWSURFACE) This->s.backbuffer, &(This->s.backbuffer->s.surface_desc), context) == DDENUMRET_CANCEL) TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
return DD_OK; if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
} return DD_OK; /* FIXME: return value correct? */
}
return DD_OK; return DD_OK;
} }
static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) { static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
...@@ -1765,10 +1785,32 @@ static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface( ...@@ -1765,10 +1785,32 @@ static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
DWORD dwFlags, DWORD dwFlags,
LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface ) LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
{ {
ICOM_THIS(IDirectDrawSurface4Impl,iface); ICOM_THIS(IDirectDrawSurface4Impl,iface);
FIXME("(%p)->(0x%08lx,%p),stub!\n",This,dwFlags,lpDDSAttachedSurface); int i;
struct _surface_chain *chain;
return DD_OK;
TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
chain = This->s.chain;
for (i=0;i<chain->nrofsurfaces;i++) {
if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
IDirectDrawSurface4_Release(lpDDSAttachedSurface);
chain->surfaces[i]->s.chain = NULL;
memcpy( chain->surfaces+i,
chain->surfaces+(i+1),
(chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
);
chain->surfaces = HeapReAlloc(
GetProcessHeap(),
0,
chain->surfaces,
sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
);
chain->nrofsurfaces--;
return DD_OK;
}
}
return DD_OK;
} }
static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders( static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
...@@ -2721,7 +2763,7 @@ static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This, ...@@ -2721,7 +2763,7 @@ static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
int bpp; int bpp;
/* The surface was already allocated when entering in this function */ /* The surface was already allocated when entering in this function */
TRACE("using system memory for a surface (%p)\n", lpdsf); TRACE("using system memory for a surface (%p) \n", lpdsf);
if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) { if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
/* This is a Z Buffer */ /* This is a Z Buffer */
...@@ -2755,106 +2797,114 @@ static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This, ...@@ -2755,106 +2797,114 @@ static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface( static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
) { ) {
ICOM_THIS(IDirectDraw2Impl,iface); ICOM_THIS(IDirectDraw2Impl,iface);
IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf; IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
int i; int i, fbheight = This->e.dga.fb_height;
TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk); TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
if (TRACE_ON(ddraw)) { if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
_dump_surface_desc(lpddsd);
} *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
GetProcessHeap(),
*ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl)); HEAP_ZERO_MEMORY,
IDirectDraw2_AddRef(iface); sizeof(IDirectDrawSurfaceImpl)
);
(*ilpdsf)->ref = 1; IDirectDraw2_AddRef(iface);
(*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
(*ilpdsf)->s.ddraw = This; (*ilpdsf)->ref = 1;
(*ilpdsf)->s.palette = NULL; (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
(*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */ (*ilpdsf)->s.ddraw = This;
(*ilpdsf)->s.palette = NULL;
/* Copy the surface description */ (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
/* Copy the surface description */
(*ilpdsf)->s.surface_desc = *lpddsd;
if (!(lpddsd->dwFlags & DDSD_WIDTH))
(*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
if (!(lpddsd->dwFlags & DDSD_HEIGHT))
(*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
(*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_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 */
(*ilpdsf)->s.surface_desc = *lpddsd; (*ilpdsf)->s.surface_desc = *lpddsd;
if (!(lpddsd->dwFlags & DDSD_WIDTH))
(*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
if (!(lpddsd->dwFlags & DDSD_HEIGHT))
(*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
(*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_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 */
(*ilpdsf)->s.surface_desc = *lpddsd;
/* Find a viewport */
for (i=0;i<32;i++)
if (!(This->e.dga.vpmask & (1<<i)))
break;
TRACE("using viewport %d for a primary surface\n",i);
/* if i == 32 or maximum ... return error */
This->e.dga.vpmask|=(1<<i);
(*ilpdsf)->s.surface_desc.y.lpSurface =
This->e.dga.fb_addr+((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
(*ilpdsf)->t.dga.fb_height = i*This->e.dga.fb_height;
(*ilpdsf)->s.surface_desc.lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch;
/* Add flags if there were not present */
(*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
(*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
(*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
/* We put our surface always in video memory */
(*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
(*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
(*ilpdsf)->s.backbuffer = NULL;
if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
IDirectDrawSurface4Impl* back;
if (lpddsd->dwBackBufferCount>1) /* Find a viewport */
FIXME("urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount); for (i=0;i<32;i++)
if (!(This->e.dga.vpmask & (1<<i)))
break;
TRACE("using viewport %d for a primary surface\n",i);
/* if i == 32 or maximum ... return error */
This->e.dga.vpmask|=(1<<i);
lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
This->e.dga.fb_width*
(This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
(*ilpdsf)->s.surface_desc.y.lpSurface =
This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
(*ilpdsf)->t.dga.fb_height = i*fbheight;
/* Add flags if there were not present */
(*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
(*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
(*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
/* We put our surface always in video memory */
SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
(*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
(*ilpdsf)->s.chain = NULL;
(*ilpdsf)->s.backbuffer = back = if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
(IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl)); IDirectDrawSurface4Impl* back;
int i;
for (i=lpddsd->dwBackBufferCount;i--;) {
back = (IDirectDrawSurface4Impl*)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(IDirectDrawSurface4Impl)
);
IDirectDraw2_AddRef(iface); IDirectDraw2_AddRef(iface);
back->ref = 1; back->ref = 1;
back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt; back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
for (i=0;i<32;i++) for (i=0;i<32;i++)
if (!(This->e.dga.vpmask & (1<<i))) if (!(This->e.dga.vpmask & (1<<i)))
break; break;
TRACE("using viewport %d for backbuffer\n",i); TRACE("using viewport %d for backbuffer\n",i);
/* if i == 32 or maximum ... return error */ /* if i == 32 or maximum ... return error */
This->e.dga.vpmask|=(1<<i); This->e.dga.vpmask|=(1<<i);
back->t.dga.fb_height = i*This->e.dga.fb_height; back->t.dga.fb_height = i*fbheight;
/* Copy the surface description from the front buffer */
back->s.surface_desc = (*ilpdsf)->s.surface_desc;
/* Change the parameters that are not the same */
back->s.surface_desc.y.lpSurface =
This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
/* Copy the surface description from the front buffer */
back->s.surface_desc = (*ilpdsf)->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.directdraw_pixelformat.x.dwRGBBitCount/8);
back->s.ddraw = This; back->s.ddraw = This;
back->s.backbuffer = NULL; /* does not have a backbuffer, it is /* Add relevant info to front and back buffers */
* one! */ /* FIXME: backbuffer/frontbuffer handling broken here, but
* will be fixed up in _Flip().
/* Add relevant info to front and back buffers */ */
(*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE; SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
} }
} else {
/* There is no DGA-specific code here...
Go to the common surface creation function */
return common_off_screen_CreateSurface(This, *ilpdsf);
} }
} else {
return DD_OK; /* There is no DGA-specific code here...
Go to the common surface creation function */
return common_off_screen_CreateSurface(This, *ilpdsf);
}
return DD_OK;
} }
#endif /* defined(HAVE_LIBXXF86DGA) */ #endif /* defined(HAVE_LIBXXF86DGA) */
...@@ -2866,242 +2916,246 @@ static int XShmErrorHandler(Display *dpy, XErrorEvent *event) { ...@@ -2866,242 +2916,246 @@ static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
} }
static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) { static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
XImage *img; XImage *img;
int (*WineXHandler)(Display *, XErrorEvent *); int (*WineXHandler)(Display *, XErrorEvent *);
img = TSXShmCreateImage(display, img = TSXShmCreateImage(display,
DefaultVisualOfScreen(X11DRV_GetXScreen()), DefaultVisualOfScreen(X11DRV_GetXScreen()),
This->d.pixmap_depth, This->d.pixmap_depth,
ZPixmap, ZPixmap,
NULL, NULL,
&(lpdsf->t.xlib.shminfo), &(lpdsf->t.xlib.shminfo),
lpdsf->s.surface_desc.dwWidth, lpdsf->s.surface_desc.dwWidth,
lpdsf->s.surface_desc.dwHeight); lpdsf->s.surface_desc.dwHeight
);
if (img == NULL) {
MESSAGE("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n"); if (img == NULL) {
This->e.xlib.xshm_active = 0; FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
return NULL; This->e.xlib.xshm_active = 0;
} return NULL;
}
lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 ); lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
if (lpdsf->t.xlib.shminfo.shmid < 0) { if (lpdsf->t.xlib.shminfo.shmid < 0) {
MESSAGE("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n"); FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
This->e.xlib.xshm_active = 0; This->e.xlib.xshm_active = 0;
TSXDestroyImage(img); TSXDestroyImage(img);
return NULL; return NULL;
} }
lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0); lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
if (img->data == (char *) -1) { if (img->data == (char *) -1) {
MESSAGE("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n"); FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
This->e.xlib.xshm_active = 0; This->e.xlib.xshm_active = 0;
TSXDestroyImage(img); TSXDestroyImage(img);
shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0); shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
return NULL; return NULL;
} }
lpdsf->t.xlib.shminfo.readOnly = False; lpdsf->t.xlib.shminfo.readOnly = False;
/* This is where things start to get trickier.... /* This is where things start to get trickier....
First, we flush the current X connections to be sure to catch all non-XShm related * First, we flush the current X connections to be sure to catch all
errors */ * non-XShm related errors
*/
TSXSync(display, False); TSXSync(display, False);
/* Then we enter in the non-thread safe part of the tests */ /* Then we enter in the non-thread safe part of the tests */
EnterCriticalSection( &X11DRV_CritSection ); EnterCriticalSection( &X11DRV_CritSection );
/* Reset the error flag, sets our new error handler and try to attach the surface */ /* Reset the error flag, sets our new error handler and try to attach
XShmErrorFlag = 0; * the surface
WineXHandler = XSetErrorHandler(XShmErrorHandler); */
XShmAttach(display, &(lpdsf->t.xlib.shminfo));
XSync(display, False);
/* Check the error flag */
if (XShmErrorFlag) {
/* An error occured */
XFlush(display);
XShmErrorFlag = 0; XShmErrorFlag = 0;
XDestroyImage(img); WineXHandler = XSetErrorHandler(XShmErrorHandler);
shmdt(lpdsf->t.xlib.shminfo.shmaddr); XShmAttach(display, &(lpdsf->t.xlib.shminfo));
shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0); XSync(display, False);
/* Check the error flag */
if (XShmErrorFlag) {
/* An error occured */
XFlush(display);
XShmErrorFlag = 0;
XDestroyImage(img);
shmdt(lpdsf->t.xlib.shminfo.shmaddr);
shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
XSetErrorHandler(WineXHandler);
FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
This->e.xlib.xshm_active = 0;
/* Leave the critical section */
LeaveCriticalSection( &X11DRV_CritSection );
return NULL;
}
/* Here, to be REALLY sure, I should do a XShmPutImage to check if
* this works, but it may be a bit overkill....
*/
XSetErrorHandler(WineXHandler); XSetErrorHandler(WineXHandler);
MESSAGE("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
This->e.xlib.xshm_active = 0;
/* Leave the critical section */
LeaveCriticalSection( &X11DRV_CritSection ); LeaveCriticalSection( &X11DRV_CritSection );
return NULL;
}
/* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
but it may be a bit overkill.... */
XSetErrorHandler(WineXHandler);
LeaveCriticalSection( &X11DRV_CritSection );
shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0); shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
if (This->d.pixel_convert != NULL) { if (This->d.pixel_convert != NULL) {
lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(
lpdsf->s.surface_desc.dwWidth * GetProcessHeap(),
lpdsf->s.surface_desc.dwHeight * HEAP_ZERO_MEMORY,
(This->d.directdraw_pixelformat.x.dwRGBBitCount)); lpdsf->s.surface_desc.dwWidth *
lpdsf->s.surface_desc.dwHeight *
(This->d.directdraw_pixelformat.x.dwRGBBitCount)
);
} else { } else {
lpdsf->s.surface_desc.y.lpSurface = img->data; lpdsf->s.surface_desc.y.lpSurface = img->data;
} }
return img;
return img;
} }
#endif /* HAVE_LIBXXSHM */ #endif /* HAVE_LIBXXSHM */
static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) { static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
XImage *img = NULL; XImage *img = NULL;
void *img_data; void *img_data;
#ifdef HAVE_LIBXXSHM #ifdef HAVE_LIBXXSHM
if (This->e.xlib.xshm_active) { if (This->e.xlib.xshm_active)
img = create_xshmimage(This, lpdsf); img = create_xshmimage(This, lpdsf);
}
if (img == NULL) {
if (img == NULL) {
#endif #endif
/* Allocate surface memory */ /* Allocate surface memory */
lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(
lpdsf->s.surface_desc.dwWidth * GetProcessHeap(),HEAP_ZERO_MEMORY,
lpdsf->s.surface_desc.dwHeight * lpdsf->s.surface_desc.dwWidth *
(This->d.directdraw_pixelformat.x.dwRGBBitCount / 8)); lpdsf->s.surface_desc.dwHeight *
(This->d.directdraw_pixelformat.x.dwRGBBitCount / 8)
);
if (This->d.pixel_convert != NULL) {
img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
lpdsf->s.surface_desc.dwWidth *
lpdsf->s.surface_desc.dwHeight *
(This->d.screen_pixelformat.x.dwRGBBitCount / 8)
);
} else {
img_data = lpdsf->s.surface_desc.y.lpSurface;
}
/* In this case, create an XImage */
img = TSXCreateImage(display,
DefaultVisualOfScreen(X11DRV_GetXScreen()),
This->d.pixmap_depth,
ZPixmap,
0,
img_data,
lpdsf->s.surface_desc.dwWidth,
lpdsf->s.surface_desc.dwHeight,
32,
lpdsf->s.surface_desc.dwWidth * (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
);
#ifdef HAVE_LIBXXSHM
}
#endif
if (This->d.pixel_convert != NULL) { if (This->d.pixel_convert != NULL) {
img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, lpdsf->s.surface_desc.lPitch = (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
lpdsf->s.surface_desc.dwWidth *
lpdsf->s.surface_desc.dwHeight *
(This->d.screen_pixelformat.x.dwRGBBitCount / 8));
} else { } else {
img_data = lpdsf->s.surface_desc.y.lpSurface; lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
} }
return img;
/* In this case, create an XImage */
img =
TSXCreateImage(display,
DefaultVisualOfScreen(X11DRV_GetXScreen()),
This->d.pixmap_depth,
ZPixmap,
0,
img_data,
lpdsf->s.surface_desc.dwWidth,
lpdsf->s.surface_desc.dwHeight,
32,
lpdsf->s.surface_desc.dwWidth * (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
);
#ifdef HAVE_LIBXXSHM
}
#endif
if (This->d.pixel_convert != NULL) {
lpdsf->s.surface_desc.lPitch = (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
} else {
lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
}
return img;
} }
static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface( static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
) { ) {
ICOM_THIS(IDirectDraw2Impl,iface); ICOM_THIS(IDirectDraw2Impl,iface);
IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf; IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
TRACE("(%p)->CreateSurface(%p,%p,%p)\n",
This,lpddsd,ilpdsf,lpunk); TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
if (TRACE_ON(ddraw)) { if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
_dump_surface_desc(lpddsd);
} *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
*ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl)); );
IDirectDraw2_AddRef(iface); IDirectDraw2_AddRef(iface);
(*ilpdsf)->s.ddraw = This;
(*ilpdsf)->ref = 1; (*ilpdsf)->s.ddraw = This;
(*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt; (*ilpdsf)->ref = 1;
(*ilpdsf)->s.palette = NULL; (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
(*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */ (*ilpdsf)->s.palette = NULL;
(*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
/* Copy the surface description */
(*ilpdsf)->s.surface_desc = *lpddsd; /* Copy the surface description */
(*ilpdsf)->s.surface_desc = *lpddsd;
if (!(lpddsd->dwFlags & DDSD_WIDTH))
(*ilpdsf)->s.surface_desc.dwWidth = This->d.width; if (!(lpddsd->dwFlags & DDSD_WIDTH))
if (!(lpddsd->dwFlags & DDSD_HEIGHT)) (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
(*ilpdsf)->s.surface_desc.dwHeight = This->d.height; if (!(lpddsd->dwFlags & DDSD_HEIGHT))
(*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT; (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
(*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
/* Check if this a 'primary surface' or not */
if ((lpddsd->dwFlags & DDSD_CAPS) && /* Check if this a 'primary surface' or not */
(lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) { if ((lpddsd->dwFlags & DDSD_CAPS) &&
XImage *img; (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
XImage *img;
TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
/* Create the XImage */ /* Create the XImage */
img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf); img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
if (img == NULL) if (img == NULL)
return DDERR_OUTOFMEMORY; return DDERR_OUTOFMEMORY;
(*ilpdsf)->t.xlib.image = img; (*ilpdsf)->t.xlib.image = img;
/* Add flags if there were not present */ /* Add flags if there were not present */
(*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT; (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
(*ilpdsf)->s.surface_desc.dwWidth = This->d.width; (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
(*ilpdsf)->s.surface_desc.dwHeight = This->d.height; (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
(*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY; (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
(*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat; (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
(*ilpdsf)->s.backbuffer = NULL;
/* Check for backbuffers */
/* Check for backbuffers */
if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) { if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
IDirectDrawSurface4Impl* back; IDirectDrawSurface4Impl* back;
XImage *img; XImage *img;
int i;
if (lpddsd->dwBackBufferCount>1)
FIXME("urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount); for (i=lpddsd->dwBackBufferCount;i--;) {
back = (IDirectDrawSurface4Impl*)HeapAlloc(
GetProcessHeap(),HEAP_ZERO_MEMORY,
sizeof(IDirectDrawSurface4Impl)
);
(*ilpdsf)->s.backbuffer = back = TRACE("allocated back-buffer (%p)\n", back);
(IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
TRACE("allocated back-buffer (%p)\n", back);
IDirectDraw2_AddRef(iface); IDirectDraw2_AddRef(iface);
back->s.ddraw = This; back->s.ddraw = This;
back->ref = 1; back->ref = 1;
back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt; back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
/* Copy the surface description from the front buffer */ /* Copy the surface description from the front buffer */
back->s.surface_desc = (*ilpdsf)->s.surface_desc; back->s.surface_desc = (*ilpdsf)->s.surface_desc;
/* Create the XImage */ /* Create the XImage */
img = create_ximage(This, back); img = create_ximage(This, back);
if (img == NULL) if (img == NULL)
return DDERR_OUTOFMEMORY; return DDERR_OUTOFMEMORY;
back->t.xlib.image = img; back->t.xlib.image = img;
back->s.backbuffer = NULL; /* does not have a backbuffer, it is /* Add relevant info to front and back buffers */
* one! */ /* FIXME: backbuffer/frontbuffer handling broken here, but
* will be fixed up in _Flip().
/* Add relevant info to front and back buffers */ */
(*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE; SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
}
} }
} else { } else {
/* There is no Xlib-specific code here... /* There is no Xlib-specific code here...
Go to the common surface creation function */ Go to the common surface creation function */
return common_off_screen_CreateSurface(This, *ilpdsf); return common_off_screen_CreateSurface(This, *ilpdsf);
} }
return DD_OK;
return DD_OK;
} }
static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface( static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
...@@ -3121,6 +3175,7 @@ static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel( ...@@ -3121,6 +3175,7 @@ static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
) { ) {
ICOM_THIS(IDirectDraw2Impl,iface); ICOM_THIS(IDirectDraw2Impl,iface);
/*
int i; int i;
const struct { const struct {
int mask; int mask;
...@@ -3138,15 +3193,9 @@ static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel( ...@@ -3138,15 +3193,9 @@ static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
FE(DDSCL_CREATEDEVICEWINDOW) FE(DDSCL_CREATEDEVICEWINDOW)
#undef FE #undef FE
}; };
*/
FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel); FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
if(TRACE_ON(ddraw)){
dbg_decl_str(ddraw, 512);
for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
if (flagmap[i].mask & cooplevel)
dsprintf(ddraw, "%s ", flagmap[i].name);
TRACE(" cooperative level %s\n", dbg_str(ddraw));
}
This->d.mainWindow = hwnd; This->d.mainWindow = hwnd;
/* This will be overwritten in the case of Full Screen mode. /* This will be overwritten in the case of Full Screen mode.
...@@ -3160,7 +3209,7 @@ static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel( ...@@ -3160,7 +3209,7 @@ static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
if( !This->d.drawable ) { if( !This->d.drawable ) {
This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window; This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
WIN_ReleaseDesktop(); WIN_ReleaseDesktop();
} }
TRACE("Setting drawable to %ld\n", This->d.drawable); TRACE("Setting drawable to %ld\n", This->d.drawable);
} }
...@@ -3182,11 +3231,17 @@ static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) { ...@@ -3182,11 +3231,17 @@ static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
if ( IsWindow(This->d.mainWindow) && if ( IsWindow(This->d.mainWindow) &&
IsWindowVisible(This->d.mainWindow) IsWindowVisible(This->d.mainWindow)
) { ) {
/* if it does not fit, resize the cooperative window.
* and hope the app likes it
*/
GetWindowRect(This->d.mainWindow,&rect); GetWindowRect(This->d.mainWindow,&rect);
if (((rect.right-rect.left) >= This->d.width) && if ((((rect.right-rect.left) >= This->d.width) &&
((rect.bottom-rect.top) >= This->d.height) ((rect.bottom-rect.top) >= This->d.height))
) )
This->d.window = This->d.mainWindow; This->d.window = This->d.mainWindow;
/*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
} }
/* ... failed, create new one. */ /* ... failed, create new one. */
if (!This->d.window) { if (!This->d.window) {
...@@ -3670,8 +3725,7 @@ static void fill_caps(LPDDCAPS caps) { ...@@ -3670,8 +3725,7 @@ static void fill_caps(LPDDCAPS caps) {
return; return;
caps->dwSize = sizeof(*caps); caps->dwSize = sizeof(*caps);
caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE;
caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES; caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */ caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
caps->dwFXCaps = 0; caps->dwFXCaps = 0;
......
...@@ -141,7 +141,8 @@ struct _common_directdrawsurface ...@@ -141,7 +141,8 @@ struct _common_directdrawsurface
{ {
IDirectDrawPaletteImpl* palette; IDirectDrawPaletteImpl* palette;
IDirectDraw2Impl* ddraw; IDirectDraw2Impl* ddraw;
IDirectDrawSurface4Impl* backbuffer;
struct _surface_chain *chain;
DDSURFACEDESC surface_desc; DDSURFACEDESC surface_desc;
...@@ -233,6 +234,11 @@ struct IDirectDrawSurface4Impl ...@@ -233,6 +234,11 @@ struct IDirectDrawSurface4Impl
} t; } t;
} ; } ;
struct _surface_chain {
IDirectDrawSurface4Impl **surfaces;
int nrofsurfaces;
};
/***************************************************************************** /*****************************************************************************
* IDirectDrawColorControl implementation structure * IDirectDrawColorControl implementation structure
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment