GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
GreDeleteObject(hVisRgn);
ASSERT(pdc->prgnVis);
- pdc->rosdc.bitsPerPixel = pdc->ppdev->gdiinfo.cBitsPixel *
- pdc->ppdev->gdiinfo.cPlanes;
}
VOID
DCTYPE dctype,
PPDEVOBJ ppdev)
{
+ if (dctype == DCTYPE_DIRECT)
+ {
+ /* Lock ppdev exclusively */
+ EngAcquireSemaphore(ppdev->hsemDevLock);
+ }
/* Setup some basic fields */
pdc->dctype = dctype;
if (dctype == DCTYPE_DIRECT)
{
+ PDC pdcTmp;
/* Direct DCs get the surface from the PDEV */
pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
+ /* Maintain a list of DC attached to this device */
+ /* We must sort them so when locking them one after the other we don't risk deadlocks */
+ /* The greatest the first, as in GDIOBJ_LockMultiplObjs */
+ if((ULONG_PTR)pdc->dclevel.pSurface->hDC < (ULONG_PTR)pdc->BaseObject.hHmgr)
+ {
+ /* Insert it at the head of the list */
+ pdc->hdcNext = pdc->dclevel.pSurface->hDC ;
+ pdc->dclevel.pSurface->hDC = pdc->BaseObject.hHmgr ;
+ pdcTmp = DC_LockDc(pdc->hdcNext);
+ if(pdcTmp)
+ {
+ pdcTmp->hdcPrev = pdc->BaseObject.hHmgr ;
+ DC_UnlockDc(pdcTmp);
+ }
+ }
+ else
+ {
+ HDC hdcTmp = pdc->dclevel.pSurface->hDC;
+ HDC hdcNext = NULL ;
+ HDC hdcPrev = NULL ;
+ /* Find its place */
+ while((ULONG_PTR)hdcTmp > (ULONG_PTR)pdc->BaseObject.hHmgr)
+ {
+ pdcTmp = DC_LockDc(hdcTmp);
+ hdcNext = hdcTmp ;
+ hdcPrev = pdcTmp->hdcPrev ;
+ hdcTmp = pdcTmp->hdcNext ;
+ DC_UnlockDc(pdcTmp);
+ }
+ pdc->hdcPrev = hdcPrev;
+ pdc->hdcNext = hdcNext;
+ /* Insert it */
+ pdcTmp = DC_LockDc(hdcPrev);
+ ASSERT(pdcTmp) ; /* There should always be a previous */
+ pdcTmp->hdcNext = pdc->BaseObject.hHmgr ;
+ DC_UnlockDc(pdcTmp) ;
+
+ pdcTmp = DC_LockDc(hdcNext);
+ if(pdcTmp) /* Last one is NULL */
+ {
+ pdcTmp->hdcPrev = pdc->BaseObject.hHmgr;
+ DC_UnlockDc(pdcTmp);
+ }
+ }
+
pdc->erclBounds.left = 0x7fffffff;
pdc->erclBounds.top = 0x7fffffff;
pdc->erclBounds.right = 0x80000000;
// 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;
if (pdc->rosdc.hClipRgn)
GreDeleteObject(pdc->rosdc.hClipRgn);
if (pdc->prgnVis)
- REGION_FreeRgnByHandle(((PROSRGNDATA)pdc->prgnVis)->BaseObject.hHmgr);
+ REGION_FreeRgnByHandle(pdc->prgnVis->BaseObject.hHmgr);
ASSERT(pdc->rosdc.hGCClipRgn);
if (pdc->rosdc.hGCClipRgn)
GreDeleteObject(pdc->rosdc.hGCClipRgn);
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;
}
INT Index;
PGDI_TABLE_ENTRY Entry;
PDC pDC;
+ BOOL ret = FALSE;
/* FIXME: This function has broken error handling */
These regions do not use attribute sections and when allocated, use
gdiobj level functions.
*/
- if (pDC->rosdc.hClipRgn)
- { // FIXME! HAX!!!
- Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hClipRgn);
- Entry = &GdiHandleTable->Entries[Index];
- if (Entry->UserData) FreeObjectAttr(Entry->UserData);
- Entry->UserData = NULL;
- //
- if (!GDIOBJ_SetOwnership(pDC->rosdc.hClipRgn, Owner)) return FALSE;
- }
- if (pDC->prgnVis)
- { // FIXME! HAX!!!
- Index = GDI_HANDLE_GET_INDEX(((PROSRGNDATA)pDC->prgnVis)->BaseObject.hHmgr);
- Entry = &GdiHandleTable->Entries[Index];
- if (Entry->UserData) FreeObjectAttr(Entry->UserData);
- Entry->UserData = NULL;
- //
- if (!GDIOBJ_SetOwnership(((PROSRGNDATA)pDC->prgnVis)->BaseObject.hHmgr, Owner)) return FALSE;
- }
- if (pDC->rosdc.hGCClipRgn)
- { // FIXME! HAX!!!
- Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hGCClipRgn);
- Entry = &GdiHandleTable->Entries[Index];
- if (Entry->UserData) FreeObjectAttr(Entry->UserData);
- Entry->UserData = NULL;
- //
- if (!GDIOBJ_SetOwnership(pDC->rosdc.hGCClipRgn, Owner)) return FALSE;
- }
- if (pDC->dclevel.hPath)
- {
- if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) return FALSE;
- }
- DC_UnlockDc(pDC);
+ if (pDC->rosdc.hClipRgn)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hClipRgn);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->rosdc.hClipRgn, Owner)) goto leave;
+ }
+ if (pDC->prgnVis)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->prgnVis->BaseObject.hHmgr);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->prgnVis->BaseObject.hHmgr, Owner)) goto leave;
+ }
+ if (pDC->rosdc.hGCClipRgn)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hGCClipRgn);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->rosdc.hGCClipRgn, Owner)) goto leave;
+ }
+ if (pDC->dclevel.hPath)
+ {
+ if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) goto leave;
+ }
+ ret = TRUE;
- return TRUE;
+leave:
+ DC_UnlockDc(pDC);
+
+ return ret;
}
HDC
}
hdc = pdc->BaseObject.hHmgr;
+ /* Lock ppdev and initialize the new DC */
DC_vInitDc(pdc, iType, ppdev);
/* FIXME: HACK! */
DC_InitHack(pdc);
}
hdcNew = pdcNew->BaseObject.hHmgr;
- /* Initialize the new DC */
+ /* Lock ppdev and initialize the new DC */
DC_vInitDc(pdcNew, DCTYPE_MEMORY, ppdev);
/* FIXME: HACK! */
DC_InitHack(pdcNew);
/* Allocate a dc attribute */
DC_AllocDcAttr(pdcNew);
- PDEVOBJ_vRelease(ppdev);
-
// HACK!
DC_vSelectSurface(pdcNew, psurfDefaultBitmap);
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;
}