mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 20:43:00 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
794
win32ss/gdi/ntgdi/dcobjs.c
Normal file
794
win32ss/gdi/ntgdi/dcobjs.c
Normal file
|
@ -0,0 +1,794 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Win32k subsystem
|
||||
* PURPOSE: Functions for creation and destruction of DCs
|
||||
* FILE: win32ss/gdi/ntgdi/dcobjs.c
|
||||
* PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org)
|
||||
*/
|
||||
|
||||
#include <win32k.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
DC_vUpdateFillBrush(PDC pdc)
|
||||
{
|
||||
PDC_ATTR pdcattr = pdc->pdcattr;
|
||||
PBRUSH pbrFill;
|
||||
|
||||
/* Check if the brush handle has changed */
|
||||
if (pdcattr->hbrush != pdc->dclevel.pbrFill->BaseObject.hHmgr)
|
||||
{
|
||||
/* Try to lock the new brush */
|
||||
pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush);
|
||||
if (pbrFill)
|
||||
{
|
||||
/* Unlock old brush, set new brush */
|
||||
BRUSH_ShareUnlockBrush(pdc->dclevel.pbrFill);
|
||||
pdc->dclevel.pbrFill = pbrFill;
|
||||
|
||||
/* Mark eboFill as dirty */
|
||||
pdcattr->ulDirty_ |= DIRTY_FILL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid brush handle, restore old one */
|
||||
pdcattr->hbrush = pdc->dclevel.pbrFill->BaseObject.hHmgr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the EBRUSHOBJ needs update */
|
||||
if (pdcattr->ulDirty_ & DIRTY_FILL)
|
||||
{
|
||||
/* Update eboFill */
|
||||
EBRUSHOBJ_vUpdateFromDC(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
|
||||
}
|
||||
|
||||
/* Check for DC brush */
|
||||
if (pdcattr->hbrush == StockObjects[DC_BRUSH])
|
||||
{
|
||||
/* Update the eboFill's solid color */
|
||||
EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboFill, pdcattr->crBrushClr);
|
||||
}
|
||||
|
||||
/* Clear flags */
|
||||
pdcattr->ulDirty_ &= ~(DIRTY_FILL | DC_BRUSH_DIRTY);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
DC_vUpdateLineBrush(PDC pdc)
|
||||
{
|
||||
PDC_ATTR pdcattr = pdc->pdcattr;
|
||||
PBRUSH pbrLine;
|
||||
|
||||
/* Check if the pen handle has changed */
|
||||
if (pdcattr->hpen != pdc->dclevel.pbrLine->BaseObject.hHmgr)
|
||||
{
|
||||
/* Try to lock the new pen */
|
||||
pbrLine = PEN_ShareLockPen(pdcattr->hpen);
|
||||
if (pbrLine)
|
||||
{
|
||||
/* Unlock old brush, set new brush */
|
||||
BRUSH_ShareUnlockBrush(pdc->dclevel.pbrLine);
|
||||
pdc->dclevel.pbrLine = pbrLine;
|
||||
|
||||
/* Mark eboLine as dirty */
|
||||
pdcattr->ulDirty_ |= DIRTY_LINE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid pen handle, restore old one */
|
||||
pdcattr->hpen = pdc->dclevel.pbrLine->BaseObject.hHmgr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the EBRUSHOBJ needs update */
|
||||
if (pdcattr->ulDirty_ & DIRTY_LINE)
|
||||
{
|
||||
/* Update eboLine */
|
||||
EBRUSHOBJ_vUpdateFromDC(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
|
||||
}
|
||||
|
||||
/* Check for DC pen */
|
||||
if (pdcattr->hpen == StockObjects[DC_PEN])
|
||||
{
|
||||
/* Update the eboLine's solid color */
|
||||
EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboLine, pdcattr->crPenClr);
|
||||
}
|
||||
|
||||
/* Clear flags */
|
||||
pdcattr->ulDirty_ &= ~(DIRTY_LINE | DC_PEN_DIRTY);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
DC_vUpdateTextBrush(PDC pdc)
|
||||
{
|
||||
PDC_ATTR pdcattr = pdc->pdcattr;
|
||||
|
||||
/* 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_vUpdateFromDC(&pdc->eboText, pbrDefaultBrush, pdc);
|
||||
|
||||
/* Update the eboText's solid color */
|
||||
EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboText, pdcattr->crForegroundClr);
|
||||
|
||||
/* Clear flag */
|
||||
pdcattr->ulDirty_ &= ~DIRTY_TEXT;
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
DC_vUpdateBackgroundBrush(PDC pdc)
|
||||
{
|
||||
PDC_ATTR pdcattr = pdc->pdcattr;
|
||||
|
||||
if(pdcattr->ulDirty_ & DIRTY_BACKGROUND)
|
||||
EBRUSHOBJ_vUpdateFromDC(&pdc->eboBackground, pbrDefaultBrush, pdc);
|
||||
|
||||
/* Update the eboBackground's solid color */
|
||||
EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboBackground, pdcattr->crBackgroundClr);
|
||||
|
||||
/* Clear flag */
|
||||
pdcattr->ulDirty_ &= ~DIRTY_BACKGROUND;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DC_vSetBrushOrigin(PDC pdc, LONG x, LONG y)
|
||||
{
|
||||
/* Set the brush origin */
|
||||
pdc->dclevel.ptlBrushOrigin.x = x;
|
||||
pdc->dclevel.ptlBrushOrigin.y = y;
|
||||
|
||||
/* Set the fill origin */
|
||||
pdc->ptlFillOrigin.x = x + pdc->ptlDCOrig.x;
|
||||
pdc->ptlFillOrigin.y = y + pdc->ptlDCOrig.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* \name NtGdiSetBrushOrg
|
||||
*
|
||||
* \brief Sets the brush origin that GDI uses when drawing with pattern
|
||||
* brushes. The brush origin is relative to the DC origin.
|
||||
*
|
||||
* @implemented
|
||||
*/
|
||||
_Success_(return!=FALSE)
|
||||
__kernel_entry
|
||||
BOOL
|
||||
APIENTRY
|
||||
NtGdiSetBrushOrg(
|
||||
_In_ HDC hdc,
|
||||
_In_ INT x,
|
||||
_In_ INT y,
|
||||
_Out_opt_ LPPOINT pptOut)
|
||||
{
|
||||
|
||||
POINT ptOut;
|
||||
/* Call the internal function */
|
||||
BOOL Ret = GreSetBrushOrg( hdc, x, y, &ptOut);
|
||||
if (Ret)
|
||||
{
|
||||
/* Check if the old origin was requested */
|
||||
if (pptOut != NULL)
|
||||
{
|
||||
/* Enter SEH for buffer transfer */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Probe and copy the old origin */
|
||||
ProbeForWrite(pptOut, sizeof(POINT), 1);
|
||||
*pptOut = ptOut;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
_SEH2_YIELD(return FALSE);
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
HPALETTE
|
||||
NTAPI
|
||||
GdiSelectPalette(
|
||||
HDC hDC,
|
||||
HPALETTE hpal,
|
||||
BOOL ForceBackground)
|
||||
{
|
||||
PDC pdc;
|
||||
HPALETTE oldPal = NULL;
|
||||
PPALETTE ppal;
|
||||
|
||||
// FIXME: Mark the palette as a [fore\back]ground pal
|
||||
pdc = DC_LockDc(hDC);
|
||||
if (!pdc)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if this is a valid palette handle */
|
||||
ppal = PALETTE_ShareLockPalette(hpal);
|
||||
if (!ppal)
|
||||
{
|
||||
DC_UnlockDc(pdc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// FIXME: we shouldn't dereference pSurface when the PDEV is not locked
|
||||
/* Is this a valid palette for this depth? */
|
||||
if ((!pdc->dclevel.pSurface) ||
|
||||
(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;
|
||||
pdc->dclevel.hpal = hpal;
|
||||
DC_vSelectPalette(pdc, ppal);
|
||||
|
||||
/* Mark the brushes invalid */
|
||||
pdc->pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE |
|
||||
DIRTY_BACKGROUND | DIRTY_TEXT;
|
||||
}
|
||||
|
||||
if(pdc->dctype == DCTYPE_MEMORY)
|
||||
{
|
||||
// This didn't work anyway
|
||||
//IntGdiRealizePalette(hDC);
|
||||
}
|
||||
|
||||
PALETTE_ShareUnlockPalette(ppal);
|
||||
DC_UnlockDc(pdc);
|
||||
|
||||
return oldPal;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HBRUSH
|
||||
APIENTRY
|
||||
NtGdiSelectBrush(
|
||||
IN HDC hDC,
|
||||
IN HBRUSH hBrush)
|
||||
{
|
||||
PDC pDC;
|
||||
HBRUSH hOrgBrush;
|
||||
|
||||
if (hDC == NULL || hBrush == NULL) return NULL;
|
||||
|
||||
pDC = DC_LockDc(hDC);
|
||||
if (!pDC)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Simply return the user mode value, without checking */
|
||||
hOrgBrush = pDC->pdcattr->hbrush;
|
||||
pDC->pdcattr->hbrush = hBrush;
|
||||
DC_vUpdateFillBrush(pDC);
|
||||
|
||||
DC_UnlockDc(pDC);
|
||||
|
||||
return hOrgBrush;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HPEN
|
||||
APIENTRY
|
||||
NtGdiSelectPen(
|
||||
IN HDC hDC,
|
||||
IN HPEN hPen)
|
||||
{
|
||||
PDC pDC;
|
||||
HPEN hOrgPen;
|
||||
|
||||
if (hDC == NULL || hPen == NULL) return NULL;
|
||||
|
||||
pDC = DC_LockDc(hDC);
|
||||
if (!pDC)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Simply return the user mode value, without checking */
|
||||
hOrgPen = pDC->pdcattr->hpen;
|
||||
pDC->pdcattr->hpen = hPen;
|
||||
DC_vUpdateLineBrush(pDC);
|
||||
|
||||
DC_UnlockDc(pDC);
|
||||
|
||||
return hOrgPen;
|
||||
}
|
||||
|
||||
BOOL
|
||||
NTAPI
|
||||
DC_bIsBitmapCompatible(PDC pdc, PSURFACE psurf)
|
||||
{
|
||||
ULONG cBitsPixel;
|
||||
|
||||
/* Must be an API bitmap */
|
||||
if (!(psurf->flags & API_BITMAP)) return FALSE;
|
||||
|
||||
/* DIB sections are always compatible */
|
||||
if (psurf->hSecure != NULL) return TRUE;
|
||||
|
||||
/* See if this is the same PDEV */
|
||||
if (psurf->SurfObj.hdev == (HDEV)pdc->ppdev)
|
||||
return TRUE;
|
||||
|
||||
/* Get the bit depth of the bitmap */
|
||||
cBitsPixel = gajBitsPerFormat[psurf->SurfObj.iBitmapFormat];
|
||||
|
||||
/* 1 BPP is compatible */
|
||||
if ((cBitsPixel == 1) || (cBitsPixel == pdc->ppdev->gdiinfo.cBitsPixel))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HBITMAP
|
||||
APIENTRY
|
||||
NtGdiSelectBitmap(
|
||||
IN HDC hdc,
|
||||
IN HBITMAP hbmp)
|
||||
{
|
||||
PDC pdc;
|
||||
HBITMAP hbmpOld;
|
||||
PSURFACE psurfNew, psurfOld;
|
||||
HDC hdcOld;
|
||||
ASSERT_NOGDILOCKS();
|
||||
|
||||
/* Verify parameters */
|
||||
if (hdc == NULL || hbmp == NULL) return NULL;
|
||||
|
||||
/* First lock the DC */
|
||||
pdc = DC_LockDc(hdc);
|
||||
if (!pdc)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Must be a memory dc to select a bitmap */
|
||||
if (pdc->dctype != DC_TYPE_MEMORY)
|
||||
{
|
||||
DC_UnlockDc(pdc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Save the old bitmap */
|
||||
psurfOld = pdc->dclevel.pSurface;
|
||||
|
||||
/* Check if there is a bitmap selected */
|
||||
if (psurfOld)
|
||||
{
|
||||
/* Get the old bitmap's handle */
|
||||
hbmpOld = psurfOld->BaseObject.hHmgr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use the default bitmap */
|
||||
hbmpOld = StockObjects[DEFAULT_BITMAP];
|
||||
}
|
||||
|
||||
/* Check if the new bitmap is already selected */
|
||||
if (hbmp == hbmpOld)
|
||||
{
|
||||
/* Unlock the DC and return the old bitmap */
|
||||
DC_UnlockDc(pdc);
|
||||
return hbmpOld;
|
||||
}
|
||||
|
||||
/* Check if the default bitmap was passed */
|
||||
if (hbmp == StockObjects[DEFAULT_BITMAP])
|
||||
{
|
||||
psurfNew = NULL;
|
||||
|
||||
/* Default bitmap is 1x1 pixel */
|
||||
pdc->dclevel.sizl.cx = 1;
|
||||
pdc->dclevel.sizl.cy = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reference the new bitmap and check if it's valid */
|
||||
psurfNew = SURFACE_ShareLockSurface(hbmp);
|
||||
if (!psurfNew)
|
||||
{
|
||||
DC_UnlockDc(pdc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if the bitmap is compatible with the dc */
|
||||
if (!DC_bIsBitmapCompatible(pdc, psurfNew))
|
||||
{
|
||||
/* Dereference the bitmap, unlock the DC and fail. */
|
||||
SURFACE_ShareUnlockSurface(psurfNew);
|
||||
DC_UnlockDc(pdc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set the bitmap's hdc and check if it was set before */
|
||||
hdcOld = InterlockedCompareExchangePointer((PVOID*)&psurfNew->hdc, hdc, 0);
|
||||
if (hdcOld != NULL)
|
||||
{
|
||||
/* The bitmap is already selected into a different DC */
|
||||
ASSERT(hdcOld != hdc);
|
||||
|
||||
/* Dereference the bitmap, unlock the DC and fail. */
|
||||
SURFACE_ShareUnlockSurface(psurfNew);
|
||||
DC_UnlockDc(pdc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Copy the bitmap size */
|
||||
pdc->dclevel.sizl = psurfNew->SurfObj.sizlBitmap;
|
||||
|
||||
/* Check if the bitmap is a dibsection */
|
||||
if (psurfNew->hSecure)
|
||||
{
|
||||
/* Set DIBSECTION attribute */
|
||||
pdc->pdcattr->ulDirty_ |= DC_DIBSECTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove DIBSECTION attribute */
|
||||
pdc->pdcattr->ulDirty_ &= ~DC_DIBSECTION;
|
||||
}
|
||||
}
|
||||
|
||||
/* Select the new bitmap */
|
||||
pdc->dclevel.pSurface = psurfNew;
|
||||
|
||||
/* Check if there was a bitmap selected before */
|
||||
if (psurfOld)
|
||||
{
|
||||
/* Reset hdc of the old bitmap, it isn't selected anymore */
|
||||
psurfOld->hdc = NULL;
|
||||
|
||||
/* Dereference the old bitmap */
|
||||
SURFACE_ShareUnlockSurface(psurfOld);
|
||||
}
|
||||
|
||||
/* Mark the DC brushes and the RAO region invalid */
|
||||
pdc->pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE;
|
||||
pdc->fs |= DC_FLAG_DIRTY_RAO;
|
||||
|
||||
/* Update the system region */
|
||||
REGION_SetRectRgn(pdc->prgnVis,
|
||||
0,
|
||||
0,
|
||||
pdc->dclevel.sizl.cx,
|
||||
pdc->dclevel.sizl.cy);
|
||||
|
||||
/* Unlock the DC */
|
||||
DC_UnlockDc(pdc);
|
||||
|
||||
/* Return the old bitmap handle */
|
||||
return hbmpOld;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
APIENTRY
|
||||
NtGdiSelectClipPath(
|
||||
HDC hDC,
|
||||
int Mode)
|
||||
{
|
||||
PREGION RgnPath;
|
||||
PPATH pPath, pNewPath;
|
||||
BOOL success = FALSE;
|
||||
PDC_ATTR pdcattr;
|
||||
PDC pdc;
|
||||
|
||||
pdc = DC_LockDc(hDC);
|
||||
if (!pdc)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
pdcattr = pdc->pdcattr;
|
||||
|
||||
pPath = PATH_LockPath(pdc->dclevel.hPath);
|
||||
if (!pPath)
|
||||
{
|
||||
DC_UnlockDc(pdc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check that path is closed */
|
||||
if (pPath->state != PATH_Closed)
|
||||
{
|
||||
EngSetLastError(ERROR_CAN_NOT_COMPLETE);
|
||||
success = FALSE;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Construct a region from the path */
|
||||
RgnPath = IntSysCreateRectpRgn(0, 0, 0, 0);
|
||||
if (!RgnPath)
|
||||
{
|
||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
DC_UnlockDc(pdc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pNewPath = PATH_FlattenPath(pPath);
|
||||
|
||||
success = PATH_PathToRegion(pNewPath, pdcattr->jFillMode, RgnPath);
|
||||
|
||||
PATH_UnlockPath(pNewPath);
|
||||
PATH_Delete(pNewPath->BaseObject.hHmgr);
|
||||
|
||||
if (success) success = IntGdiExtSelectClipRgn(pdc, RgnPath, Mode) != ERROR;
|
||||
|
||||
REGION_Delete(RgnPath);
|
||||
|
||||
Exit:
|
||||
PATH_UnlockPath(pPath);
|
||||
PATH_Delete(pdc->dclevel.hPath);
|
||||
pdc->dclevel.flPath &= ~DCPATH_ACTIVE;
|
||||
pdc->dclevel.hPath = NULL;
|
||||
|
||||
DC_UnlockDc(pdc);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
HFONT
|
||||
NTAPI
|
||||
DC_hSelectFont(
|
||||
_In_ PDC pdc,
|
||||
_In_ HFONT hlfntNew)
|
||||
{
|
||||
PLFONT plfntNew;
|
||||
HFONT hlfntOld;
|
||||
|
||||
// Legacy crap that will die with font engine rewrite
|
||||
if (!NT_SUCCESS(TextIntRealizeFont(hlfntNew, NULL)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the current selected font */
|
||||
hlfntOld = pdc->dclevel.plfnt->BaseObject.hHmgr;
|
||||
|
||||
/* Check if a new font should be selected */
|
||||
if (hlfntNew != hlfntOld)
|
||||
{
|
||||
/* Lock the new font */
|
||||
plfntNew = LFONT_ShareLockFont(hlfntNew);
|
||||
if (plfntNew)
|
||||
{
|
||||
/* Success, dereference the old font */
|
||||
LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
|
||||
|
||||
/* Select the new font */
|
||||
pdc->dclevel.plfnt = plfntNew;
|
||||
pdc->pdcattr->hlfntNew = hlfntNew;
|
||||
|
||||
/* Update dirty flags */
|
||||
pdc->pdcattr->ulDirty_ |= DIRTY_CHARSET;
|
||||
pdc->pdcattr->ulDirty_ &= ~SLOW_WIDTHS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed, restore old, return NULL */
|
||||
pdc->pdcattr->hlfntNew = hlfntOld;
|
||||
hlfntOld = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return hlfntOld;
|
||||
}
|
||||
|
||||
HFONT
|
||||
APIENTRY
|
||||
NtGdiSelectFont(
|
||||
_In_ HDC hdc,
|
||||
_In_ HFONT hfont)
|
||||
{
|
||||
HFONT hfontOld;
|
||||
PDC pdc;
|
||||
|
||||
/* Check parameters */
|
||||
if ((hdc == NULL) || (hfont == NULL))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Lock the DC */
|
||||
pdc = DC_LockDc(hdc);
|
||||
if (!pdc)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Call the internal function */
|
||||
hfontOld = DC_hSelectFont(pdc, hfont);
|
||||
|
||||
/* Unlock the DC */
|
||||
DC_UnlockDc(pdc);
|
||||
|
||||
/* Return the previously selected font */
|
||||
return hfontOld;
|
||||
}
|
||||
|
||||
HANDLE
|
||||
APIENTRY
|
||||
NtGdiGetDCObject(HDC hDC, INT ObjectType)
|
||||
{
|
||||
HGDIOBJ SelObject;
|
||||
DC *pdc;
|
||||
PDC_ATTR pdcattr;
|
||||
|
||||
/* From Wine: GetCurrentObject does not SetLastError() on a null object */
|
||||
if(!hDC) return NULL;
|
||||
|
||||
if(!(pdc = DC_LockDc(hDC)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
pdcattr = pdc->pdcattr;
|
||||
|
||||
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||
DC_vUpdateFillBrush(pdc);
|
||||
|
||||
if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
|
||||
DC_vUpdateLineBrush(pdc);
|
||||
|
||||
switch(ObjectType)
|
||||
{
|
||||
case GDI_OBJECT_TYPE_EXTPEN:
|
||||
case GDI_OBJECT_TYPE_PEN:
|
||||
SelObject = pdcattr->hpen;
|
||||
break;
|
||||
|
||||
case GDI_OBJECT_TYPE_BRUSH:
|
||||
SelObject = pdcattr->hbrush;
|
||||
break;
|
||||
|
||||
case GDI_OBJECT_TYPE_PALETTE:
|
||||
SelObject = pdc->dclevel.hpal;
|
||||
break;
|
||||
|
||||
case GDI_OBJECT_TYPE_FONT:
|
||||
SelObject = pdcattr->hlfntNew;
|
||||
break;
|
||||
|
||||
case GDI_OBJECT_TYPE_BITMAP:
|
||||
{
|
||||
SURFACE *psurf = pdc->dclevel.pSurface;
|
||||
SelObject = psurf ? psurf->BaseObject.hHmgr : StockObjects[DEFAULT_BITMAP];
|
||||
break;
|
||||
}
|
||||
|
||||
case GDI_OBJECT_TYPE_COLORSPACE:
|
||||
DPRINT1("FIXME: NtGdiGetCurrentObject() ObjectType OBJ_COLORSPACE not supported yet!\n");
|
||||
// SelObject = dc->dclevel.pColorSpace.BaseObject.hHmgr; ?
|
||||
SelObject = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
SelObject = NULL;
|
||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||
break;
|
||||
}
|
||||
|
||||
DC_UnlockDc(pdc);
|
||||
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;
|
||||
PREGION prgnSrc = NULL;
|
||||
|
||||
pdc = DC_LockDc(hdc);
|
||||
if (!pdc)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (iCode)
|
||||
{
|
||||
case CLIPRGN:
|
||||
prgnSrc = pdc->dclevel.prgnClip;
|
||||
break;
|
||||
|
||||
case METARGN:
|
||||
prgnSrc = pdc->dclevel.prgnMeta;
|
||||
break;
|
||||
|
||||
case APIRGN:
|
||||
if (pdc->fs & DC_FLAG_DIRTY_RAO)
|
||||
CLIPPING_UpdateGCRegion(pdc);
|
||||
if (pdc->prgnAPI)
|
||||
{
|
||||
prgnSrc = pdc->prgnAPI;
|
||||
}
|
||||
else if (pdc->dclevel.prgnClip)
|
||||
{
|
||||
prgnSrc = pdc->dclevel.prgnClip;
|
||||
}
|
||||
else if (pdc->dclevel.prgnMeta)
|
||||
{
|
||||
prgnSrc = pdc->dclevel.prgnMeta;
|
||||
}
|
||||
break;
|
||||
|
||||
case SYSRGN:
|
||||
prgnSrc = pdc->prgnVis;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (prgnSrc)
|
||||
{
|
||||
PREGION prgnDest = REGION_LockRgn(hrgnDest);
|
||||
if (prgnDest)
|
||||
{
|
||||
ret = IntGdiCombineRgn(prgnDest, prgnSrc, 0, RGN_COPY) == ERROR ? -1 : 1;
|
||||
if ((ret == 1) && (iCode == SYSRGN))
|
||||
{
|
||||
/// \todo FIXME This is not really correct, since we already modified the region
|
||||
ret = REGION_bOffsetRgn(prgnDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
||||
}
|
||||
REGION_UnlockRgn(prgnDest);
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
DC_UnlockDc(pdc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ULONG
|
||||
APIENTRY
|
||||
NtGdiEnumObjects(
|
||||
IN HDC hdc,
|
||||
IN INT iObjectType,
|
||||
IN ULONG cjBuf,
|
||||
OUT OPTIONAL PVOID pvBuf)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue