* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Functions for creation and destruction of DCs
- * FILE: subsystem/win32/win32k/objects/dclife.c
+ * FILE: win32ss/gdi/ntgdi/dclife.c
* PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org)
*/
PSURFACE psurfDefaultBitmap = NULL;
PBRUSH pbrDefaultBrush = NULL;
-static const MATRIX gmxWorldToDeviceDefault =
+const MATRIX gmxWorldToDeviceDefault =
{
FLOATOBJ_16, FLOATOBJ_0,
FLOATOBJ_0, FLOATOBJ_16,
0, 0, 0x4b
};
-static const MATRIX gmxDeviceToWorldDefault =
+const MATRIX gmxDeviceToWorldDefault =
{
FLOATOBJ_1_16, FLOATOBJ_0,
FLOATOBJ_0, FLOATOBJ_1_16,
0, 0, 0x53
};
-static const MATRIX gmxWorldToPageDefault =
+const MATRIX gmxWorldToPageDefault =
{
FLOATOBJ_1, FLOATOBJ_0,
FLOATOBJ_0, FLOATOBJ_1,
INIT_FUNCTION
NTSTATUS
NTAPI
-InitDcImpl()
+InitDcImpl(VOID)
{
psurfDefaultBitmap = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
if (!psurfDefaultBitmap)
PDC
NTAPI
-DC_AllocDcWithHandle()
+DC_AllocDcWithHandle(GDILOOBJTYPE eDcObjType)
{
PDC pdc;
+ NT_ASSERT((eDcObjType == GDILoObjType_LO_DC_TYPE) ||
+ (eDcObjType == GDILoObjType_LO_ALTDC_TYPE));
+
+ /* Allocate the object */
pdc = (PDC)GDIOBJ_AllocateObject(GDIObjType_DC_TYPE,
sizeof(DC),
BASEFLAG_LOOKASIDE);
return NULL;
}
+ /* Set the actual DC type */
+ pdc->BaseObject.hHmgr = UlongToHandle(eDcObjType);
+
+ pdc->pdcattr = &pdc->dcattr;
+
+ /* Insert the object */
if (!GDIOBJ_hInsertObject(&pdc->BaseObject, GDI_OBJ_HMGR_POWNED))
{
DPRINT1("Could not insert DC into handle table.\n");
return NULL;
}
- pdc->pdcattr = &pdc->dcattr;
-
return pdc;
}
void
DC_InitHack(PDC pdc)
{
- HRGN hVisRgn;
+ if (defaultDCstate == NULL)
+ {
+ defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
+ ASSERT(defaultDCstate);
+ RtlZeroMemory(defaultDCstate, sizeof(DC));
+ defaultDCstate->pdcattr = &defaultDCstate->dcattr;
+ DC_vCopyState(pdc, defaultDCstate, TRUE);
+ }
+
+ if (prgnDefault == NULL)
+ {
+ prgnDefault = IntSysCreateRectpRgn(0, 0, 0, 0);
+ }
TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL);
pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
/* This should never fail */
ASSERT(pdc->dclevel.ppal);
-
- /* Select regions */
- pdc->rosdc.hClipRgn = NULL;
- pdc->rosdc.hGCClipRgn = NULL;
-
- hVisRgn = IntSysCreateRectRgn(0, 0, 1, 1);
- ASSERT(hVisRgn);
- GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
- GreDeleteObject(hVisRgn);
}
VOID
pdc->erclBoundsApp.right = 0x00007ffc; // FIXME
pdc->erclBoundsApp.bottom = 0x00000333; // FIXME
pdc->erclClip = pdc->erclBounds;
-// pdc->co
-
- pdc->fs |= DC_SYNCHRONIZEACCESS | DC_ACCUM_APP | DC_PERMANANT | DC_DISPLAY;
+ pdc->co = gxcoTrivial;
}
else
{
pdc->erclBounds.bottom = 0;
pdc->erclBoundsApp = pdc->erclBounds;
pdc->erclClip = pdc->erclWindow;
- //pdc->co = NULL
+ pdc->co = gxcoTrivial;
}
//pdc->dcattr.VisRectRegion:
/* Setup regions */
pdc->prgnAPI = NULL;
pdc->prgnRao = NULL;
+ pdc->dclevel.prgnClip = NULL;
+ pdc->dclevel.prgnMeta = NULL;
/* Allocate a Vis region */
pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
ASSERT(pdc->prgnVis);
+ /* Setup Vis Region Attribute information */
+ UpdateVisRgn(pdc);
+
+ /* Initialize Clip object */
+ IntEngInitClipObj(&pdc->co);
+
/* Setup palette */
pdc->dclevel.hpal = StockObjects[DEFAULT_PALETTE];
pdc->dclevel.ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal);
/* Other stuff */
pdc->hdcNext = NULL;
pdc->hdcPrev = NULL;
- pdc->ipfdDevMax = 0x0000ffff;
+ pdc->ipfdDevMax = 0;
pdc->ulCopyCount = -1;
pdc->ptlDoBanding.x = 0;
pdc->ptlDoBanding.y = 0;
pdc->dcattr.iGraphicsMode = GM_COMPATIBLE;
pdc->dcattr.iCS_CP = 0;
pdc->pSurfInfo = NULL;
-
- if (defaultDCstate == NULL)
- {
- defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
- ASSERT(defaultDCstate);
- RtlZeroMemory(defaultDCstate, sizeof(DC));
- defaultDCstate->pdcattr = &defaultDCstate->dcattr;
- DC_vCopyState(pdc, defaultDCstate, TRUE);
- }
}
-BOOL
+VOID
NTAPI
-DC_Cleanup(PVOID ObjectBody)
+DC_vCleanup(PVOID ObjectBody)
{
PDC pdc = (PDC)ObjectBody;
EBRUSHOBJ_vCleanup(&pdc->eboBackground);
/* Release font */
- LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
+ if (pdc->dclevel.plfnt)
+ LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
/* Free regions */
- if (pdc->rosdc.hClipRgn && GreIsHandleValid(pdc->rosdc.hClipRgn))
- GreDeleteObject(pdc->rosdc.hClipRgn);
+ if (pdc->dclevel.prgnClip)
+ REGION_Delete(pdc->dclevel.prgnClip);
+ if (pdc->dclevel.prgnMeta)
+ REGION_Delete(pdc->dclevel.prgnMeta);
if (pdc->prgnVis)
- {
REGION_Delete(pdc->prgnVis);
- }
- if (pdc->rosdc.hGCClipRgn && GreIsHandleValid(pdc->rosdc.hGCClipRgn))
- {
- GreDeleteObject(pdc->rosdc.hGCClipRgn);
- }
- if (NULL != pdc->rosdc.CombinedClip)
- IntEngDeleteClipRegion(pdc->rosdc.CombinedClip);
+ if (pdc->prgnRao)
+ REGION_Delete(pdc->prgnRao);
+ if (pdc->prgnAPI)
+ REGION_Delete(pdc->prgnAPI);
- PATH_Delete(pdc->dclevel.hPath);
+ /* Free CLIPOBJ resources */
+ IntEngFreeClipResources(&pdc->co);
- if(pdc->dclevel.pSurface)
+ if (pdc->dclevel.hPath)
+ {
+ DPRINT("DC_vCleanup Path\n");
+ PATH_Delete(pdc->dclevel.hPath);
+ pdc->dclevel.hPath = 0;
+ pdc->dclevel.flPath = 0;
+ }
+ if (pdc->dclevel.pSurface)
SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface);
- PDEVOBJ_vRelease(pdc->ppdev) ;
-
- return TRUE;
+ if (pdc->ppdev)
+ PDEVOBJ_vRelease(pdc->ppdev);
}
VOID
NTAPI
DC_vSetOwner(PDC pdc, ULONG ulOwner)
{
-
- if (pdc->rosdc.hClipRgn)
- {
- IntGdiSetRegionOwner(pdc->rosdc.hClipRgn, ulOwner);
- }
-
- if (pdc->rosdc.hGCClipRgn)
- {
- IntGdiSetRegionOwner(pdc->rosdc.hGCClipRgn, ulOwner);
- }
+ /* Delete saved DCs */
+ DC_vRestoreDC(pdc, 1);
if (pdc->dclevel.hPath)
{
void
DC_vUpdateDC(PDC pdc)
{
- HRGN hVisRgn ;
- PPDEVOBJ ppdev = pdc->ppdev ;
+ // PREGION VisRgn ;
+ PPDEVOBJ ppdev = pdc->ppdev;
pdc->dhpdev = ppdev->dhpdev;
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);
+#if 0
+ VisRgn = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
+ ASSERT(VisRgn);
+ GdiSelectVisRgn(pdc->BaseObject.hHmgr, VisRgn);
+ REGION_Delete(VisRgn);
+#endif
pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps;
pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2;
* from where we take pixels. */
VOID
FASTCALL
-DC_vPrepareDCsForBlit(PDC pdc1,
- RECT rc1,
- PDC pdc2,
- RECT rc2)
+DC_vPrepareDCsForBlit(
+ PDC pdcDest,
+ const RECT* rcDest,
+ PDC pdcSrc,
+ const RECT* rcSrc)
{
PDC pdcFirst, pdcSecond;
- PRECT prcFirst, prcSecond;
+ const RECT *prcFirst, *prcSecond;
/* Update brushes */
- if (pdc1->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
- DC_vUpdateFillBrush(pdc1);
- if (pdc1->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
- DC_vUpdateLineBrush(pdc1);
- if(pdc1->pdcattr->ulDirty_ & DIRTY_TEXT)
- DC_vUpdateTextBrush(pdc1);
+ if (pdcDest->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(pdcDest);
+ if (pdcDest->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(pdcDest);
+ if(pdcDest->pdcattr->ulDirty_ & DIRTY_TEXT)
+ DC_vUpdateTextBrush(pdcDest);
/* Lock them in good order */
- if(pdc2)
+ if (pdcSrc)
{
- if((ULONG_PTR)pdc1->ppdev->hsemDevLock >= (ULONG_PTR)pdc2->ppdev->hsemDevLock)
+ if((ULONG_PTR)pdcDest->ppdev->hsemDevLock >=
+ (ULONG_PTR)pdcSrc->ppdev->hsemDevLock)
{
- pdcFirst = pdc1;
- prcFirst = &rc1;
- pdcSecond = pdc2;
- prcSecond = &rc2;
+ pdcFirst = pdcDest;
+ prcFirst = rcDest;
+ pdcSecond = pdcSrc;
+ prcSecond = rcSrc;
}
else
{
- pdcFirst = pdc2;
- prcFirst = &rc2;
- pdcSecond = pdc1;
- prcSecond = &rc1;
+ pdcFirst = pdcSrc;
+ prcFirst = rcSrc;
+ pdcSecond = pdcDest;
+ prcSecond = rcDest;
}
}
else
{
- pdcFirst = pdc1 ;
- prcFirst = &rc1;
+ pdcFirst = pdcDest;
+ prcFirst = rcDest;
pdcSecond = NULL;
prcSecond = NULL;
}
- if(pdcFirst && pdcFirst->dctype == DCTYPE_DIRECT)
+ if (pdcDest->fs & DC_FLAG_DIRTY_RAO)
+ CLIPPING_UpdateGCRegion(pdcDest);
+
+ /* Lock and update first DC */
+ if (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)
+ if (pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface)
{
DC_vUpdateDC(pdcFirst);
}
}
- if(pdcSecond && pdcSecond->dctype == DCTYPE_DIRECT)
+
+ if (pdcFirst->dctype == DCTYPE_DIRECT)
+ {
+ if (!prcFirst)
+ prcFirst = &pdcFirst->erclClip;
+
+ MouseSafetyOnDrawStart(pdcFirst->ppdev,
+ prcFirst->left,
+ prcFirst->top,
+ prcFirst->right,
+ prcFirst->bottom) ;
+ }
+
+#if DBG
+ pdcFirst->fs |= DC_PREPARED;
+#endif
+
+ if (!pdcSecond)
+ return;
+
+ /* Lock and update second DC */
+ if (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)
+ if (pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface)
{
DC_vUpdateDC(pdcSecond);
}
}
+
+ if (pdcSecond->dctype == DCTYPE_DIRECT)
+ {
+ if (!prcSecond)
+ prcSecond = &pdcSecond->erclClip;
+ MouseSafetyOnDrawStart(pdcSecond->ppdev,
+ prcSecond->left,
+ prcSecond->top,
+ prcSecond->right,
+ prcSecond->bottom) ;
+ }
+
+#if DBG
+ pdcSecond->fs |= DC_PREPARED;
+#endif
}
/* Finishes a blit for one or two DCs */
FASTCALL
DC_vFinishBlit(PDC pdc1, PDC pdc2)
{
- if(pdc1->dctype == DCTYPE_DIRECT)
+ if (pdc1->dctype == DCTYPE_DIRECT)
{
MouseSafetyOnDrawEnd(pdc1->ppdev);
EngReleaseSemaphore(pdc1->ppdev->hsemDevLock);
}
+#if DBG
+ pdc1->fs &= ~DC_PREPARED;
+#endif
- if(pdc2)
+ if (pdc2)
{
- if(pdc2->dctype == DCTYPE_DIRECT)
+ if (pdc2->dctype == DCTYPE_DIRECT)
{
MouseSafetyOnDrawEnd(pdc2->ppdev);
EngReleaseSemaphore(pdc2->ppdev->hsemDevLock);
}
+#if DBG
+ pdc2->fs &= ~DC_PREPARED;
+#endif
}
}
BOOL bDisplay,
HANDLE hspool,
VOID *pDriverInfo2,
- VOID *pUMdhpdev)
+ PVOID *pUMdhpdev)
{
PPDEVOBJ ppdev;
PDC pdc;
DPRINT("GreOpenDCW - ppdev = %p\n", ppdev);
- pdc = DC_AllocDcWithHandle();
+ pdc = DC_AllocDcWithHandle(GDILoObjType_LO_DC_TYPE);
if (!pdc)
{
DPRINT1("Could not Allocate a DC\n");
/* Lock ppdev and initialize the new DC */
DC_vInitDc(pdc, iType, ppdev);
+ if (pUMdhpdev) *pUMdhpdev = ppdev->dhpdev;
/* FIXME: HACK! */
DC_InitHack(pdc);
return hdc;
}
+__kernel_entry
HDC
APIENTRY
NtGdiOpenDCW(
- PUNICODE_STRING pustrDevice,
- DEVMODEW *pdmInit,
- PUNICODE_STRING pustrLogAddr,
- ULONG iType,
- BOOL bDisplay,
- HANDLE hspool,
- VOID *pDriverInfo2,
- VOID *pUMdhpdev)
+ _In_opt_ PUNICODE_STRING pustrDevice,
+ _In_ DEVMODEW *pdmInit,
+ _In_ PUNICODE_STRING pustrLogAddr,
+ _In_ ULONG iType,
+ _In_ BOOL bDisplay,
+ _In_opt_ HANDLE hspool,
+ /*_In_opt_ DRIVER_INFO2W *pdDriverInfo2, Need this soon!!!! */
+ _At_((PUMDHPDEV*)pUMdhpdev, _Out_) PVOID pUMdhpdev)
{
UNICODE_STRING ustrDevice;
WCHAR awcDevice[CCHDEVICENAME];
- DEVMODEW dmInit;
PVOID dhpdev;
HDC hdc;
+ WORD dmSize, dmDriverExtra;
+ DWORD Size;
+ DEVMODEW * _SEH2_VOLATILE pdmAllocated = NULL;
/* Only if a devicename is given, we need any data */
if (pustrDevice)
/* Copy the string */
RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+ /* Allocate and store pdmAllocated if pdmInit is not NULL */
if (pdmInit)
{
- /* FIXME: could be larger */
ProbeForRead(pdmInit, sizeof(DEVMODEW), 1);
- RtlCopyMemory(&dmInit, pdmInit, sizeof(DEVMODEW));
+
+ dmSize = pdmInit->dmSize;
+ dmDriverExtra = pdmInit->dmDriverExtra;
+ Size = dmSize + dmDriverExtra;
+ ProbeForRead(pdmInit, Size, 1);
+
+ pdmAllocated = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE,
+ Size,
+ TAG_DC);
+ RtlCopyMemory(pdmAllocated, pdmInit, Size);
+ pdmAllocated->dmSize = dmSize;
+ pdmAllocated->dmDriverExtra = dmDriverExtra;
}
if (pUMdhpdev)
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
+ if (pdmAllocated)
+ {
+ ExFreePoolWithTag(pdmAllocated, TAG_DC);
+ }
SetLastNtError(_SEH2_GetExceptionCode());
_SEH2_YIELD(return NULL);
}
{
pdmInit = NULL;
pUMdhpdev = NULL;
+ // return UserGetDesktopDC(iType, FALSE, TRUE);
}
/* FIXME: HACK! */
/* Call the internal function */
hdc = GreOpenDCW(pustrDevice ? &ustrDevice : NULL,
- pdmInit ? &dmInit : NULL,
+ pdmAllocated,
NULL, // FIXME: pwszLogAddress
iType,
bDisplay,
/* If we got a HDC and a UM dhpdev is requested,... */
if (hdc && pUMdhpdev)
{
- /* Copy dhpdev to caller (FIXME: use dhpdev?) */
+ /* Copy dhpdev to caller */
_SEH2_TRY
{
/* Pointer was already probed */
_SEH2_END
}
+ /* Free the allocated */
+ if (pdmAllocated)
+ {
+ ExFreePoolWithTag(pdmAllocated, TAG_DC);
+ }
+
return hdc;
}
HDC
APIENTRY
-NtGdiCreateCompatibleDC(HDC hdc)
+GreCreateCompatibleDC(HDC hdc, BOOL bAltDc)
{
+ GDILOOBJTYPE eDcObjType;
HDC hdcNew;
PPDEVOBJ ppdev;
PDC pdc, pdcNew;
}
/* Allocate a new DC */
- pdcNew = DC_AllocDcWithHandle();
+ eDcObjType = bAltDc ? GDILoObjType_LO_ALTDC_TYPE : GDILoObjType_LO_DC_TYPE;
+ pdcNew = DC_AllocDcWithHandle(eDcObjType);
if (!pdcNew)
{
DPRINT1("Could not allocate a new DC\n");
hdcNew = pdcNew->BaseObject.hHmgr;
/* Lock ppdev and initialize the new DC */
- DC_vInitDc(pdcNew, DCTYPE_MEMORY, ppdev);
+ DC_vInitDc(pdcNew, bAltDc ? DCTYPE_INFO : DCTYPE_MEMORY, ppdev);
/* FIXME: HACK! */
DC_InitHack(pdcNew);
return hdcNew;
}
+HDC
+APIENTRY
+NtGdiCreateCompatibleDC(HDC hdc)
+{
+ /* Call the internal function to create a normal memory DC */
+ return GreCreateCompatibleDC(hdc, FALSE);
+}
+
BOOL
FASTCALL
IntGdiDeleteDC(HDC hDC, BOOL Force)
if (!GreDeleteObject(hDC))
{
DPRINT1("DC_FreeDC failed\n");
+ return FALSE;
}
}
else
{
DPRINT1("Attempted to Delete 0x%p currently being destroyed!!!\n", hDC);
+ return FALSE;
}
return TRUE;