Added support for DirectDraw overlays using the XVideo extension.
This commit is contained in:
parent
dc71c0c954
commit
fc67be9a01
@ -267,7 +267,7 @@ static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lp
|
|||||||
void *img_data;
|
void *img_data;
|
||||||
int bpp = PFGET_BPP(This->d->directdraw_pixelformat);
|
int bpp = PFGET_BPP(This->d->directdraw_pixelformat);
|
||||||
int screen_bpp = PFGET_BPP(This->d->screen_pixelformat);
|
int screen_bpp = PFGET_BPP(This->d->screen_pixelformat);
|
||||||
|
|
||||||
#ifdef HAVE_LIBXXSHM
|
#ifdef HAVE_LIBXXSHM
|
||||||
if (ddpriv->xshm_active)
|
if (ddpriv->xshm_active)
|
||||||
img = create_xshmimage(This, lpdsf);
|
img = create_xshmimage(This, lpdsf);
|
||||||
@ -318,6 +318,164 @@ static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lp
|
|||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_XVIDEO
|
||||||
|
#ifdef HAVE_LIBXXSHM
|
||||||
|
static XvImage *create_xvshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
|
||||||
|
DSPRIVATE(lpdsf);
|
||||||
|
DDPRIVATE(This);
|
||||||
|
XvImage *img;
|
||||||
|
int (*WineXHandler)(Display *, XErrorEvent *);
|
||||||
|
|
||||||
|
img = TSXvShmCreateImage(display,
|
||||||
|
ddpriv->port_id,
|
||||||
|
(int) lpdsf->s.surface_desc.ddpfPixelFormat.dwFourCC,
|
||||||
|
NULL,
|
||||||
|
lpdsf->s.surface_desc.dwWidth,
|
||||||
|
lpdsf->s.surface_desc.dwHeight,
|
||||||
|
&(dspriv->shminfo));
|
||||||
|
|
||||||
|
if (img == NULL) {
|
||||||
|
FIXME("Couldn't create XShm XvImage (due to X11 remote display or failure).\nReverting to standard X images !\n");
|
||||||
|
ddpriv->xshm_active = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dspriv->shminfo.shmid = shmget( IPC_PRIVATE, img->data_size, IPC_CREAT|0777 );
|
||||||
|
|
||||||
|
if (dspriv->shminfo.shmid < 0) {
|
||||||
|
FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
|
||||||
|
ddpriv->xshm_active = 0;
|
||||||
|
TSXFree(img);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dspriv->shminfo.shmaddr=img->data=(char*)shmat(dspriv->shminfo.shmid,0,0);
|
||||||
|
|
||||||
|
if (img->data == (char *) -1) {
|
||||||
|
FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
|
||||||
|
ddpriv->xshm_active = 0;
|
||||||
|
TSXFree(img);
|
||||||
|
shmctl(dspriv->shminfo.shmid, IPC_RMID, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dspriv->shminfo.readOnly = False;
|
||||||
|
|
||||||
|
/* This is where things start to get trickier....
|
||||||
|
* First, we flush the current X connections to be sure to catch all
|
||||||
|
* non-XShm related errors
|
||||||
|
*/
|
||||||
|
TSXSync(display, False);
|
||||||
|
/* Then we enter in the non-thread safe part of the tests */
|
||||||
|
EnterCriticalSection( &X11DRV_CritSection );
|
||||||
|
|
||||||
|
/* Reset the error flag, sets our new error handler and try to attach
|
||||||
|
* the surface
|
||||||
|
*/
|
||||||
|
XShmErrorFlag = 0;
|
||||||
|
WineXHandler = XSetErrorHandler(XShmErrorHandler);
|
||||||
|
XShmAttach(display, &(dspriv->shminfo));
|
||||||
|
XSync(display, False);
|
||||||
|
|
||||||
|
/* Check the error flag */
|
||||||
|
if (XShmErrorFlag) {
|
||||||
|
/* An error occured */
|
||||||
|
XFlush(display);
|
||||||
|
XShmErrorFlag = 0;
|
||||||
|
XFree(img);
|
||||||
|
shmdt(dspriv->shminfo.shmaddr);
|
||||||
|
shmctl(dspriv->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");
|
||||||
|
ddpriv->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);
|
||||||
|
LeaveCriticalSection( &X11DRV_CritSection );
|
||||||
|
|
||||||
|
shmctl(dspriv->shminfo.shmid, IPC_RMID, 0);
|
||||||
|
|
||||||
|
lpdsf->s.surface_desc.u1.lpSurface = img->data;
|
||||||
|
VirtualAlloc(img->data, img->data_size, MEM_RESERVE|MEM_SYSTEM, PAGE_READWRITE);
|
||||||
|
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static XvImage *create_xvimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf, HRESULT *err_code) {
|
||||||
|
XvImage *img = NULL;
|
||||||
|
DDPRIVATE(This);
|
||||||
|
void *img_data;
|
||||||
|
XvImageFormatValues *fo;
|
||||||
|
int formats, i;
|
||||||
|
int bpp = PFGET_BPP(lpdsf->s.surface_desc.ddpfPixelFormat);
|
||||||
|
|
||||||
|
*err_code = DDERR_OUTOFVIDEOMEMORY;
|
||||||
|
|
||||||
|
if (!(lpdsf->s.surface_desc.ddpfPixelFormat.dwFlags & DDPF_FOURCC)) {
|
||||||
|
/* Hmmm, overlay without FOURCC code.. Baaaaaad */
|
||||||
|
ERR("Overlay without a FOURCC pixel format !\n");
|
||||||
|
*err_code = DDERR_INVALIDPIXELFORMAT;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First, find out if we support this PixelFormat.
|
||||||
|
I make the assumption here that the id of the XvImage format is the
|
||||||
|
same as the Windows FOURCC code. */
|
||||||
|
fo = TSXvListImageFormats(display, ddpriv->port_id, &formats);
|
||||||
|
for (i = 0; i < formats; i++)
|
||||||
|
if (fo[i].id == lpdsf->s.surface_desc.ddpfPixelFormat.dwFourCC) break;
|
||||||
|
if (fo)
|
||||||
|
TSXFree(fo);
|
||||||
|
|
||||||
|
if (i == formats) {
|
||||||
|
ERR("FOURCC code not supported by the video card !\n");
|
||||||
|
*err_code = DDERR_INVALIDPIXELFORMAT;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBXXSHM
|
||||||
|
if (ddpriv->xshm_active)
|
||||||
|
img = create_xvshmimage(This, lpdsf);
|
||||||
|
|
||||||
|
if (img == NULL) {
|
||||||
|
#endif
|
||||||
|
/* Allocate surface memory */
|
||||||
|
lpdsf->s.surface_desc.u1.lpSurface =
|
||||||
|
VirtualAlloc(NULL,
|
||||||
|
lpdsf->s.surface_desc.dwWidth *
|
||||||
|
lpdsf->s.surface_desc.dwHeight *
|
||||||
|
bpp,
|
||||||
|
MEM_RESERVE | MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
img_data = lpdsf->s.surface_desc.u1.lpSurface;
|
||||||
|
|
||||||
|
/* In this case, create an XvImage */
|
||||||
|
img = TSXvCreateImage(display,
|
||||||
|
ddpriv->port_id,
|
||||||
|
(int) lpdsf->s.surface_desc.ddpfPixelFormat.dwFourCC,
|
||||||
|
img_data,
|
||||||
|
lpdsf->s.surface_desc.dwWidth,
|
||||||
|
lpdsf->s.surface_desc.dwHeight);
|
||||||
|
#ifdef HAVE_LIBXXSHM
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
lpdsf->s.surface_desc.lPitch = ((XvImage *) img)->pitches[0];
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static XvImage *create_xvimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf, HRESULT *err_code) {
|
||||||
|
*err_code = DDERR_INVALIDPIXELFORMAT;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
|
static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
|
||||||
LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,
|
LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,
|
||||||
IUnknown *lpunk
|
IUnknown *lpunk
|
||||||
@ -350,7 +508,8 @@ static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
|
|||||||
|
|
||||||
dsurf->s.palette = NULL;
|
dsurf->s.palette = NULL;
|
||||||
dsurf->s.lpClipper = NULL;
|
dsurf->s.lpClipper = NULL;
|
||||||
dspriv->image = NULL; /* This is for off-screen buffers */
|
dspriv->is_overlay = FALSE;
|
||||||
|
dspriv->info.image = NULL; /* This is for off-screen buffers */
|
||||||
|
|
||||||
/* Copy the surface description */
|
/* Copy the surface description */
|
||||||
dsurf->s.surface_desc = *lpddsd;
|
dsurf->s.surface_desc = *lpddsd;
|
||||||
@ -361,30 +520,43 @@ static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
|
|||||||
dsurf->s.surface_desc.dwHeight = This->d->height;
|
dsurf->s.surface_desc.dwHeight = This->d->height;
|
||||||
dsurf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
|
dsurf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
|
||||||
|
|
||||||
/* Check if this a 'primary surface' or not */
|
/* Check if this a 'primary surface' or an overlay */
|
||||||
if ((lpddsd->dwFlags & DDSD_CAPS) &&
|
if ((lpddsd->dwFlags & DDSD_CAPS) &&
|
||||||
(lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
|
((lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) ||
|
||||||
|
(lpddsd->ddsCaps.dwCaps & DDSCAPS_OVERLAY))
|
||||||
) {
|
) {
|
||||||
XImage *img;
|
|
||||||
|
|
||||||
/* Add flags if there were not present */
|
/* Add flags if there were not present */
|
||||||
dsurf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
|
dsurf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
|
||||||
dsurf->s.surface_desc.dwWidth = This->d->width;
|
dsurf->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
|
||||||
dsurf->s.surface_desc.dwHeight = This->d->height;
|
|
||||||
dsurf->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
|
|
||||||
dsurf->s.surface_desc.ddpfPixelFormat = This->d->directdraw_pixelformat;
|
|
||||||
|
|
||||||
TRACE("using standard XImage for a primary surface (%p)\n", dsurf);
|
if (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) {
|
||||||
/* Create the XImage */
|
dsurf->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
|
||||||
img = create_ximage(This,(IDirectDrawSurface4Impl*)dsurf);
|
dsurf->s.surface_desc.ddpfPixelFormat = This->d->directdraw_pixelformat;
|
||||||
if (img == NULL)
|
dsurf->s.surface_desc.dwWidth = This->d->width;
|
||||||
|
dsurf->s.surface_desc.dwHeight = This->d->height;
|
||||||
|
} else {
|
||||||
|
dspriv->is_overlay = TRUE;
|
||||||
|
/* In the case of Overlay surfaces, copy the one provided by the application */
|
||||||
|
dsurf->s.surface_desc.ddpfPixelFormat = lpddsd->ddpfPixelFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpddsd->ddsCaps.dwCaps & DDSCAPS_OVERLAY) {
|
||||||
|
HRESULT err_code;
|
||||||
|
TRACE("using an XvImage for the overlay (%p)\n", dsurf);
|
||||||
|
dspriv->info.overlay.image = create_xvimage(This,(IDirectDrawSurface4Impl*)dsurf, &err_code);
|
||||||
|
if (dspriv->info.overlay.image == NULL)
|
||||||
|
return err_code;
|
||||||
|
} else {
|
||||||
|
TRACE("using standard XImage for a primary surface (%p)\n", dsurf);
|
||||||
|
/* Create the XImage */
|
||||||
|
dspriv->info.image = create_ximage(This,(IDirectDrawSurface4Impl*)dsurf);
|
||||||
|
if (dspriv->info.image == NULL)
|
||||||
return DDERR_OUTOFMEMORY;
|
return DDERR_OUTOFMEMORY;
|
||||||
dspriv->image = img;
|
}
|
||||||
|
|
||||||
/* Check for backbuffers */
|
/* Check for backbuffers */
|
||||||
if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
|
if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
|
||||||
IDirectDrawSurface4Impl* back;
|
IDirectDrawSurface4Impl* back;
|
||||||
XImage *img;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=lpddsd->dwBackBufferCount;i--;) {
|
for (i=lpddsd->dwBackBufferCount;i--;) {
|
||||||
@ -413,11 +585,18 @@ static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
|
|||||||
bspriv = (x11_ds_private*)back->private;
|
bspriv = (x11_ds_private*)back->private;
|
||||||
|
|
||||||
/* Create the XImage. */
|
/* Create the XImage. */
|
||||||
img = create_ximage(This, back);
|
if (lpddsd->ddsCaps.dwCaps & DDSCAPS_OVERLAY) {
|
||||||
if (img == NULL)
|
HRESULT err_code;
|
||||||
|
dspriv->is_overlay = TRUE;
|
||||||
|
bspriv->info.overlay.image = create_xvimage(This, back, &err_code);
|
||||||
|
if (bspriv->info.overlay.image == NULL)
|
||||||
|
return err_code;
|
||||||
|
} else {
|
||||||
|
bspriv->info.image = create_ximage(This, back);
|
||||||
|
if (bspriv->info.image == NULL)
|
||||||
return DDERR_OUTOFMEMORY;
|
return DDERR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
TRACE("bspriv = %p\n",bspriv);
|
TRACE("bspriv = %p\n",bspriv);
|
||||||
bspriv->image = img;
|
|
||||||
|
|
||||||
/* Add relevant info to front and back buffers */
|
/* Add relevant info to front and back buffers */
|
||||||
/* FIXME: backbuffer/frontbuffer handling broken here, but
|
/* FIXME: backbuffer/frontbuffer handling broken here, but
|
||||||
@ -521,7 +700,7 @@ static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
|
|||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fill_caps(LPDDCAPS caps) {
|
static void fill_caps(LPDDCAPS caps, x11_dd_private *x11ddp) {
|
||||||
/* This function tries to fill the capabilities of Wine's DDraw implementation.
|
/* This function tries to fill the capabilities of Wine's DDraw implementation.
|
||||||
Need to be fixed, though.. */
|
Need to be fixed, though.. */
|
||||||
if (caps == NULL)
|
if (caps == NULL)
|
||||||
@ -545,24 +724,39 @@ static void fill_caps(LPDDCAPS caps) {
|
|||||||
/* These are all the supported capabilities of the surfaces */
|
/* These are all the supported capabilities of the surfaces */
|
||||||
caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
|
caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
|
||||||
DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
|
DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
|
||||||
/*DDSCAPS_OVERLAY |*/ DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
|
DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
|
||||||
DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
|
DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
|
||||||
#ifdef HAVE_OPENGL
|
#ifdef HAVE_OPENGL
|
||||||
caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
|
caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
|
||||||
caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
|
caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
|
||||||
caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
|
caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_XVIDEO
|
||||||
|
if (x11ddp->xvideo_active) {
|
||||||
|
caps->dwCaps |= DDCAPS_OVERLAY | DDCAPS_OVERLAYFOURCC | DDCAPS_OVERLAYSTRETCH | DDCAPS_BLTFOURCC;
|
||||||
|
caps->dwCaps2 |= DDCAPS2_VIDEOPORT;
|
||||||
|
caps->dwMaxVisibleOverlays = 16;
|
||||||
|
caps->dwCurrVisibleOverlays = 0;
|
||||||
|
caps->dwMinOverlayStretch = 1; /* Apparently there is no 'down' stretching in XVideo, but well, Windows
|
||||||
|
Media player refuses to work when I put 1000 here :-/ */
|
||||||
|
caps->dwMaxOverlayStretch = 100000; /* This is a 'bogus' value, I do not know the maximum stretching */
|
||||||
|
TSXvListImageFormats(display, x11ddp->port_id, (unsigned int *) &(caps->dwNumFourCCCodes));
|
||||||
|
caps->ddsCaps.dwCaps |= DDSCAPS_OVERLAY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
|
static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
|
||||||
LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
|
LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
|
||||||
) {
|
) {
|
||||||
ICOM_THIS(IDirectDraw2Impl,iface);
|
ICOM_THIS(IDirectDraw2Impl,iface);
|
||||||
|
DDPRIVATE(This);
|
||||||
TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
|
TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
|
||||||
|
|
||||||
/* Put the same caps for the two capabilities */
|
/* Put the same caps for the two capabilities */
|
||||||
fill_caps(caps1);
|
fill_caps(caps1, ddpriv);
|
||||||
fill_caps(caps2);
|
fill_caps(caps2, ddpriv);
|
||||||
|
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
@ -843,6 +1037,18 @@ static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
|
|||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI Xlib_IDirectDraw2Impl_GetFourCCCodes(
|
||||||
|
LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
|
||||||
|
) {
|
||||||
|
#ifdef HAVE_XVIDEO
|
||||||
|
ICOM_THIS(IDirectDraw2Impl,iface);
|
||||||
|
FIXME("(%p,%p,%p), stub\n",This,x,y);
|
||||||
|
return DD_OK;
|
||||||
|
#else
|
||||||
|
return IDirectDraw2Impl_GetFourCCCodes(iface, x, y);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Note: Hack so we can reuse the old functions without compiler warnings */
|
/* Note: Hack so we can reuse the old functions without compiler warnings */
|
||||||
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
|
#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
|
||||||
# define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
|
# define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
|
||||||
@ -865,7 +1071,7 @@ ICOM_VTABLE(IDirectDraw) xlib_ddvt = {
|
|||||||
XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
|
XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
|
||||||
XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
|
XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
|
||||||
XCAST(GetDisplayMode)IDirectDraw2Impl_GetDisplayMode,
|
XCAST(GetDisplayMode)IDirectDraw2Impl_GetDisplayMode,
|
||||||
XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
|
XCAST(GetFourCCCodes)Xlib_IDirectDraw2Impl_GetFourCCCodes,
|
||||||
XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
|
XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
|
||||||
XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
|
XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
|
||||||
XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
|
XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
|
||||||
@ -916,7 +1122,7 @@ ICOM_VTABLE(IDirectDraw2) xlib_dd2vt = {
|
|||||||
IDirectDraw2Impl_FlipToGDISurface,
|
IDirectDraw2Impl_FlipToGDISurface,
|
||||||
Xlib_IDirectDraw2Impl_GetCaps,
|
Xlib_IDirectDraw2Impl_GetCaps,
|
||||||
IDirectDraw2Impl_GetDisplayMode,
|
IDirectDraw2Impl_GetDisplayMode,
|
||||||
IDirectDraw2Impl_GetFourCCCodes,
|
Xlib_IDirectDraw2Impl_GetFourCCCodes,
|
||||||
IDirectDraw2Impl_GetGDISurface,
|
IDirectDraw2Impl_GetGDISurface,
|
||||||
IDirectDraw2Impl_GetMonitorFrequency,
|
IDirectDraw2Impl_GetMonitorFrequency,
|
||||||
IDirectDraw2Impl_GetScanLine,
|
IDirectDraw2Impl_GetScanLine,
|
||||||
@ -950,7 +1156,7 @@ ICOM_VTABLE(IDirectDraw4) xlib_dd4vt = {
|
|||||||
XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
|
XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
|
||||||
XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
|
XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
|
||||||
XCAST(GetDisplayMode)IDirectDraw2Impl_GetDisplayMode,
|
XCAST(GetDisplayMode)IDirectDraw2Impl_GetDisplayMode,
|
||||||
XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
|
XCAST(GetFourCCCodes)Xlib_IDirectDraw2Impl_GetFourCCCodes,
|
||||||
XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
|
XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
|
||||||
XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
|
XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
|
||||||
XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
|
XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
|
||||||
|
@ -402,4 +402,5 @@ extern void _dump_surface_desc(DDSURFACEDESC *lpddsd);
|
|||||||
extern void _dump_cooperativelevel(DWORD cooplevel);
|
extern void _dump_cooperativelevel(DWORD cooplevel);
|
||||||
extern void _dump_surface_desc(DDSURFACEDESC *lpddsd);
|
extern void _dump_surface_desc(DDSURFACEDESC *lpddsd);
|
||||||
extern void _dump_DDCOLORKEY(void *in);
|
extern void _dump_DDCOLORKEY(void *in);
|
||||||
|
extern void _dump_DDOVERLAY(DWORD flagmask) ;
|
||||||
#endif /* __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H */
|
#endif /* __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H */
|
||||||
|
@ -133,7 +133,7 @@ HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Lock(
|
|||||||
assert(This->s.surface_desc.u1.lpSurface);
|
assert(This->s.surface_desc.u1.lpSurface);
|
||||||
/* wait for any previous operations to complete */
|
/* wait for any previous operations to complete */
|
||||||
#ifdef HAVE_LIBXXSHM
|
#ifdef HAVE_LIBXXSHM
|
||||||
if (dspriv->image && VISIBLE(This) && ddpriv->xshm_active) {
|
if (dspriv->info.image && VISIBLE(This) && ddpriv->xshm_active) {
|
||||||
/*
|
/*
|
||||||
int compl = InterlockedExchange( &(ddpriv->xshm_compl), 0 );
|
int compl = InterlockedExchange( &(ddpriv->xshm_compl), 0 );
|
||||||
if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
|
if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
|
||||||
@ -144,7 +144,7 @@ HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Lock(
|
|||||||
|
|
||||||
/* If part of a visible 'clipped' surface, copy what is seen on the
|
/* If part of a visible 'clipped' surface, copy what is seen on the
|
||||||
screen to the surface */
|
screen to the surface */
|
||||||
if ((dspriv->image && VISIBLE(This)) &&
|
if ((dspriv->info.image && VISIBLE(This)) &&
|
||||||
(This->s.lpClipper)) {
|
(This->s.lpClipper)) {
|
||||||
HWND hWnd = ((IDirectDrawClipperImpl *) This->s.lpClipper)->hWnd;
|
HWND hWnd = ((IDirectDrawClipperImpl *) This->s.lpClipper)->hWnd;
|
||||||
WND *wndPtr = WIN_FindWndPtr(hWnd);
|
WND *wndPtr = WIN_FindWndPtr(hWnd);
|
||||||
@ -164,7 +164,7 @@ HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Lock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
TSXGetSubImage(display, drawable, 0, 0, width, height, 0xFFFFFFFF,
|
TSXGetSubImage(display, drawable, 0, 0, width, height, 0xFFFFFFFF,
|
||||||
ZPixmap, dspriv->image, dest_x, dest_y);
|
ZPixmap, dspriv->info.image, dest_x, dest_y);
|
||||||
|
|
||||||
WIN_ReleaseWndPtr(wndPtr);
|
WIN_ReleaseWndPtr(wndPtr);
|
||||||
}
|
}
|
||||||
@ -180,8 +180,8 @@ static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
|
|||||||
SIZE imgsiz;
|
SIZE imgsiz;
|
||||||
|
|
||||||
/* Get XImage size */
|
/* Get XImage size */
|
||||||
imgsiz.cx = dspriv->image->width;
|
imgsiz.cx = dspriv->info.image->width;
|
||||||
imgsiz.cy = dspriv->image->height;
|
imgsiz.cy = dspriv->info.image->height;
|
||||||
|
|
||||||
if (This->s.lpClipper) {
|
if (This->s.lpClipper) {
|
||||||
HWND hWnd = ((IDirectDrawClipperImpl *) This->s.lpClipper)->hWnd;
|
HWND hWnd = ((IDirectDrawClipperImpl *) This->s.lpClipper)->hWnd;
|
||||||
@ -225,7 +225,7 @@ static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
|
|||||||
|
|
||||||
if (This->s.ddraw->d->pixel_convert != NULL)
|
if (This->s.ddraw->d->pixel_convert != NULL)
|
||||||
This->s.ddraw->d->pixel_convert(This->s.surface_desc.u1.lpSurface,
|
This->s.ddraw->d->pixel_convert(This->s.surface_desc.u1.lpSurface,
|
||||||
dspriv->image->data,
|
dspriv->info.image->data,
|
||||||
This->s.surface_desc.dwWidth,
|
This->s.surface_desc.dwWidth,
|
||||||
This->s.surface_desc.dwHeight,
|
This->s.surface_desc.dwHeight,
|
||||||
This->s.surface_desc.lPitch,
|
This->s.surface_desc.lPitch,
|
||||||
@ -233,7 +233,7 @@ static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
|
|||||||
|
|
||||||
/* if the DIB section is in GdiMod state, we must
|
/* if the DIB section is in GdiMod state, we must
|
||||||
* touch the surface to get any updates from the DIB */
|
* touch the surface to get any updates from the DIB */
|
||||||
Xlib_TouchData(dspriv->image->data);
|
Xlib_TouchData(dspriv->info.image->data);
|
||||||
#ifdef HAVE_LIBXXSHM
|
#ifdef HAVE_LIBXXSHM
|
||||||
if (ddpriv->xshm_active) {
|
if (ddpriv->xshm_active) {
|
||||||
/*
|
/*
|
||||||
@ -246,7 +246,7 @@ static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
|
|||||||
TSXShmPutImage(display,
|
TSXShmPutImage(display,
|
||||||
drawable,
|
drawable,
|
||||||
DefaultGCOfScreen(X11DRV_GetXScreen()),
|
DefaultGCOfScreen(X11DRV_GetXScreen()),
|
||||||
dspriv->image,
|
dspriv->info.image,
|
||||||
adjust[0].x, adjust[0].y, adjust[1].x, adjust[1].y,
|
adjust[0].x, adjust[0].y, adjust[1].x, adjust[1].y,
|
||||||
imgsiz.cx, imgsiz.cy,
|
imgsiz.cx, imgsiz.cy,
|
||||||
True
|
True
|
||||||
@ -258,7 +258,7 @@ static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
|
|||||||
TSXPutImage(display,
|
TSXPutImage(display,
|
||||||
drawable,
|
drawable,
|
||||||
DefaultGCOfScreen(X11DRV_GetXScreen()),
|
DefaultGCOfScreen(X11DRV_GetXScreen()),
|
||||||
dspriv->image,
|
dspriv->info.image,
|
||||||
adjust[0].x, adjust[0].y, adjust[1].x, adjust[1].y,
|
adjust[0].x, adjust[0].y, adjust[1].x, adjust[1].y,
|
||||||
imgsiz.cx, imgsiz.cy
|
imgsiz.cx, imgsiz.cy
|
||||||
);
|
);
|
||||||
@ -276,7 +276,7 @@ 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 (dspriv->image && VISIBLE(This)) {
|
if (dspriv->info.image && VISIBLE(This)) {
|
||||||
Xlib_copy_surface_on_screen(This);
|
Xlib_copy_surface_on_screen(This);
|
||||||
if (This->s.palette) {
|
if (This->s.palette) {
|
||||||
DPPRIVATE(This->s.palette);
|
DPPRIVATE(This->s.palette);
|
||||||
@ -289,6 +289,56 @@ HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
|
|||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_XVIDEO
|
||||||
|
static void Xlib_copy_overlay_on_screen(IDirectDrawSurface4Impl* This) {
|
||||||
|
DSPRIVATE(This);
|
||||||
|
DDPRIVATE(This->s.ddraw);
|
||||||
|
Drawable drawable = ddpriv->drawable;
|
||||||
|
|
||||||
|
if (!drawable) {
|
||||||
|
WND *tmpWnd = WIN_FindWndPtr(This->s.ddraw->d->window);
|
||||||
|
drawable = X11DRV_WND_GetXWindow(tmpWnd);
|
||||||
|
WIN_ReleaseWndPtr(tmpWnd);
|
||||||
|
|
||||||
|
/* We don't have a context for this window. Host off the desktop */
|
||||||
|
if( !drawable ) {
|
||||||
|
FIXME("Have to use Desktop Root Window??? Bummer.\n");
|
||||||
|
drawable = X11DRV_WND_GetXWindow(WIN_GetDesktop());
|
||||||
|
WIN_ReleaseDesktop();
|
||||||
|
}
|
||||||
|
ddpriv->drawable = drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBXXSHM
|
||||||
|
if (ddpriv->xshm_active) {
|
||||||
|
/* let WaitShmCompletions track 'em for now */
|
||||||
|
/* (you may want to track it again whenever you implement DX7's partial
|
||||||
|
* surface locking, where threads have concurrent access) */
|
||||||
|
X11DRV_EVENT_PrepareShmCompletion( ddpriv->drawable );
|
||||||
|
TSXvShmPutImage(display, ddpriv->port_id, drawable, DefaultGCOfScreen(X11DRV_GetXScreen()),
|
||||||
|
dspriv->info.overlay.image,
|
||||||
|
dspriv->info.overlay.src_rect.left, dspriv->info.overlay.src_rect.top,
|
||||||
|
dspriv->info.overlay.src_rect.right - dspriv->info.overlay.src_rect.left,
|
||||||
|
dspriv->info.overlay.src_rect.bottom - dspriv->info.overlay.src_rect.top,
|
||||||
|
dspriv->info.overlay.dst_rect.left, dspriv->info.overlay.dst_rect.top,
|
||||||
|
dspriv->info.overlay.dst_rect.right - dspriv->info.overlay.dst_rect.left,
|
||||||
|
dspriv->info.overlay.dst_rect.bottom - dspriv->info.overlay.dst_rect.top,
|
||||||
|
True);
|
||||||
|
/* make sure the image is transferred ASAP */
|
||||||
|
TSXFlush(display);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
TSXvPutImage(display, ddpriv->port_id, drawable, DefaultGCOfScreen(X11DRV_GetXScreen()),
|
||||||
|
dspriv->info.overlay.image,
|
||||||
|
dspriv->info.overlay.src_rect.left, dspriv->info.overlay.src_rect.top,
|
||||||
|
dspriv->info.overlay.src_rect.right - dspriv->info.overlay.src_rect.left,
|
||||||
|
dspriv->info.overlay.src_rect.bottom - dspriv->info.overlay.src_rect.top,
|
||||||
|
dspriv->info.overlay.dst_rect.left, dspriv->info.overlay.dst_rect.top,
|
||||||
|
dspriv->info.overlay.dst_rect.right - dspriv->info.overlay.dst_rect.left,
|
||||||
|
dspriv->info.overlay.dst_rect.bottom - dspriv->info.overlay.dst_rect.top);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
|
HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
|
||||||
LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
|
LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
|
||||||
) {
|
) {
|
||||||
@ -301,9 +351,9 @@ HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
|
|||||||
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);
|
||||||
if (!This->s.ddraw->d->paintable)
|
if ((!This->s.ddraw->d->paintable) && (dspriv->is_overlay == FALSE))
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
|
|
||||||
iflipto = _common_find_flipto(This,iflipto);
|
iflipto = _common_find_flipto(This,iflipto);
|
||||||
fspriv = (x11_ds_private*)iflipto->private;
|
fspriv = (x11_ds_private*)iflipto->private;
|
||||||
|
|
||||||
@ -313,16 +363,28 @@ HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
|
|||||||
This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
|
This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
|
||||||
iflipto->s.surface_desc.u1.lpSurface = surf;
|
iflipto->s.surface_desc.u1.lpSurface = surf;
|
||||||
|
|
||||||
/* the associated ximage */
|
/* the associated ximage
|
||||||
image = dspriv->image;
|
|
||||||
dspriv->image = fspriv->image;
|
NOTE : for XVideo, the pointer to the XvImage is at the same position
|
||||||
fspriv->image = image;
|
in memory than the standard XImage. This means that this code
|
||||||
|
still works :-)
|
||||||
|
*/
|
||||||
|
image = dspriv->info.image;
|
||||||
|
dspriv->info.image = fspriv->info.image;
|
||||||
|
fspriv->info.image = image;
|
||||||
|
|
||||||
if (dspriv->opengl_flip) {
|
if (dspriv->opengl_flip) {
|
||||||
#ifdef HAVE_OPENGL
|
#ifdef HAVE_OPENGL
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
glXSwapBuffers(display, ddpriv->drawable);
|
glXSwapBuffers(display, ddpriv->drawable);
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
|
#endif
|
||||||
|
} else if (dspriv->is_overlay) {
|
||||||
|
#ifdef HAVE_XVIDEO
|
||||||
|
if (dspriv->info.overlay.shown)
|
||||||
|
Xlib_copy_overlay_on_screen(This);
|
||||||
|
#else
|
||||||
|
ERR("Why was this code activated WITHOUT XVideo support ?\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifdef HAVE_LIBXXSHM
|
#ifdef HAVE_LIBXXSHM
|
||||||
@ -432,24 +494,32 @@ ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
|
|||||||
VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE);
|
VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE);
|
||||||
|
|
||||||
/* Now free the XImages and the respective screen-side surfaces */
|
/* Now free the XImages and the respective screen-side surfaces */
|
||||||
if (dspriv->image != NULL) {
|
if (dspriv->info.image != NULL) {
|
||||||
if (dspriv->image->data != This->s.surface_desc.u1.lpSurface)
|
if (dspriv->info.image->data != This->s.surface_desc.u1.lpSurface)
|
||||||
VirtualFree(dspriv->image->data, 0, MEM_RELEASE);
|
VirtualFree(dspriv->info.image->data, 0, MEM_RELEASE);
|
||||||
#ifdef HAVE_LIBXXSHM
|
#ifdef HAVE_LIBXXSHM
|
||||||
if (ddpriv->xshm_active) {
|
if (ddpriv->xshm_active) {
|
||||||
TSXShmDetach(display, &(dspriv->shminfo));
|
TSXShmDetach(display, &(dspriv->shminfo));
|
||||||
TSXDestroyImage(dspriv->image);
|
if (This->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_OVERLAY) {
|
||||||
|
TSXFree(dspriv->info.image);
|
||||||
|
} else {
|
||||||
|
TSXDestroyImage(dspriv->info.image);
|
||||||
|
}
|
||||||
shmdt(dspriv->shminfo.shmaddr);
|
shmdt(dspriv->shminfo.shmaddr);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
if (This->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_OVERLAY) {
|
||||||
|
TSXFree(dspriv->info.image);
|
||||||
|
} else {
|
||||||
/* normal X Image memory was never allocated by X, but always by
|
/* normal X Image memory was never allocated by X, but always by
|
||||||
* ourselves -> Don't let X free our imagedata.
|
* ourselves -> Don't let X free our imagedata.
|
||||||
*/
|
*/
|
||||||
dspriv->image->data = NULL;
|
dspriv->info.image->data = NULL;
|
||||||
TSXDestroyImage(dspriv->image);
|
TSXDestroyImage(dspriv->info.image);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dspriv->image = 0;
|
dspriv->info.image = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (This->s.palette)
|
if (This->s.palette)
|
||||||
@ -492,6 +562,108 @@ HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_XVIDEO
|
||||||
|
typedef struct {
|
||||||
|
BOOL shown;
|
||||||
|
LPRECT src_rect;
|
||||||
|
LPRECT dst_rect;
|
||||||
|
LPDIRECTDRAWSURFACE dest_surface;
|
||||||
|
} UpdateOverlayEnumerate;
|
||||||
|
|
||||||
|
static HRESULT WINAPI enum_func(LPDIRECTDRAWSURFACE lpDDSurface,
|
||||||
|
LPDDSURFACEDESC lpDDSurfaceDesc,
|
||||||
|
LPVOID lpContext) {
|
||||||
|
ICOM_THIS(IDirectDrawSurface4Impl,lpDDSurface);
|
||||||
|
DSPRIVATE(This);
|
||||||
|
UpdateOverlayEnumerate *ctx = (UpdateOverlayEnumerate *) lpContext;
|
||||||
|
|
||||||
|
if ((lpDDSurfaceDesc->ddsCaps.dwCaps) & DDSCAPS_BACKBUFFER) {
|
||||||
|
TRACE("Upgrading surface %p\n", lpDDSurface);
|
||||||
|
|
||||||
|
if (ctx->shown) {
|
||||||
|
dspriv->info.overlay.shown = TRUE;
|
||||||
|
dspriv->info.overlay.src_rect = *(ctx->src_rect);
|
||||||
|
dspriv->info.overlay.dst_rect = *(ctx->dst_rect);
|
||||||
|
dspriv->info.overlay.dest_surface = ctx->dest_surface;
|
||||||
|
} else {
|
||||||
|
dspriv->info.overlay.shown = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DDENUMRET_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_UpdateOverlay(
|
||||||
|
LPDIRECTDRAWSURFACE4 iface, LPRECT lpSrcRect,
|
||||||
|
LPDIRECTDRAWSURFACE4 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags,
|
||||||
|
LPDDOVERLAYFX lpDDOverlayFx
|
||||||
|
) {
|
||||||
|
ICOM_THIS(IDirectDrawSurface4Impl,iface);
|
||||||
|
#ifdef HAVE_XVIDEO
|
||||||
|
DSPRIVATE(This);
|
||||||
|
DDPRIVATE(This->s.ddraw);
|
||||||
|
|
||||||
|
if (ddpriv->xvideo_active) {
|
||||||
|
TRACE("(%p)->(%p,%p,%p,0x%08lx,%p)\n", This,
|
||||||
|
lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
|
||||||
|
|
||||||
|
if (TRACE_ON(ddraw)) {
|
||||||
|
DPRINTF(" - dwFlags : ");
|
||||||
|
_dump_DDOVERLAY(dwFlags);
|
||||||
|
|
||||||
|
if (lpSrcRect) DPRINTF(" - src rectangle :%dx%d-%dx%d\n",lpSrcRect->left,lpSrcRect->top,
|
||||||
|
lpSrcRect->right,lpSrcRect->bottom);
|
||||||
|
if (lpDestRect) DPRINTF(" - dest rectangle :%dx%d-%dx%d\n",lpDestRect->left,lpDestRect->top,
|
||||||
|
lpDestRect->right,lpDestRect->bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwFlags & DDOVER_SHOW) {
|
||||||
|
UpdateOverlayEnumerate ctx;
|
||||||
|
|
||||||
|
dwFlags &= ~DDOVER_SHOW;
|
||||||
|
|
||||||
|
if ((lpSrcRect == NULL) || (lpDestRect == NULL)) {
|
||||||
|
FIXME("This is NOT supported yet...\n");
|
||||||
|
return DD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the shown BOOL to TRUE and update the rectangles */
|
||||||
|
dspriv->info.overlay.shown = TRUE;
|
||||||
|
dspriv->info.overlay.src_rect = *lpSrcRect;
|
||||||
|
dspriv->info.overlay.dst_rect = *lpDestRect;
|
||||||
|
dspriv->info.overlay.dest_surface = (LPDIRECTDRAWSURFACE) lpDDDestSurface;
|
||||||
|
|
||||||
|
/* Now the same for the backbuffers */
|
||||||
|
ctx.shown = TRUE;
|
||||||
|
ctx.src_rect = lpSrcRect;
|
||||||
|
ctx.dst_rect = lpDestRect;
|
||||||
|
ctx.dest_surface = (LPDIRECTDRAWSURFACE) lpDDDestSurface;
|
||||||
|
|
||||||
|
IDirectDrawSurface4Impl_EnumAttachedSurfaces(iface, &ctx, enum_func);
|
||||||
|
} else if (dwFlags & DDOVER_HIDE) {
|
||||||
|
UpdateOverlayEnumerate ctx;
|
||||||
|
|
||||||
|
dwFlags &= ~DDOVER_HIDE;
|
||||||
|
|
||||||
|
/* Set the shown BOOL to FALSE for all overlays */
|
||||||
|
dspriv->info.overlay.shown = FALSE;
|
||||||
|
ctx.shown = FALSE;
|
||||||
|
IDirectDrawSurface4Impl_EnumAttachedSurfaces(iface, &ctx, enum_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwFlags && TRACE_ON(ddraw)) {
|
||||||
|
WARN("Unsupported flags : ");
|
||||||
|
_dump_DDOVERLAY(dwFlags);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
FIXME("(%p)->(%p,%p,%p,0x%08lx,%p) not supported without XVideo !\n", This,
|
||||||
|
lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
|
||||||
|
|
||||||
|
return DD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
|
ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
|
||||||
{
|
{
|
||||||
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
||||||
@ -528,7 +700,7 @@ ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
|
|||||||
IDirectDrawSurface4Impl_SetOverlayPosition,
|
IDirectDrawSurface4Impl_SetOverlayPosition,
|
||||||
Xlib_IDirectDrawSurface4Impl_SetPalette,
|
Xlib_IDirectDrawSurface4Impl_SetPalette,
|
||||||
Xlib_IDirectDrawSurface4Impl_Unlock,
|
Xlib_IDirectDrawSurface4Impl_Unlock,
|
||||||
IDirectDrawSurface4Impl_UpdateOverlay,
|
Xlib_IDirectDrawSurface4Impl_UpdateOverlay,
|
||||||
IDirectDrawSurface4Impl_UpdateOverlayDisplay,
|
IDirectDrawSurface4Impl_UpdateOverlayDisplay,
|
||||||
IDirectDrawSurface4Impl_UpdateOverlayZOrder,
|
IDirectDrawSurface4Impl_UpdateOverlayZOrder,
|
||||||
IDirectDrawSurface4Impl_GetDDInterface,
|
IDirectDrawSurface4Impl_GetDDInterface,
|
||||||
|
@ -51,6 +51,44 @@ void _dump_DDBLTFX(DWORD flagmask) {
|
|||||||
DPRINTF("\n");
|
DPRINTF("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _dump_DDOVERLAY(DWORD flagmask) {
|
||||||
|
int i;
|
||||||
|
const struct {
|
||||||
|
DWORD mask;
|
||||||
|
char *name;
|
||||||
|
} flags[] = {
|
||||||
|
#define FE(x) { x, #x},
|
||||||
|
FE(DDOVER_ALPHADEST)
|
||||||
|
FE(DDOVER_ALPHADESTCONSTOVERRIDE)
|
||||||
|
FE(DDOVER_ALPHADESTNEG)
|
||||||
|
FE(DDOVER_ALPHADESTSURFACEOVERRIDE)
|
||||||
|
FE(DDOVER_ALPHAEDGEBLEND)
|
||||||
|
FE(DDOVER_ALPHASRC)
|
||||||
|
FE(DDOVER_ALPHASRCCONSTOVERRIDE)
|
||||||
|
FE(DDOVER_ALPHASRCNEG)
|
||||||
|
FE(DDOVER_ALPHASRCSURFACEOVERRIDE)
|
||||||
|
FE(DDOVER_HIDE)
|
||||||
|
FE(DDOVER_KEYDEST)
|
||||||
|
FE(DDOVER_KEYDESTOVERRIDE)
|
||||||
|
FE(DDOVER_KEYSRC)
|
||||||
|
FE(DDOVER_KEYSRCOVERRIDE)
|
||||||
|
FE(DDOVER_SHOW)
|
||||||
|
FE(DDOVER_ADDDIRTYRECT)
|
||||||
|
FE(DDOVER_REFRESHDIRTYRECTS)
|
||||||
|
FE(DDOVER_REFRESHALL)
|
||||||
|
FE(DDOVER_DDFX)
|
||||||
|
FE(DDOVER_AUTOFLIP)
|
||||||
|
FE(DDOVER_BOB)
|
||||||
|
FE(DDOVER_OVERRIDEBOBWEAVE)
|
||||||
|
FE(DDOVER_INTERLEAVED)
|
||||||
|
#undef FE
|
||||||
|
};
|
||||||
|
for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
|
||||||
|
if (flags[i].mask & flagmask)
|
||||||
|
DPRINTF("%s ",flags[i].name);
|
||||||
|
DPRINTF("\n");
|
||||||
|
}
|
||||||
|
|
||||||
void _dump_DDBLTFAST(DWORD flagmask) {
|
void _dump_DDBLTFAST(DWORD flagmask) {
|
||||||
int i;
|
int i;
|
||||||
const struct {
|
const struct {
|
||||||
@ -216,12 +254,13 @@ void _dump_pixelformat(void *in) {
|
|||||||
DPRINTF("( ");
|
DPRINTF("( ");
|
||||||
_dump_pixelformat_flag(pf->dwFlags);
|
_dump_pixelformat_flag(pf->dwFlags);
|
||||||
if (pf->dwFlags & DDPF_FOURCC) {
|
if (pf->dwFlags & DDPF_FOURCC) {
|
||||||
DPRINTF(", dwFourCC (%08lx) : %c%c%c%c",
|
DPRINTF(", dwFourCC code '%c%c%c%c' (0x%08lx) - %ld bits per pixel",
|
||||||
pf->dwFourCC,
|
|
||||||
(unsigned char)( pf->dwFourCC &0xff),
|
(unsigned char)( pf->dwFourCC &0xff),
|
||||||
(unsigned char)((pf->dwFourCC>> 8)&0xff),
|
(unsigned char)((pf->dwFourCC>> 8)&0xff),
|
||||||
(unsigned char)((pf->dwFourCC>>16)&0xff),
|
(unsigned char)((pf->dwFourCC>>16)&0xff),
|
||||||
(unsigned char)((pf->dwFourCC>>24)&0xff)
|
(unsigned char)((pf->dwFourCC>>24)&0xff),
|
||||||
|
pf->dwFourCC,
|
||||||
|
pf->u.dwYUVBitCount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (pf->dwFlags & DDPF_RGB) {
|
if (pf->dwFlags & DDPF_RGB) {
|
||||||
|
@ -44,6 +44,64 @@ DDRAW_XSHM_Available(void) {
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_XVIDEO
|
||||||
|
static BOOL
|
||||||
|
DDRAW_XVIDEO_Available(x11_dd_private *x11ddp) {
|
||||||
|
unsigned int p_version, p_release, p_request_base, p_event_base, p_error_base;
|
||||||
|
|
||||||
|
if (TSXvQueryExtension(display, &p_version, &p_release, &p_request_base,
|
||||||
|
&p_event_base, &p_error_base) == Success) {
|
||||||
|
XvAdaptorInfo *ai;
|
||||||
|
int num_adaptators, i, default_port;
|
||||||
|
|
||||||
|
if ((p_version < 2) || ((p_version == 2) && (p_release < 2))) {
|
||||||
|
TRACE("XVideo extension does NOT support needed features (need version 2.2) !\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSXvQueryAdaptors(display, X11DRV_GetXRootWindow(), &num_adaptators, &ai) != Success) {
|
||||||
|
TRACE("Failed to get list of adaptators.\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (num_adaptators == 0) {
|
||||||
|
TRACE("No XVideo supporting adaptators found.\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
default_port = PROFILE_GetWineIniInt("x11drv", "XVideoPort", -1);
|
||||||
|
for (i = 0; i < num_adaptators; i++) {
|
||||||
|
if ((ai[i].type & XvInputMask) && (ai[i].type & XvImageMask)) {
|
||||||
|
/* This supports everything I want : XvImages and the possibility to put something */
|
||||||
|
if (default_port == -1) {
|
||||||
|
default_port = ai[i].base_id;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if ((ai[i].base_id <= default_port) &&
|
||||||
|
((ai[i].base_id + ai[i].num_ports) > default_port)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == num_adaptators) {
|
||||||
|
if (default_port != -1) {
|
||||||
|
ERR("User specified port (%d) not found.\n", default_port);
|
||||||
|
} else {
|
||||||
|
TRACE("No input + image capable device found.\n");
|
||||||
|
}
|
||||||
|
TSXvFreeAdaptorInfo(ai);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
x11ddp->port_id = default_port;
|
||||||
|
|
||||||
|
TRACE("XVideo support available (using version %d.%d)\n", p_version, p_release);
|
||||||
|
TSXvFreeAdaptorInfo(ai);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static HRESULT X11_Create( LPDIRECTDRAW *lplpDD ) {
|
static HRESULT X11_Create( LPDIRECTDRAW *lplpDD ) {
|
||||||
IDirectDrawImpl* ddraw;
|
IDirectDrawImpl* ddraw;
|
||||||
int depth;
|
int depth;
|
||||||
@ -88,6 +146,13 @@ static HRESULT X11_Create( LPDIRECTDRAW *lplpDD ) {
|
|||||||
TRACE("Using XShm extension.\n");
|
TRACE("Using XShm extension.\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_XVIDEO
|
||||||
|
/* Test if XVideo support is available */
|
||||||
|
if ((x11priv->xvideo_active = DDRAW_XVIDEO_Available(x11priv))) {
|
||||||
|
TRACE("Using XVideo extension on port '%ld'.\n", x11priv->port_id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,13 @@
|
|||||||
# include "ts_xshm.h"
|
# include "ts_xshm.h"
|
||||||
#endif /* defined(HAVE_LIBXXSHM) */
|
#endif /* defined(HAVE_LIBXXSHM) */
|
||||||
|
|
||||||
|
#ifdef HAVE_XVIDEO
|
||||||
|
#include "ts_xvideo.h"
|
||||||
|
#else
|
||||||
|
/* Fake type so that NOT to have too many #ifdef XVideo lying around */
|
||||||
|
typedef int XvImage;
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "x11drv.h"
|
#include "x11drv.h"
|
||||||
|
|
||||||
#include "ddraw_private.h"
|
#include "ddraw_private.h"
|
||||||
@ -34,6 +41,10 @@ typedef struct x11_dd_private {
|
|||||||
#ifdef HAVE_LIBXXSHM
|
#ifdef HAVE_LIBXXSHM
|
||||||
int xshm_active, xshm_compl;
|
int xshm_active, xshm_compl;
|
||||||
#endif /* defined(HAVE_LIBXXSHM) */
|
#endif /* defined(HAVE_LIBXXSHM) */
|
||||||
|
#ifdef HAVE_XVIDEO
|
||||||
|
BOOL xvideo_active;
|
||||||
|
XvPortID port_id;
|
||||||
|
#endif
|
||||||
Window drawable;
|
Window drawable;
|
||||||
void *device_capabilities;
|
void *device_capabilities;
|
||||||
} x11_dd_private;
|
} x11_dd_private;
|
||||||
@ -47,7 +58,18 @@ extern HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(LPDIRECTDRAWPALETTE
|
|||||||
extern ULONG WINAPI Xlib_IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface);
|
extern ULONG WINAPI Xlib_IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface);
|
||||||
|
|
||||||
typedef struct x11_ds_private {
|
typedef struct x11_ds_private {
|
||||||
XImage *image;
|
BOOL is_overlay;
|
||||||
|
union {
|
||||||
|
XImage *image;
|
||||||
|
struct {
|
||||||
|
/* The 'image' field should be in FIRST !!!! The Flip function depends on that... */
|
||||||
|
XvImage *image;
|
||||||
|
BOOL shown;
|
||||||
|
RECT src_rect;
|
||||||
|
RECT dst_rect;
|
||||||
|
LPDIRECTDRAWSURFACE dest_surface;
|
||||||
|
} overlay;
|
||||||
|
} info;
|
||||||
#ifdef HAVE_LIBXXSHM
|
#ifdef HAVE_LIBXXSHM
|
||||||
XShmSegmentInfo shminfo;
|
XShmSegmentInfo shminfo;
|
||||||
#endif
|
#endif
|
||||||
|
@ -811,6 +811,31 @@ typedef struct _DDPIXELFORMAT {
|
|||||||
#define DDOVERFX_MIRRORLEFTRIGHT 0x00000002
|
#define DDOVERFX_MIRRORLEFTRIGHT 0x00000002
|
||||||
#define DDOVERFX_MIRRORUPDOWN 0x00000004
|
#define DDOVERFX_MIRRORUPDOWN 0x00000004
|
||||||
|
|
||||||
|
/* UpdateOverlay flags */
|
||||||
|
#define DDOVER_ALPHADEST 0x00000001
|
||||||
|
#define DDOVER_ALPHADESTCONSTOVERRIDE 0x00000002
|
||||||
|
#define DDOVER_ALPHADESTNEG 0x00000004
|
||||||
|
#define DDOVER_ALPHADESTSURFACEOVERRIDE 0x00000008
|
||||||
|
#define DDOVER_ALPHAEDGEBLEND 0x00000010
|
||||||
|
#define DDOVER_ALPHASRC 0x00000020
|
||||||
|
#define DDOVER_ALPHASRCCONSTOVERRIDE 0x00000040
|
||||||
|
#define DDOVER_ALPHASRCNEG 0x00000080
|
||||||
|
#define DDOVER_ALPHASRCSURFACEOVERRIDE 0x00000100
|
||||||
|
#define DDOVER_HIDE 0x00000200
|
||||||
|
#define DDOVER_KEYDEST 0x00000400
|
||||||
|
#define DDOVER_KEYDESTOVERRIDE 0x00000800
|
||||||
|
#define DDOVER_KEYSRC 0x00001000
|
||||||
|
#define DDOVER_KEYSRCOVERRIDE 0x00002000
|
||||||
|
#define DDOVER_SHOW 0x00004000
|
||||||
|
#define DDOVER_ADDDIRTYRECT 0x00008000
|
||||||
|
#define DDOVER_REFRESHDIRTYRECTS 0x00010000
|
||||||
|
#define DDOVER_REFRESHALL 0x00020000
|
||||||
|
#define DDOVER_DDFX 0x00080000
|
||||||
|
#define DDOVER_AUTOFLIP 0x00100000
|
||||||
|
#define DDOVER_BOB 0x00200000
|
||||||
|
#define DDOVER_OVERRIDEBOBWEAVE 0x00400000
|
||||||
|
#define DDOVER_INTERLEAVED 0x00800000
|
||||||
|
|
||||||
/* DDCOLORKEY.dwFlags */
|
/* DDCOLORKEY.dwFlags */
|
||||||
#define DDPF_ALPHAPIXELS 0x00000001
|
#define DDPF_ALPHAPIXELS 0x00000001
|
||||||
#define DDPF_ALPHA 0x00000002
|
#define DDPF_ALPHA 0x00000002
|
||||||
|
3
wine.ini
3
wine.ini
@ -113,6 +113,9 @@ DesktopDoubleBuffered = N
|
|||||||
; Code page used for captions in managed mode
|
; Code page used for captions in managed mode
|
||||||
; 0 means default ANSI code page (CP_ACP == 0)
|
; 0 means default ANSI code page (CP_ACP == 0)
|
||||||
TextCP=0
|
TextCP=0
|
||||||
|
; Use this if you have more than one port for video on your setup
|
||||||
|
; (Wine uses for now the first 'input image' it founds).
|
||||||
|
;; XVideoPort = 43
|
||||||
|
|
||||||
[fonts]
|
[fonts]
|
||||||
;Read documentation/fonts before adding aliases
|
;Read documentation/fonts before adding aliases
|
||||||
|
Loading…
x
Reference in New Issue
Block a user