* PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org)
*/
-#include <w32k.h>
+#include <win32k.h>
#include <bugcodes.h>
#define NDEBUG
/** Internal functions ********************************************************/
+INIT_FUNCTION
NTSTATUS
+NTAPI
InitDcImpl()
{
psurfDefaultBitmap = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
void
DC_InitHack(PDC pdc)
{
- HRGN hVisRgn;
-
TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL);
pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
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
DCTYPE dctype,
PPDEVOBJ ppdev)
{
- if (dctype == DCTYPE_DIRECT)
- {
- /* Lock ppdev exclusively */
- EngAcquireSemaphore(ppdev->hsemDevLock);
- }
-
/* Setup some basic fields */
pdc->dctype = dctype;
pdc->ppdev = ppdev;
/* Direct DCs get the surface from the PDEV */
pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
- /* Maintain a list of DC attached to this device */
- if(!pdc->dclevel.pSurface->hDC)
- pdc->dclevel.pSurface->hDC = pdc->BaseObject.hHmgr ;
- else
- {
- PDC Surf_Dc = DC_LockDc(pdc->dclevel.pSurface->hDC);
- if(!Surf_Dc)
- {
- DPRINT1("Something went wrong with device DC list!\n");
- /* Save what can be saved ... */
- pdc->dclevel.pSurface->hDC = pdc->BaseObject.hHmgr;
- }
- else
- {
- /* Insert this one at the head of the list */
- pdc->hdcNext = Surf_Dc->BaseObject.hHmgr;
- /* Sanity check */
- ASSERT(NULL == Surf_Dc->hdcPrev);
- Surf_Dc->hdcPrev = pdc->BaseObject.hHmgr ;
- pdc->dclevel.pSurface->hDC = pdc->BaseObject.hHmgr;
- DC_UnlockDc(Surf_Dc);
- }
- }
-
pdc->erclBounds.left = 0x7fffffff;
pdc->erclBounds.top = 0x7fffffff;
pdc->erclBounds.right = 0x80000000;
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];
// pdc->dclevel.pFont = LFONT_ShareLockFont(pdc->dcattr.hlfntNew);
/* Other stuff */
+ pdc->hdcNext = NULL;
+ pdc->hdcPrev = NULL;
pdc->ipfdDevMax = 0x0000ffff;
pdc->ulCopyCount = -1;
pdc->ptlDoBanding.x = 0;
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)
PATH_Delete(pdc->dclevel.hPath);
- if(pdc->dctype == DCTYPE_DIRECT)
- {
- EngAcquireSemaphore(pdc->ppdev->hsemDevLock);
- /* Remove it from the list of DC attached to the Device */
- PDC tmpDC = DC_LockDc(pdc->hdcNext);
- if(tmpDC != NULL)
- {
- tmpDC->hdcPrev = pdc->hdcPrev ;
- DC_UnlockDc(tmpDC);
- }
- tmpDC = DC_LockDc(pdc->hdcPrev);
- if(tmpDC != NULL)
- {
- tmpDC->hdcNext = pdc->hdcNext ;
- DC_UnlockDc(tmpDC);
- }
- /* Reassign list head if needed */
- if(pdc->BaseObject.hHmgr == pdc->dclevel.pSurface->hDC)
- {
- /* Sanity check */
- ASSERT(pdc->hdcPrev == NULL);
- pdc->dclevel.pSurface->hDC = pdc->hdcNext;
- }
- EngReleaseSemaphore(pdc->ppdev->hsemDevLock) ;
- }
-
if(pdc->dclevel.pSurface)
SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface);
+
PDEVOBJ_vRelease(pdc->ppdev) ;
return TRUE;
PDC pDC;
BOOL ret = FALSE;
- /* FIXME: This function has broken error handling */
-
if (!GDIOBJ_SetOwnership(hDC, Owner))
{
DPRINT1("GDIOBJ_SetOwnership failed\n");
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(
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);
+ }
}
}
{
DPRINT1("Attempted to Delete 0x%x currently being destroyed!!!\n", hDC);
}
-
+
return TRUE;
}