X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=subsystems%2Fwin32%2Fwin32k%2Fobjects%2Fdclife.c;h=589e92c594fa39ab21ee81e9f3ae875ac90a8bd3;hp=0487f60e2d77c655a1d16114351133dd62b1f870;hb=406dfdbc870f3a6874c0959a87428c94f7526d3b;hpb=49383c3d9731c3ee9135431b3b1fcbbe9e2ad357 diff --git a/subsystems/win32/win32k/objects/dclife.c b/subsystems/win32/win32k/objects/dclife.c index 0487f60e2d7..589e92c594f 100644 --- a/subsystems/win32/win32k/objects/dclife.c +++ b/subsystems/win32/win32k/objects/dclife.c @@ -6,7 +6,7 @@ * PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org) */ -#include +#include #include #define NDEBUG @@ -58,7 +58,9 @@ static const MATRIX gmxWorldToPageDefault = /** Internal functions ********************************************************/ +INIT_FUNCTION NTSTATUS +NTAPI InitDcImpl() { psurfDefaultBitmap = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]); @@ -89,8 +91,6 @@ DC_AllocDcWithHandle() void DC_InitHack(PDC pdc) { - HRGN hVisRgn; - TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL); pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0); @@ -98,16 +98,8 @@ DC_InitHack(PDC pdc) ASSERT(pdc->dclevel.ppal); /* Select regions */ - // FIXME: too complicated, broken error handling pdc->rosdc.hClipRgn = NULL; pdc->rosdc.hGCClipRgn = NULL; - hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy); - ASSERT(hVisRgn); - GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn); - GreDeleteObject(hVisRgn); - ASSERT(pdc->prgnVis); - pdc->rosdc.bitsPerPixel = pdc->ppdev->gdiinfo.cBitsPixel * - pdc->ppdev->gdiinfo.cPlanes; } VOID @@ -117,9 +109,6 @@ DC_vInitDc( DCTYPE dctype, PPDEVOBJ ppdev) { - /* Lock ppdev */ - EngAcquireSemaphoreShared(ppdev->hsemDevLock); - /* Setup some basic fields */ pdc->dctype = dctype; pdc->ppdev = ppdev; @@ -230,17 +219,20 @@ DC_vInitDc( pdc->dcattr.ptlViewportOrg.y = 0; pdc->dcattr.szlViewportExt.cx = 1; pdc->dcattr.szlViewportExt.cy = 1; - pdc->dcattr.szlVirtualDevicePixel.cx = 0; - pdc->dcattr.szlVirtualDevicePixel.cy = 0; - pdc->dcattr.szlVirtualDeviceMm.cx = 0; - pdc->dcattr.szlVirtualDeviceMm.cy = 0; + pdc->dcattr.szlVirtualDevicePixel.cx = ppdev->gdiinfo.ulHorzRes; + pdc->dcattr.szlVirtualDevicePixel.cy = ppdev->gdiinfo.ulVertRes; + pdc->dcattr.szlVirtualDeviceMm.cx = ppdev->gdiinfo.ulHorzSize; + pdc->dcattr.szlVirtualDeviceMm.cy = ppdev->gdiinfo.ulVertSize; pdc->dcattr.szlVirtualDeviceSize.cx = 0; pdc->dcattr.szlVirtualDeviceSize.cy = 0; /* Setup regions */ pdc->prgnAPI = NULL; - pdc->prgnVis = NULL; // FIXME - pdc->prgnRao = NULL; + pdc->prgnRao = NULL; + /* Allocate a Vis region */ + pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy); + ASSERT(pdc->prgnVis); + GDIOBJ_CopyOwnership(pdc->BaseObject.hHmgr, pdc->prgnVis->BaseObject.hHmgr); /* Setup palette */ pdc->dclevel.hpal = StockObjects[DEFAULT_PALETTE]; @@ -366,7 +358,6 @@ DC_Cleanup(PVOID ObjectBody) GreDeleteObject(pdc->rosdc.hClipRgn); if (pdc->prgnVis) REGION_FreeRgnByHandle(pdc->prgnVis->BaseObject.hHmgr); -ASSERT(pdc->rosdc.hGCClipRgn); if (pdc->rosdc.hGCClipRgn) GreDeleteObject(pdc->rosdc.hGCClipRgn); if (NULL != pdc->rosdc.CombinedClip) @@ -374,6 +365,9 @@ ASSERT(pdc->rosdc.hGCClipRgn); PATH_Delete(pdc->dclevel.hPath); + if(pdc->dclevel.pSurface) + SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface); + PDEVOBJ_vRelease(pdc->ppdev) ; return TRUE; @@ -388,8 +382,6 @@ DC_SetOwnership(HDC hDC, PEPROCESS Owner) PDC pDC; BOOL ret = FALSE; - /* FIXME: This function has broken error handling */ - if (!GDIOBJ_SetOwnership(hDC, Owner)) { DPRINT1("GDIOBJ_SetOwnership failed\n"); @@ -447,6 +439,123 @@ leave: return ret; } + +int FASTCALL +CLIPPING_UpdateGCRegion(DC* Dc); + +static +void +DC_vUpdateDC(PDC pdc) +{ + HRGN hVisRgn ; + PPDEVOBJ ppdev = pdc->ppdev ; + + pdc->dhpdev = ppdev->dhpdev; + + SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface); + pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev); + + PDEVOBJ_sizl(pdc->ppdev, &pdc->dclevel.sizl); + hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy); + ASSERT(hVisRgn); + GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn); + GreDeleteObject(hVisRgn); + + pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps; + pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2; + + /* Mark EBRUSHOBJs as dirty */ + pdc->pdcattr->ulDirty_ |= DIRTY_DEFAULT ; +} + +/* Prepare a blit for up to 2 DCs */ +/* rc1 and rc2 are the rectangles where we want to draw or + * from where we take pixels. */ +VOID +FASTCALL +DC_vPrepareDCsForBlit(PDC pdc1, + RECT rc1, + PDC pdc2, + RECT rc2) +{ + PDC pdcFirst, pdcSecond; + PRECT prcFirst, prcSecond; + /* Lock them in good order */ + if(pdc2) + { + if((ULONG_PTR)pdc1->ppdev->hsemDevLock >= (ULONG_PTR)pdc2->ppdev->hsemDevLock) + { + pdcFirst = pdc1; + prcFirst = &rc1; + pdcSecond = pdc2; + prcSecond = &rc2; + } + else + { + pdcFirst = pdc2; + prcFirst = &rc2; + pdcSecond = pdc1; + prcSecond = &rc1; + } + } + else + { + pdcFirst = pdc1 ; + prcFirst = &rc1; + pdcSecond = NULL ; + } + + if(pdcFirst && pdcFirst->dctype == DCTYPE_DIRECT) + { + EngAcquireSemaphore(pdcFirst->ppdev->hsemDevLock); + MouseSafetyOnDrawStart(pdcFirst->ppdev, + prcFirst->left, + prcFirst->top, + prcFirst->right, + prcFirst->bottom) ; + /* Update surface if needed */ + if(pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface) + { + DC_vUpdateDC(pdcFirst); + } + } + if(pdcSecond && pdcSecond->dctype == DCTYPE_DIRECT) + { + EngAcquireSemaphore(pdcSecond->ppdev->hsemDevLock); + MouseSafetyOnDrawStart(pdcSecond->ppdev, + prcSecond->left, + prcSecond->top, + prcSecond->right, + prcSecond->bottom) ; + /* Update surface if needed */ + if(pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface) + { + DC_vUpdateDC(pdcSecond); + } + } +} + +/* Finishes a blit for one or two DCs */ +VOID +FASTCALL +DC_vFinishBlit(PDC pdc1, PDC pdc2) +{ + if(pdc1->dctype == DCTYPE_DIRECT) + { + MouseSafetyOnDrawEnd(pdc1->ppdev); + EngReleaseSemaphore(pdc1->ppdev->hsemDevLock); + } + + if(pdc2) + { + if(pdc2->dctype == DCTYPE_DIRECT) + { + MouseSafetyOnDrawEnd(pdc2->ppdev); + EngReleaseSemaphore(pdc2->ppdev->hsemDevLock); + } + } +} + HDC NTAPI GreOpenDCW( @@ -679,11 +788,28 @@ IntGdiDeleteDC(HDC hDC, BOOL Force) if (!Force) { + /* Windows permits NtGdiDeleteObjectApp to delete a permanent DC + * For some reason, it's still a valid handle, pointing to some kernel data. + * Not sure if this is a bug, a feature, some cache stuff... Who knows? + * See NtGdiDeleteObjectApp test for details */ if (DCToDelete->fs & DC_FLAG_PERMANENT) { - DPRINT1("No! You Naughty Application!\n"); DC_UnlockDc(DCToDelete); - return UserReleaseDC(NULL, hDC, FALSE); + if(UserReleaseDC(NULL, hDC, FALSE)) + { + /* ReactOs feature : call UserReleaseDC + * I don't think windows does it. + * Still, complain, no one should ever call DeleteDC + * on a window DC */ + DPRINT1("No, you naughty application!\n"); + return TRUE; + } + else + { + /* This is not a window owned DC. + * Force its deletion */ + return IntGdiDeleteDC(hDC, TRUE); + } } } @@ -700,7 +826,7 @@ IntGdiDeleteDC(HDC hDC, BOOL Force) { DPRINT1("Attempted to Delete 0x%x currently being destroyed!!!\n", hDC); } - + return TRUE; } @@ -727,14 +853,74 @@ NtGdiDeleteObjectApp(HANDLE DCHandle) return IntGdiDeleteDC(DCHandle, FALSE); } +BOOL +FASTCALL +MakeInfoDC(PDC pdc, BOOL bSet) +{ + PSURFACE pSurface; + SIZEL sizl; + + /* Can not be a display DC. */ + if (pdc->fs & DC_FLAG_DISPLAY) return FALSE; + if (bSet) + { + if (pdc->fs & DC_FLAG_TEMPINFODC || pdc->dctype == DC_TYPE_DIRECT) + return FALSE; + + pSurface = pdc->dclevel.pSurface; + pdc->fs |= DC_FLAG_TEMPINFODC; + pdc->pSurfInfo = pSurface; + pdc->dctype = DC_TYPE_INFO; + pdc->dclevel.pSurface = NULL; + + PDEVOBJ_sizl(pdc->ppdev, &sizl); + + if ( sizl.cx == pdc->dclevel.sizl.cx && + sizl.cy == pdc->dclevel.sizl.cy ) + return TRUE; + + pdc->dclevel.sizl.cx = sizl.cx; + pdc->dclevel.sizl.cy = sizl.cy; + } + else + { + if (!(pdc->fs & DC_FLAG_TEMPINFODC) || pdc->dctype != DC_TYPE_INFO) + return FALSE; + + pSurface = pdc->pSurfInfo; + pdc->fs &= ~DC_FLAG_TEMPINFODC; + pdc->dclevel.pSurface = pSurface; + pdc->dctype = DC_TYPE_DIRECT; + pdc->pSurfInfo = NULL; + + if ( !pSurface || + (pSurface->SurfObj.sizlBitmap.cx == pdc->dclevel.sizl.cx && + pSurface->SurfObj.sizlBitmap.cy == pdc->dclevel.sizl.cy) ) + return TRUE; + + pdc->dclevel.sizl.cx = pSurface->SurfObj.sizlBitmap.cx; + pdc->dclevel.sizl.cy = pSurface->SurfObj.sizlBitmap.cy; + } + return IntSetDefaultRegion(pdc); +} + +/* +* @implemented +*/ BOOL APIENTRY NtGdiMakeInfoDC( IN HDC hdc, IN BOOL bSet) { - UNIMPLEMENTED; - ASSERT(FALSE); + BOOL Ret; + PDC pdc = DC_LockDc(hdc); + if (pdc) + { + Ret = MakeInfoDC(pdc, bSet); + DC_UnlockDc(pdc); + return Ret; + } return FALSE; }