* PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org)
*/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
{
PDC_ATTR pdcattr = pdc->pdcattr;
PBRUSH pbrFill;
- XLATEOBJ *pxlo = NULL;
/* Check if the brush handle has changed */
if (pdcattr->hbrush != pdc->dclevel.pbrFill->BaseObject.hHmgr)
}
}
- /* ROS HACK, should use surf xlate */
- pxlo = IntCreateBrushXlate(pdc->dclevel.pbrFill,
- pdc->dclevel.pSurface,
- pdc->pdcattr->crBackgroundClr);
-
/* Check if the EBRUSHOBJ needs update */
if (pdcattr->ulDirty_ & DIRTY_FILL)
{
- pbrFill = pdc->dclevel.pbrFill;
-
- /* Update eboFill, realizing it, if needed */
- EBRUSHOBJ_vUpdate(&pdc->eboFill, pbrFill, pdc);
+ /* Update eboFill */
+ EBRUSHOBJ_vUpdate(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
}
/* Check for DC brush */
if (pdcattr->hbrush == StockObjects[DC_BRUSH])
{
+ /* ROS HACK, should use surf xlate */
/* Update the eboFill's solid color */
- EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboFill, pdcattr->crPenClr, pxlo);
+ EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboFill, pdcattr->crPenClr);
}
- EngDeleteXlate(pxlo);
-
/* Clear flags */
pdcattr->ulDirty_ &= ~(DIRTY_FILL | DC_BRUSH_DIRTY);
}
{
PDC_ATTR pdcattr = pdc->pdcattr;
PBRUSH pbrLine;
- XLATEOBJ *pxlo;
/* Check if the pen handle has changed */
if (pdcattr->hpen != pdc->dclevel.pbrLine->BaseObject.hHmgr)
}
}
- /* ROS HACK, should use surf xlate */
- pxlo = IntCreateBrushXlate(pdc->dclevel.pbrFill,
- pdc->dclevel.pSurface,
- pdc->pdcattr->crBackgroundClr);
-
/* Check if the EBRUSHOBJ needs update */
if (pdcattr->ulDirty_ & DIRTY_LINE)
{
- pbrLine = pdc->dclevel.pbrLine;
-
- /* Update eboLine, realizing it, if needed */
- EBRUSHOBJ_vUpdate(&pdc->eboLine, pbrLine, pdc);
+ /* Update eboLine */
+ EBRUSHOBJ_vUpdate(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
}
/* Check for DC pen */
if (pdcattr->hpen == StockObjects[DC_PEN])
{
/* Update the eboLine's solid color */
- EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboLine, pdcattr->crPenClr, pxlo);
+ EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboLine, pdcattr->crPenClr);
}
- EngDeleteXlate(pxlo);
-
/* Clear flags */
pdcattr->ulDirty_ &= ~(DIRTY_LINE | DC_PEN_DIRTY);
}
DC_vUpdateTextBrush(PDC pdc)
{
PDC_ATTR pdcattr = pdc->pdcattr;
- XLATEOBJ *pxlo = NULL;
- SURFACE *psurf;
- HPALETTE hpal;
- psurf = pdc->dclevel.pSurface;
- if (psurf)
- {
- hpal = psurf->hDIBPalette;
- if (!hpal) hpal = pPrimarySurface->DevInfo.hpalDefault;
- pxlo = IntEngCreateXlate(0, PAL_RGB, hpal, NULL);
- }
+ /* Timo : The text brush should never be changed.
+ * Jérôme : Yeah, but its palette must be updated anyway! */
+ if(pdcattr->ulDirty_ & DIRTY_TEXT)
+ EBRUSHOBJ_vUpdate(&pdc->eboText, pbrDefaultBrush, pdc);
/* Update the eboText's solid color */
- EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, pdcattr->crForegroundClr, pxlo);
-
- if (pxlo)
- {
- EngDeleteXlate(pxlo);
- }
+ EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, pdcattr->crForegroundClr);
/* Clear flag */
pdcattr->ulDirty_ &= ~DIRTY_TEXT;
DC_vUpdateBackgroundBrush(PDC pdc)
{
PDC_ATTR pdcattr = pdc->pdcattr;
- XLATEOBJ *pxlo = NULL;
- SURFACE *psurf;
- HPALETTE hpal;
- psurf = pdc->dclevel.pSurface;
- if (psurf)
- {
- hpal = psurf->hDIBPalette;
- if (!hpal) hpal = pPrimarySurface->DevInfo.hpalDefault;
- pxlo = IntEngCreateXlate(0, PAL_RGB, hpal, NULL);
- }
+ if(pdcattr->ulDirty_ & DIRTY_BACKGROUND)
+ EBRUSHOBJ_vUpdate(&pdc->eboBackground, pbrDefaultBrush, pdc);
/* Update the eboBackground's solid color */
- EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, pdcattr->crBackgroundClr, pxlo);
-
- if (pxlo)
- {
- EngDeleteXlate(pxlo);
- }
+ EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, pdcattr->crBackgroundClr);
/* Clear flag */
pdcattr->ulDirty_ &= ~DIRTY_BACKGROUND;
return NULL;
}
- // FIXME: This looks wrong
/* Is this a valid palette for this depth? */
- if ((pdc->rosdc.bitsPerPixel <= 8 && ppal->Mode == PAL_INDEXED) ||
- (pdc->rosdc.bitsPerPixel > 8))
+ if ((BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) <= 8
+ && (ppal->flFlags & PAL_INDEXED)) ||
+ (BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) > 8))
{
/* Get old palette, set new one */
oldPal = pdc->dclevel.hpal;
HBITMAP
APIENTRY
NtGdiSelectBitmap(
- IN HDC hDC,
- IN HBITMAP hBmp)
+ IN HDC hdc,
+ IN HBITMAP hbmp)
{
- PDC pDC;
+ PDC pdc;
PDC_ATTR pdcattr;
- HBITMAP hOrgBmp;
- PSURFACE psurfBmp, psurfOld;
+ HBITMAP hbmpOld;
+ PSURFACE psurfNew;
HRGN hVisRgn;
+ SIZEL sizlBitmap = {1, 1};
+ HDC hdcOld;
+ ASSERT_NOGDILOCKS();
- if (hDC == NULL || hBmp == NULL) return NULL;
+ /* Verify parameters */
+ if (hdc == NULL || hbmp == NULL) return NULL;
- pDC = DC_LockDc(hDC);
- if (!pDC)
+ /* First lock the DC */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
{
return NULL;
}
- pdcattr = pDC->pdcattr;
+ pdcattr = pdc->pdcattr;
- /* must be memory dc to select bitmap */
- if (pDC->dctype != DC_TYPE_MEMORY)
+ /* Must be a memory dc to select a bitmap */
+ if (pdc->dctype != DC_TYPE_MEMORY)
{
- DC_UnlockDc(pDC);
+ DC_UnlockDc(pdc);
return NULL;
}
- psurfBmp = SURFACE_LockSurface(hBmp);
- if (!psurfBmp)
+ /* Check if there was a bitmap selected before */
+ if (pdc->dclevel.pSurface)
{
- DC_UnlockDc(pDC);
- return NULL;
+ /* Return its handle */
+ hbmpOld = pdc->dclevel.pSurface->BaseObject.hHmgr;
+ }
+ else
+ {
+ /* Return default bitmap */
+ hbmpOld = StockObjects[DEFAULT_BITMAP];
}
- /* Get the handle for the old bitmap */
- psurfOld = pDC->dclevel.pSurface;
- hOrgBmp = psurfOld ? psurfOld->BaseObject.hHmgr : NULL;
-
- /* Release the old bitmap, reference the new */
- DC_vSelectSurface(pDC, psurfBmp);
-
- // If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
- psurfBmp->hDC = hDC;
-
- // if we're working with a DIB, get the palette
- // [fixme: only create if the selected palette is null]
- if (psurfBmp->hSecure)
+ /* Check if the default bitmap was passed */
+ if (hbmp == StockObjects[DEFAULT_BITMAP])
{
-// pDC->rosdc.bitsPerPixel = psurfBmp->dib->dsBmih.biBitCount; ???
- pDC->rosdc.bitsPerPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
+ psurfNew = NULL;
+
+ // HACK
+ psurfNew = SURFACE_ShareLockSurface(hbmp);
}
else
{
- pDC->rosdc.bitsPerPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
+ /* Reference the new bitmap and check if it's valid */
+ psurfNew = SURFACE_ShareLockSurface(hbmp);
+ if (!psurfNew)
+ {
+ DC_UnlockDc(pdc);
+ return NULL;
+ }
+
+ /* Set the bitmp's hdc */
+ hdcOld = InterlockedCompareExchangePointer((PVOID*)&psurfNew->hdc, hdc, 0);
+ if (hdcOld != NULL && hdcOld != hdc)
+ {
+ /* The bitmap is already selected, fail */
+ SURFACE_ShareUnlockSurface(psurfNew);
+ DC_UnlockDc(pdc);
+ return NULL;
+ }
+
+ /* Get the bitmap size */
+ sizlBitmap = psurfNew->SurfObj.sizlBitmap;
+
+ /* Check if the bitmap is a dibsection */
+ if(psurfNew->hSecure)
+ {
+ /* Set DIBSECTION attribute */
+ pdcattr->ulDirty_ |= DC_DIBSECTION;
+ }
+ else
+ {
+ pdcattr->ulDirty_ &= ~DC_DIBSECTION;
+ }
}
- /* FIXME; improve by using a region without a handle and selecting it */
- hVisRgn = NtGdiCreateRectRgn(0,
- 0,
- psurfBmp->SurfObj.sizlBitmap.cx,
- psurfBmp->SurfObj.sizlBitmap.cy);
+ /* Select the new surface, release the old */
+ DC_vSelectSurface(pdc, psurfNew);
+
+ /* Set the new size */
+ pdc->dclevel.sizl = sizlBitmap;
- /* Release the exclusive lock */
- SURFACE_UnlockSurface(psurfBmp);
+ /* Release one reference we added */
+ SURFACE_ShareUnlockSurface(psurfNew);
- /* Mark the brushes invalid */
+ /* Mark the dc brushes invalid */
pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE;
- DC_UnlockDc(pDC);
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+ /* FIXME; improve by using a region without a handle and selecting it */
+ hVisRgn = IntSysCreateRectRgn( 0,
+ 0,
+ sizlBitmap.cx,
+ sizlBitmap.cy);
if (hVisRgn)
{
- GdiSelectVisRgn(hDC, hVisRgn);
- GreDeleteObject(hVisRgn);
+ GdiSelectVisRgn(hdc, hVisRgn);
+ REGION_FreeRgnByHandle(hVisRgn);
}
- return hOrgBmp;
+ /* Return the old bitmp handle */
+ return hbmpOld;
}
pdc = DC_LockDc(hDC);
if (!pdc)
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
pdcattr = pdc->pdcattr;
/* Check that path is closed */
if (pPath->state != PATH_Closed)
{
- SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+ EngSetLastError(ERROR_CAN_NOT_COMPLETE);
+ DC_UnlockDc(pdc);
return FALSE;
}
if(!(pdc = DC_LockDc(hDC)))
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
pdcattr = pdc->pdcattr;
default:
SelObject = NULL;
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
break;
}
return SelObject;
}
+/* See wine, msdn, osr and Feng Yuan - Windows Graphics Programming Win32 Gdi And Directdraw
+
+ 1st: http://www.codeproject.com/gdi/cliprgnguide.asp is wrong!
+
+ The intersection of the clip with the meta region is not Rao it's API!
+ Go back and read 7.2 Clipping pages 418-19:
+ Rao = API & Vis:
+ 1) The Rao region is the intersection of the API region and the system region,
+ named after the Microsoft engineer who initially proposed it.
+ 2) The Rao region can be calculated from the API region and the system region.
+
+ API:
+ API region is the intersection of the meta region and the clipping region,
+ clearly named after the fact that it is controlled by GDI API calls.
+*/
+INT
+APIENTRY
+NtGdiGetRandomRgn(
+ HDC hdc,
+ HRGN hrgnDest,
+ INT iCode)
+{
+ INT ret = 0;
+ PDC pdc;
+ HRGN hrgnSrc = NULL;
+ POINTL ptlOrg;
+
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
+ {
+ EngSetLastError(ERROR_INVALID_HANDLE);
+ return -1;
+ }
+
+ switch (iCode)
+ {
+ case CLIPRGN:
+ hrgnSrc = pdc->rosdc.hClipRgn;
+// if (pdc->dclevel.prgnClip) hrgnSrc = pdc->dclevel.prgnClip->BaseObject.hHmgr;
+ break;
+ case METARGN:
+ if (pdc->dclevel.prgnMeta)
+ hrgnSrc = pdc->dclevel.prgnMeta->BaseObject.hHmgr;
+ break;
+ case APIRGN:
+ if (pdc->prgnAPI) hrgnSrc = pdc->prgnAPI->BaseObject.hHmgr;
+// else if (pdc->dclevel.prgnClip) hrgnSrc = pdc->dclevel.prgnClip->BaseObject.hHmgr;
+ else if (pdc->rosdc.hClipRgn) hrgnSrc = pdc->rosdc.hClipRgn;
+ else if (pdc->dclevel.prgnMeta) hrgnSrc = pdc->dclevel.prgnMeta->BaseObject.hHmgr;
+ break;
+ case SYSRGN:
+ if (pdc->prgnVis) hrgnSrc = pdc->prgnVis->BaseObject.hHmgr;
+ break;
+ default:
+ hrgnSrc = NULL;
+ }
+
+ if (hrgnSrc)
+ {
+ ret = NtGdiCombineRgn(hrgnDest, hrgnSrc, 0, RGN_COPY) == ERROR ? -1 : 1;
+ }
+
+ if (iCode == SYSRGN)
+ {
+ ptlOrg = pdc->ptlDCOrig;
+ NtGdiOffsetRgn(hrgnDest, ptlOrg.x, ptlOrg.y );
+ }
+
+ DC_UnlockDc(pdc);
+
+ return ret;
+}
+
ULONG
APIENTRY
NtGdiEnumObjects(