| /* DirectDrawSurface XF86DGA implementation |
| * |
| * Copyright 1997-2000 Marcus Meissner |
| * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff) |
| */ |
| #include "config.h" |
| #include "winerror.h" |
| |
| #include <unistd.h> |
| #include <assert.h> |
| #include <fcntl.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| |
| #include "debugtools.h" |
| #include "dga_private.h" |
| #include "bitmap.h" |
| |
| DEFAULT_DEBUG_CHANNEL(ddraw); |
| |
| #define DDPRIVATE(x) dga_dd_private *ddpriv = ((dga_dd_private*)(x)->d->private) |
| #define DPPRIVATE(x) dga_dp_private *dppriv = ((dga_dp_private*)(x)->private) |
| #define DSPRIVATE(x) dga_ds_private *dspriv = ((dga_ds_private*)(x)->private) |
| |
| static BYTE DGA_TouchSurface(LPDIRECTDRAWSURFACE4 iface) |
| { |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); |
| /* if the DIB section is in GdiMod state, we must |
| * touch the surface to get any updates from the DIB */ |
| return *(BYTE*)(This->s.surface_desc.u1.lpSurface); |
| } |
| |
| /****************************************************************************** |
| * IDirectDrawSurface methods |
| * |
| * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let |
| * DDS and DDS2 use those functions. (Function calls did not change (except |
| * using different DirectDrawSurfaceX version), just added flags and functions) |
| */ |
| |
| HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip( |
| LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags |
| ) { |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); |
| DSPRIVATE(This); |
| dga_ds_private *fspriv; |
| IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto; |
| DWORD xheight; |
| LPBYTE surf; |
| |
| TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags); |
| |
| DGA_TouchSurface(iface); |
| iflipto = _common_find_flipto(This,iflipto); |
| |
| /* and flip! */ |
| fspriv = (dga_ds_private*)iflipto->private; |
| TSXF86DGASetViewPort(display,DefaultScreen(display),0,fspriv->fb_height); |
| if (iflipto->s.palette) { |
| DPPRIVATE(iflipto); |
| |
| if (dppriv->cm) |
| TSXF86DGAInstallColormap(display,DefaultScreen(display),dppriv->cm); |
| } |
| while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) { |
| /* EMPTY */ |
| } |
| /* We need to switch the lowlevel surfaces, for DGA this is: */ |
| |
| /* The height within the framebuffer */ |
| xheight = dspriv->fb_height; |
| dspriv->fb_height = fspriv->fb_height; |
| fspriv->fb_height = xheight; |
| |
| /* And the assciated surface pointer */ |
| surf = This->s.surface_desc.u1.lpSurface; |
| This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface; |
| iflipto->s.surface_desc.u1.lpSurface= surf; |
| return DD_OK; |
| } |
| |
| HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette( |
| LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal |
| ) { |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); |
| IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal; |
| |
| TRACE("(%p)->(%p)\n",This,ipal); |
| |
| /* According to spec, we are only supposed to |
| * AddRef if this is not the same palette. |
| */ |
| if( This->s.palette != ipal ) { |
| dga_dp_private *fppriv; |
| if( ipal != NULL ) |
| IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal ); |
| if( This->s.palette != NULL ) |
| IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette ); |
| This->s.palette = ipal; |
| fppriv = (dga_dp_private*)This->s.palette->private; |
| |
| if (!fppriv->cm && |
| (This->s.ddraw->d->screen_pixelformat.u.dwRGBBitCount<=8) ) { |
| int i; |
| |
| /* Delayed palette creation */ |
| fppriv->cm = TSXCreateColormap(display,DefaultRootWindow(display), |
| DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll); |
| |
| for (i=0;i<256;i++) { |
| XColor xc; |
| |
| xc.red = ipal->palents[i].peRed<<8; |
| xc.blue = ipal->palents[i].peBlue<<8; |
| xc.green = ipal->palents[i].peGreen<<8; |
| xc.flags = DoRed|DoBlue|DoGreen; |
| xc.pixel = i; |
| TSXStoreColor(display,fppriv->cm,&xc); |
| } |
| } |
| |
| TSXF86DGAInstallColormap(display,DefaultScreen(display),fppriv->cm); |
| |
| if (This->s.hdc != 0) { |
| /* hack: set the DIBsection color map */ |
| BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(This->s.DIBsection, BITMAP_MAGIC); |
| X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *)bmp->dib; |
| dib->colorMap = This->s.palette ? This->s.palette->screen_palents : NULL; |
| GDI_ReleaseObj(This->s.DIBsection); |
| } |
| TSXFlush(display); |
| } |
| return DD_OK; |
| } |
| |
| ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) { |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); |
| DDPRIVATE(This->s.ddraw); |
| DSPRIVATE(This); |
| |
| TRACE("(%p)->() decrementing from %lu.\n", This, This->ref ); |
| |
| if (--(This->ref)) |
| return This->ref; |
| |
| IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw); |
| /* clear out of surface list */ |
| if (ddpriv->fb_height == -1) |
| VirtualFree(This->s.surface_desc.u1.lpSurface, 0, MEM_RELEASE); |
| else |
| ddpriv->vpmask &= ~(1<<(dspriv->fb_height/ddpriv->fb_height)); |
| |
| /* Free the DIBSection (if any) */ |
| if (This->s.hdc != 0) { |
| /* hack: restore the original DIBsection color map */ |
| BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(This->s.DIBsection, BITMAP_MAGIC); |
| X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *)bmp->dib; |
| dib->colorMap = dspriv->oldDIBmap; |
| GDI_ReleaseObj(This->s.DIBsection); |
| |
| SelectObject(This->s.hdc, This->s.holdbitmap); |
| DeleteDC(This->s.hdc); |
| DeleteObject(This->s.DIBsection); |
| } |
| /* Free the clipper if attached to this surface */ |
| if( This->s.lpClipper ) |
| IDirectDrawClipper_Release(This->s.lpClipper); |
| HeapFree(GetProcessHeap(),0,This); |
| return S_OK; |
| } |
| |
| HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock( |
| LPDIRECTDRAWSURFACE4 iface,LPVOID surface |
| ) { |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); |
| TRACE("(%p)->Unlock(%p)\n",This,surface); |
| |
| /* in case this was called from ReleaseDC */ |
| DGA_TouchSurface(iface); |
| |
| return DD_OK; |
| } |
| |
| HRESULT WINAPI DGA_IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) { |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); |
| DSPRIVATE(This); |
| int was_ok = This->s.hdc != 0; |
| HRESULT result = IDirectDrawSurface4Impl_GetDC(iface,lphdc); |
| if (This->s.hdc && !was_ok) { |
| /* hack: take over the DIBsection color map */ |
| BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(This->s.DIBsection, BITMAP_MAGIC); |
| X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *)bmp->dib; |
| dspriv->oldDIBmap = dib->colorMap; |
| dib->colorMap = This->s.palette ? This->s.palette->screen_palents : NULL; |
| GDI_ReleaseObj(This->s.DIBsection); |
| } |
| return result; |
| } |
| |
| ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| IDirectDrawSurface4Impl_QueryInterface, |
| IDirectDrawSurface4Impl_AddRef, |
| DGA_IDirectDrawSurface4Impl_Release, |
| IDirectDrawSurface4Impl_AddAttachedSurface, |
| IDirectDrawSurface4Impl_AddOverlayDirtyRect, |
| IDirectDrawSurface4Impl_Blt, |
| IDirectDrawSurface4Impl_BltBatch, |
| IDirectDrawSurface4Impl_BltFast, |
| IDirectDrawSurface4Impl_DeleteAttachedSurface, |
| IDirectDrawSurface4Impl_EnumAttachedSurfaces, |
| IDirectDrawSurface4Impl_EnumOverlayZOrders, |
| DGA_IDirectDrawSurface4Impl_Flip, |
| IDirectDrawSurface4Impl_GetAttachedSurface, |
| IDirectDrawSurface4Impl_GetBltStatus, |
| IDirectDrawSurface4Impl_GetCaps, |
| IDirectDrawSurface4Impl_GetClipper, |
| IDirectDrawSurface4Impl_GetColorKey, |
| DGA_IDirectDrawSurface4Impl_GetDC, |
| IDirectDrawSurface4Impl_GetFlipStatus, |
| IDirectDrawSurface4Impl_GetOverlayPosition, |
| IDirectDrawSurface4Impl_GetPalette, |
| IDirectDrawSurface4Impl_GetPixelFormat, |
| IDirectDrawSurface4Impl_GetSurfaceDesc, |
| IDirectDrawSurface4Impl_Initialize, |
| IDirectDrawSurface4Impl_IsLost, |
| IDirectDrawSurface4Impl_Lock, |
| IDirectDrawSurface4Impl_ReleaseDC, |
| IDirectDrawSurface4Impl_Restore, |
| IDirectDrawSurface4Impl_SetClipper, |
| IDirectDrawSurface4Impl_SetColorKey, |
| IDirectDrawSurface4Impl_SetOverlayPosition, |
| DGA_IDirectDrawSurface4Impl_SetPalette, |
| DGA_IDirectDrawSurface4Impl_Unlock, |
| IDirectDrawSurface4Impl_UpdateOverlay, |
| IDirectDrawSurface4Impl_UpdateOverlayDisplay, |
| IDirectDrawSurface4Impl_UpdateOverlayZOrder, |
| IDirectDrawSurface4Impl_GetDDInterface, |
| IDirectDrawSurface4Impl_PageLock, |
| IDirectDrawSurface4Impl_PageUnlock, |
| IDirectDrawSurface4Impl_SetSurfaceDesc, |
| IDirectDrawSurface4Impl_SetPrivateData, |
| IDirectDrawSurface4Impl_GetPrivateData, |
| IDirectDrawSurface4Impl_FreePrivateData, |
| IDirectDrawSurface4Impl_GetUniquenessValue, |
| IDirectDrawSurface4Impl_ChangeUniquenessValue |
| }; |