X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=subsystems%2Fwin32%2Fwin32k%2Fobjects%2Fdclife.c;h=589e92c594fa39ab21ee81e9f3ae875ac90a8bd3;hp=b93ba336d361cecb74670c4777201e2d5dcb112a;hb=406dfdbc870f3a6874c0959a87428c94f7526d3b;hpb=0cdfd4399d9fc75ffc6557a4ea707654e7543ba7;ds=sidebyside diff --git a/subsystems/win32/win32k/objects/dclife.c b/subsystems/win32/win32k/objects/dclife.c index b93ba336d36..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,14 +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); } VOID @@ -115,12 +109,6 @@ DC_vInitDc( DCTYPE dctype, PPDEVOBJ ppdev) { - if (dctype == DCTYPE_DIRECT) - { - /* Lock ppdev */ - EngAcquireSemaphoreShared(ppdev->hsemDevLock); - } - /* Setup some basic fields */ pdc->dctype = dctype; pdc->ppdev = ppdev; @@ -231,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]; @@ -367,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) @@ -392,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"); @@ -451,6 +439,35 @@ 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. */ @@ -461,15 +478,60 @@ DC_vPrepareDCsForBlit(PDC pdc1, PDC pdc2, RECT rc2) { - if(pdc1->dctype == DCTYPE_DIRECT) + PDC pdcFirst, pdcSecond; + PRECT prcFirst, prcSecond; + /* Lock them in good order */ + if(pdc2) { - EngAcquireSemaphore(pdc1->ppdev->hsemDevLock); - MouseSafetyOnDrawStart(&pdc1->dclevel.pSurface->SurfObj, rc1.left, rc1.top, rc1.right, rc1.bottom) ; + 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; + } } - if(pdc2 && pdc2->dctype == DCTYPE_DIRECT) + else { - EngAcquireSemaphore(pdc2->ppdev->hsemDevLock); - MouseSafetyOnDrawStart(&pdc2->dclevel.pSurface->SurfObj, rc2.left, rc2.top, rc2.right, rc2.bottom) ; + 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); + } } } @@ -480,7 +542,7 @@ DC_vFinishBlit(PDC pdc1, PDC pdc2) { if(pdc1->dctype == DCTYPE_DIRECT) { - MouseSafetyOnDrawEnd(&pdc1->dclevel.pSurface->SurfObj); + MouseSafetyOnDrawEnd(pdc1->ppdev); EngReleaseSemaphore(pdc1->ppdev->hsemDevLock); } @@ -488,7 +550,7 @@ DC_vFinishBlit(PDC pdc1, PDC pdc2) { if(pdc2->dctype == DCTYPE_DIRECT) { - MouseSafetyOnDrawEnd(&pdc2->dclevel.pSurface->SurfObj); + MouseSafetyOnDrawEnd(pdc2->ppdev); EngReleaseSemaphore(pdc2->ppdev->hsemDevLock); } } @@ -726,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); + } } } @@ -747,7 +826,7 @@ IntGdiDeleteDC(HDC hDC, BOOL Force) { DPRINT1("Attempted to Delete 0x%x currently being destroyed!!!\n", hDC); } - + return TRUE; }