📄 dc.c
字号:
}
NtGdiDeleteObjectApp (hdcs);
}
DC_UnlockDc( dc );
return success;
}
INT STDCALL
NtGdiSaveDC(HDC hDC)
{
HDC hdcs;
PDC dc, dcs;
INT ret;
DPRINT("NtGdiSaveDC(%lx)\n", hDC);
if (!(hdcs = NtGdiGetDCState(hDC)))
{
return 0;
}
dcs = DC_LockDc (hdcs);
if (dcs == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
dc = DC_LockDc (hDC);
if (dc == NULL)
{
DC_UnlockDc(dcs);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
#if 0
/* Copy path. The reason why path saving / restoring is in SaveDC/
* RestoreDC and not in GetDCState/SetDCState is that the ...DCState
* functions are only in Win16 (which doesn't have paths) and that
* SetDCState doesn't allow us to signal an error (which can happen
* when copying paths).
*/
if (!PATH_AssignGdiPath (&dcs->w.path, &dc->w.path))
{
NtGdiDeleteObjectApp (hdcs);
return 0;
}
#endif
DC_SetNextDC (dcs, DC_GetNextDC (dc));
DC_SetNextDC (dc, hdcs);
ret = ++dc->saveLevel;
DC_UnlockDc( dcs );
DC_UnlockDc( dc );
return ret;
}
HGDIOBJ
STDCALL
NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj)
{
HGDIOBJ objOrg = NULL; // default to failure
BITMAPOBJ *pb;
PDC dc;
PGDIBRUSHOBJ pen;
PGDIBRUSHOBJ brush;
XLATEOBJ *XlateObj;
DWORD objectType;
HRGN hVisRgn;
BOOLEAN Failed;
if (!hDC || !hGDIObj)
{
/* From Wine:
* SelectObject() with a NULL DC returns 0 and sets ERROR_INVALID_HANDLE.
* Note: Under XP at least invalid ptrs can also be passed, not just NULL;
* Don't test that here in case it crashes earlier win versions.
*/
if (!hDC) SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
dc = DC_LockDc(hDC);
if (NULL == dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
objectType = GDIOBJ_GetObjectType(hGDIObj);
switch (objectType)
{
case GDI_OBJECT_TYPE_PEN:
pen = PENOBJ_LockPen((HPEN) hGDIObj);
if (pen == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
break;
}
XlateObj = IntGdiCreateBrushXlate(dc, pen, &Failed);
PENOBJ_UnlockPen(pen);
if (Failed)
{
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
break;
}
objOrg = (HGDIOBJ)dc->w.hPen;
dc->w.hPen = hGDIObj;
if (dc->XlatePen != NULL)
EngDeleteXlate(dc->XlatePen);
dc->XlatePen = XlateObj;
break;
case GDI_OBJECT_TYPE_BRUSH:
brush = BRUSHOBJ_LockBrush((HPEN) hGDIObj);
if (brush == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
break;
}
XlateObj = IntGdiCreateBrushXlate(dc, brush, &Failed);
BRUSHOBJ_UnlockBrush(brush);
if (Failed)
{
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
break;
}
objOrg = (HGDIOBJ)dc->w.hBrush;
dc->w.hBrush = hGDIObj;
if (dc->XlateBrush != NULL)
EngDeleteXlate(dc->XlateBrush);
dc->XlateBrush = XlateObj;
break;
case GDI_OBJECT_TYPE_FONT:
if(NT_SUCCESS(TextIntRealizeFont((HFONT)hGDIObj)))
{
objOrg = (HGDIOBJ)dc->w.hFont;
dc->w.hFont = (HFONT) hGDIObj;
}
break;
case GDI_OBJECT_TYPE_BITMAP:
// must be memory dc to select bitmap
if (!(dc->w.flags & DC_MEMORY))
{
DC_UnlockDc(dc);
return NULL;
}
pb = BITMAPOBJ_LockBitmap(hGDIObj);
if (NULL == pb)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
DC_UnlockDc(dc);
return NULL;
}
objOrg = (HGDIOBJ)dc->w.hBitmap;
/* Release the old bitmap, lock the new one and convert it to a SURF */
dc->w.hBitmap = hGDIObj;
// if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
if(pb->dib)
{
dc->w.bitsPerPixel = pb->dib->dsBmih.biBitCount;
dc->w.hPalette = pb->hDIBPalette;
}
else
{
dc->w.bitsPerPixel = BitsPerFormat(pb->SurfObj.iBitmapFormat);
dc->w.hPalette = dc->DevInfo->hpalDefault;
}
/* Reselect brush and pen to regenerate the XLATEOBJs. */
NtGdiSelectObject ( hDC, dc->w.hBrush );
NtGdiSelectObject ( hDC, dc->w.hPen );
DC_UnlockDc ( dc );
hVisRgn = NtGdiCreateRectRgn ( 0, 0, pb->SurfObj.sizlBitmap.cx, pb->SurfObj.sizlBitmap.cy );
BITMAPOBJ_UnlockBitmap( pb );
NtGdiSelectVisRgn ( hDC, hVisRgn );
NtGdiDeleteObject ( hVisRgn );
return objOrg;
case GDI_OBJECT_TYPE_REGION:
DC_UnlockDc (dc);
/*
* The return value is one of the following values:
* SIMPLEREGION
* COMPLEXREGION
* NULLREGION
*/
return (HGDIOBJ) NtGdiSelectClipRgn(hDC, (HRGN) hGDIObj);
default:
break;
}
DC_UnlockDc( dc );
return objOrg;
}
WORD STDCALL
NtGdiSetHookFlags(HDC hDC, WORD Flags)
{
WORD wRet;
DC *dc = DC_LockDc(hDC);
if (NULL == dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
wRet = dc->w.flags & DC_DIRTY;
/* "Undocumented Windows" info is slightly confusing.
*/
DPRINT("DC %p, Flags %04x\n", hDC, Flags);
if (Flags & DCHF_INVALIDATEVISRGN)
{
dc->w.flags |= DC_DIRTY;
}
else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
{
dc->w.flags &= ~DC_DIRTY;
}
DC_UnlockDc(dc);
return wRet;
}
DC_SET_MODE( NtGdiSetBkMode, w.backgroundMode, TRANSPARENT, OPAQUE )
DC_SET_MODE( NtGdiSetPolyFillMode, w.polyFillMode, ALTERNATE, WINDING )
// DC_SET_MODE( NtGdiSetRelAbs, w.relAbsMode, ABSOLUTE, RELATIVE )
DC_SET_MODE( NtGdiSetROP2, w.ROPmode, R2_BLACK, R2_WHITE )
DC_SET_MODE( NtGdiSetStretchBltMode, w.stretchBltMode, BLACKONWHITE, HALFTONE )
// ---------------------------------------------------- Private Interface
HDC FASTCALL
DC_AllocDC(PUNICODE_STRING Driver)
{
PDC NewDC;
HDC hDC;
PWSTR Buf = NULL;
if (Driver != NULL)
{
Buf = ExAllocatePoolWithTag(PagedPool, Driver->MaximumLength, TAG_DC);
if(!Buf)
{
return NULL;
}
RtlCopyMemory(Buf, Driver->Buffer, Driver->MaximumLength);
}
hDC = (HDC) GDIOBJ_AllocObj(GdiHandleTable, GDI_OBJECT_TYPE_DC);
if (hDC == NULL)
{
if(Buf)
{
ExFreePool(Buf);
}
return NULL;
}
NewDC = DC_LockDc(hDC);
/* FIXME - Handle NewDC == NULL! */
if (Driver != NULL)
{
RtlCopyMemory(&NewDC->DriverName, Driver, sizeof(UNICODE_STRING));
NewDC->DriverName.Buffer = Buf;
}
NewDC->w.xformWorld2Wnd.eM11 = 1.0f;
NewDC->w.xformWorld2Wnd.eM12 = 0.0f;
NewDC->w.xformWorld2Wnd.eM21 = 0.0f;
NewDC->w.xformWorld2Wnd.eM22 = 1.0f;
NewDC->w.xformWorld2Wnd.eDx = 0.0f;
NewDC->w.xformWorld2Wnd.eDy = 0.0f;
NewDC->w.xformWorld2Vport = NewDC->w.xformWorld2Wnd;
NewDC->w.xformVport2World = NewDC->w.xformWorld2Wnd;
NewDC->w.vport2WorldValid = TRUE;
NewDC->w.MapMode = MM_TEXT;
NewDC->wndExtX = 1.0f;
NewDC->wndExtY = 1.0f;
NewDC->vportExtX = 1.0f;
NewDC->vportExtY = 1.0f;
NewDC->w.textColor = 0;
NewDC->w.backgroundColor = 0xffffff;
NewDC->w.hFont = NtGdiGetStockObject(SYSTEM_FONT);
TextIntRealizeFont(NewDC->w.hFont);
NewDC->w.hPalette = NtGdiGetStockObject(DEFAULT_PALETTE);
DC_UnlockDc(NewDC);
return hDC;
}
HDC FASTCALL
DC_FindOpenDC(PUNICODE_STRING Driver)
{
return NULL;
}
/*!
* Initialize some common fields in the Device Context structure.
*/
VOID FASTCALL
DC_InitDC(HDC DCHandle)
{
// NtGdiRealizeDefaultPalette(DCHandle);
NtGdiSelectObject(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
NtGdiSelectObject(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
//NtGdiSelectObject(DCHandle, hFont);
/*
{
int res;
res = CLIPPING_UpdateGCRegion(DCToInit);
ASSERT ( res != ERROR );
}
*/
}
VOID FASTCALL
DC_FreeDC(HDC DCToFree)
{
if (!GDIOBJ_FreeObj(GdiHandleTable, DCToFree, GDI_OBJECT_TYPE_DC))
{
DPRINT("DC_FreeDC failed\n");
}
}
BOOL INTERNAL_CALL
DC_Cleanup(PVOID ObjectBody)
{
PDC pDC = (PDC)ObjectBody;
RtlFreeUnicodeString(&pDC->DriverName);
return TRUE;
}
HDC FASTCALL
DC_GetNextDC (PDC pDC)
{
return pDC->hNext;
}
VOID FASTCALL
DC_SetNextDC (PDC pDC, HDC hNextDC)
{
pDC->hNext = hNextDC;
}
VOID FASTCALL
DC_UpdateXforms(PDC dc)
{
XFORM xformWnd2Vport;
FLOAT scaleX, scaleY;
/* Construct a transformation to do the window-to-viewport conversion */
scaleX = (dc->wndExtX ? (FLOAT)dc->vportExtX / (FLOAT)dc->wndExtX : 0.0f);
scaleY = (dc->wndExtY ? (FLOAT)dc->vportExtY / (FLOAT)dc->wndExtY : 0.0f);
xformWnd2Vport.eM11 = scaleX;
xformWnd2Vport.eM12 = 0.0;
xformWnd2Vport.eM21 = 0.0;
xformWnd2Vport.eM22 = scaleY;
xformWnd2Vport.eDx = (FLOAT)dc->vportOrgX - scaleX * (FLOAT)dc->wndOrgX;
xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY - scaleY * (FLOAT)dc->wndOrgY;
/* Combine with the world transformation */
IntGdiCombineTransform(&dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd, &xformWnd2Vport);
/* Create inverse of world-to-viewport transformation */
dc->w.vport2WorldValid = DC_InvertXform(&dc->w.xformWorld2Vport, &dc->w.xformVport2World);
}
BOOL FASTCALL
DC_InvertXform(const XFORM *xformSrc,
XFORM *xformDest)
{
FLOAT determinant;
determinant = xformSrc->eM11*xformSrc->eM22 - xformSrc->eM12*xformSrc->eM21;
if (determinant > -1e-12 && determinant < 1e-12)
{
return FALSE;
}
xformDest->eM11 = xformSrc->eM22 / determinant;
xformDest->eM12 = -xformSrc->eM12 / determinant;
xformDest->eM21 = -xformSrc->eM21 / determinant;
xformDest->eM22 = xformSrc->eM11 / determinant;
xformDest->eDx = -xformSrc->eDx * xformDest->eM11 - xformSrc->eDy * xformDest->eM21;
xformDest->eDy = -xformSrc->eDx * xformDest->eM12 - xformSrc->eDy * xformDest->eM22;
return TRUE;
}
VOID FASTCALL
DC_SetOwnership(HDC hDC, PEPROCESS Owner)
{
PDC DC;
GDIOBJ_SetOwnership(GdiHandleTable, hDC, Owner);
DC = DC_LockDc(hDC);
if (NULL != DC)
{
if (NULL != DC->w.hClipRgn)
{
GDIOBJ_CopyOwnership(GdiHandleTable, hDC, DC->w.hClipRgn);
}
if (NULL != DC->w.hVisRgn)
{
GDIOBJ_CopyOwnership(GdiHandleTable, hDC, DC->w.hVisRgn);
}
if (NULL != DC->w.hGCClipRgn)
{
GDIOBJ_CopyOwnership(GdiHandleTable, hDC, DC->w.hGCClipRgn);
}
DC_UnlockDc(DC);
}
}
BOOL FASTCALL
IntIsPrimarySurface(SURFOBJ *SurfObj)
{
if (PrimarySurface.Handle == NULL)
{
return FALSE;
}
return SurfObj->hsurf == PrimarySurface.Handle;
}
/*
* Returns the color of the brush or pen that is currently selected into the DC.
* This function is called from GetDCBrushColor() and GetDCPenColor()
*/
COLORREF FASTCALL
IntGetDCColor(HDC hDC, ULONG Object)
{
/*
* The previous implementation was completly incorrect. It modified the
* brush that was currently selected into the device context, but in fact
* the DC pen/brush color should be stored directly in the device context
* (at address 0x2C of the user mode DC object memory on Windows 2K/XP).
* The actual color is then used when DC_BRUSH/DC_PEN object is selected
* into the device context and BRUSHOBJ for drawing is composed (belongs
* to IntGdiInitBrushInstance in the current ReactOS implementation). Also
* the implementation should be moved to user mode GDI32.dll when UM
* mapped GDI objects will be implemented.
*/
DPRINT("WIN32K:IntGetDCColor is unimplemented\n");
return 0xFFFFFF; /* The default DC color. */
}
/*
* Changes the color of the brush or pen that is currently selected into the DC.
* This function is called from SetDCBrushColor() and SetDCPenColor()
*/
COLORREF FASTCALL
IntSetDCColor(HDC hDC, ULONG Object, COLORREF Color)
{
/* See the comment in IntGetDCColor. */
DPRINT("WIN32K:IntSetDCColor is unimplemented\n");
return CLR_INVALID;
}
#define SIZEOF_DEVMODEW_300 188
#define SIZEOF_DEVMODEW_400 212
#define SIZEOF_DEVMODEW_500 220
/*! \brief Enumerate possible display settings for the given display...
*
* \todo Make thread safe!?
* \todo Don't ignore pDeviceName
* \todo Implement non-raw mode (only return settings valid for driver and monitor)
*/
BOOL FASTCALL
IntEnumDisplaySettings(
IN PUNICODE_STRING pDeviceName OPTIONAL,
IN DWORD iModeNum,
IN OUT LPDEVMODEW pDevMode,
IN DWORD dwFlags)
{
static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
static DWORD SizeOfCachedDevModes = 0;
PDEVMOD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -