reactos/subsystems/win32/win32k/objects/dclife.c

750 lines
20 KiB
C
Raw Normal View History

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Functions for creation and destruction of DCs
* FILE: subsystem/win32/win32k/objects/dclife.c
* PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org)
*/
#include <w32k.h>
#include <bugcodes.h>
#define NDEBUG
#include <debug.h>
/** Internal functions ********************************************************/
HDC FASTCALL
DC_AllocDC(PUNICODE_STRING Driver)
{
PDC NewDC;
PDC_ATTR pdcattr;
HDC hDC;
PWSTR Buf = NULL;
XFORM xformTemplate;
PBRUSH pbrush;
XLATEOBJ rewrite. The new XLATEOBJ is not allocated from paged pool anymore, but instead allocated on the stack and Initialized. Only when we habe more than a color table with more than 6 entries, we need to allocate an additional buffer. The new interface: EXLATEOBJ_vInitialize is the main init function. It takes a source and destination palette and back and fore colors for monochome surfaces. EXLATEOBJ_vInitXlateFromDCs takes the source and dest DC and is for color translation between 2 surfaces represented by 2 DCs. EXLATEOBJ_vInitBrushXlate initializes an XLATEOBJ for a pattern brush. Finally EXLATEOBJ_vCleanup needs to be called when the XLATEOBJ is not needed anymore. Implement individual iXlate functions for certain cases and store a function pointer in the EXLATEOBJ structure for quick access. Change the usage of the PALETTE.Mode member to be a flag instead of an enum, add usage of PAL_MONOCHOME, PAL_RGB16_555 and PAL_RGB16_565. Add gpalMono, which *should* be used as palette for 1bpp DDBs. Currently there's a hack in the XLATEOBJ init code, to hack around the fact that this is missing. Fix the Hatch brush patterns, as they were inverted. Implement PALETTE_ulGetNearestBitFieldsIndex and PALETTE_ulGetNearestIndex. Get rid of the XLATEOBJ for the mouse pointer instead realize the pointer before usage. Get rid of logicalToSystem PALETTE member. NtGdiGetDIBitsInternal: Don't create a DIBBrush from the BITMAPINFO, when pvBits is NULL, as the function might be uninitualized. This fixes a crash of gdi_regtest. The whole function is quite ugly and needs to be rewritten (like probably the rest of the DIB code). This fixes the problem of artifacts in the selected desktop icons and some color problems. svn path=/trunk/; revision=42391
2009-08-04 20:37:10 +00:00
HSURF hsurf;
if (Driver != NULL)
{
Buf = ExAllocatePoolWithTag(PagedPool, Driver->MaximumLength, TAG_DC);
if (!Buf)
{
DPRINT1("ExAllocatePoolWithTag failed\n");
return NULL;
}
RtlCopyMemory(Buf, Driver->Buffer, Driver->MaximumLength);
}
NewDC = (PDC)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_DC);
if (!NewDC)
{
if (Buf)
{
ExFreePoolWithTag(Buf, TAG_DC);
}
DPRINT1("GDIOBJ_AllocObjWithHandle failed\n");
return NULL;
}
hDC = NewDC->BaseObject.hHmgr;
NewDC->pdcattr = &NewDC->dcattr;
DC_AllocateDcAttr(hDC);
if (Driver != NULL)
{
RtlCopyMemory(&NewDC->rosdc.DriverName, Driver, sizeof(UNICODE_STRING));
NewDC->rosdc.DriverName.Buffer = Buf;
}
pdcattr = NewDC->pdcattr;
// FIXME: no floating point in the kernel!
xformTemplate.eM11 = 1.0f;
xformTemplate.eM12 = 0.0f;
xformTemplate.eM21 = 0.0f;
xformTemplate.eM22 = 1.0f;
xformTemplate.eDx = 0.0f;
xformTemplate.eDy = 0.0f;
XForm2MatrixS(&NewDC->dclevel.mxWorldToDevice, &xformTemplate);
XForm2MatrixS(&NewDC->dclevel.mxDeviceToWorld, &xformTemplate);
XForm2MatrixS(&NewDC->dclevel.mxWorldToPage, &xformTemplate);
// Setup syncing bits for the dcattr data packets.
pdcattr->flXform = DEVICE_TO_PAGE_INVALID;
pdcattr->ulDirty_ = 0; // Server side
pdcattr->iMapMode = MM_TEXT;
pdcattr->iGraphicsMode = GM_COMPATIBLE;
pdcattr->jFillMode = ALTERNATE;
pdcattr->szlWindowExt.cx = 1; // Float to Int,,, WRONG!
pdcattr->szlWindowExt.cy = 1;
pdcattr->szlViewportExt.cx = 1;
pdcattr->szlViewportExt.cy = 1;
pdcattr->crForegroundClr = 0;
pdcattr->ulForegroundClr = 0;
pdcattr->ulBackgroundClr = 0xffffff;
pdcattr->crBackgroundClr = 0xffffff;
pdcattr->ulPenClr = RGB(0, 0, 0);
pdcattr->crPenClr = RGB(0, 0, 0);
pdcattr->ulBrushClr = RGB(255, 255, 255); // Do this way too.
pdcattr->crBrushClr = RGB(255, 255, 255);
//// This fixes the default brush and pen settings. See DC_InitDC.
/* Create the default fill brush */
pdcattr->hbrush = NtGdiGetStockObject(WHITE_BRUSH);
NewDC->dclevel.pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush);
EBRUSHOBJ_vInit(&NewDC->eboFill, NewDC->dclevel.pbrFill, NewDC);
/* Create the default pen / line brush */
pdcattr->hpen = NtGdiGetStockObject(BLACK_PEN);
NewDC->dclevel.pbrLine = PEN_ShareLockPen(pdcattr->hpen);
EBRUSHOBJ_vInit(&NewDC->eboLine, NewDC->dclevel.pbrLine, NewDC);
/* Create the default text brush */
pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(BLACK_BRUSH));
EBRUSHOBJ_vInit(&NewDC->eboText, pbrush, NewDC);
pdcattr->ulDirty_ |= DIRTY_TEXT;
/* Create the default background brush */
pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(WHITE_BRUSH));
EBRUSHOBJ_vInit(&NewDC->eboBackground, pbrush, NewDC);
pdcattr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT);
TextIntRealizeFont(pdcattr->hlfntNew,NULL);
NewDC->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE);
NewDC->dclevel.ppal = PALETTE_ShareLockPalette(NewDC->dclevel.hpal);
/* This should never fail */
ASSERT(NewDC->dclevel.ppal);
NewDC->dclevel.laPath.eMiterLimit = 10.0; // FIXME: use FLOATL or FLOATOBJ!
NewDC->dclevel.lSaveDepth = 1;
XLATEOBJ rewrite. The new XLATEOBJ is not allocated from paged pool anymore, but instead allocated on the stack and Initialized. Only when we habe more than a color table with more than 6 entries, we need to allocate an additional buffer. The new interface: EXLATEOBJ_vInitialize is the main init function. It takes a source and destination palette and back and fore colors for monochome surfaces. EXLATEOBJ_vInitXlateFromDCs takes the source and dest DC and is for color translation between 2 surfaces represented by 2 DCs. EXLATEOBJ_vInitBrushXlate initializes an XLATEOBJ for a pattern brush. Finally EXLATEOBJ_vCleanup needs to be called when the XLATEOBJ is not needed anymore. Implement individual iXlate functions for certain cases and store a function pointer in the EXLATEOBJ structure for quick access. Change the usage of the PALETTE.Mode member to be a flag instead of an enum, add usage of PAL_MONOCHOME, PAL_RGB16_555 and PAL_RGB16_565. Add gpalMono, which *should* be used as palette for 1bpp DDBs. Currently there's a hack in the XLATEOBJ init code, to hack around the fact that this is missing. Fix the Hatch brush patterns, as they were inverted. Implement PALETTE_ulGetNearestBitFieldsIndex and PALETTE_ulGetNearestIndex. Get rid of the XLATEOBJ for the mouse pointer instead realize the pointer before usage. Get rid of logicalToSystem PALETTE member. NtGdiGetDIBitsInternal: Don't create a DIBBrush from the BITMAPINFO, when pvBits is NULL, as the function might be uninitualized. This fixes a crash of gdi_regtest. The whole function is quite ugly and needs to be rewritten (like probably the rest of the DIB code). This fixes the problem of artifacts in the selected desktop icons and some color problems. svn path=/trunk/; revision=42391
2009-08-04 20:37:10 +00:00
hsurf = (HBITMAP)PrimarySurface.pSurface; // <- what kind of haxx0ry is that?
NewDC->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
return NewDC;
}
BOOL INTERNAL_CALL
DC_Cleanup(PVOID ObjectBody)
{
PDC pDC = (PDC)ObjectBody;
/* Free driver name (HACK) */
if (pDC->rosdc.DriverName.Buffer)
ExFreePoolWithTag(pDC->rosdc.DriverName.Buffer, TAG_DC);
/* Deselect dc objects */
DC_vSelectSurface(pDC, NULL);
DC_vSelectFillBrush(pDC, NULL);
DC_vSelectLineBrush(pDC, NULL);
DC_vSelectPalette(pDC, NULL);
/* Dereference default brushes */
BRUSH_ShareUnlockBrush(pDC->eboText.pbrush);
BRUSH_ShareUnlockBrush(pDC->eboBackground.pbrush);
/* Cleanup the dc brushes */
EBRUSHOBJ_vCleanup(&pDC->eboFill);
EBRUSHOBJ_vCleanup(&pDC->eboLine);
EBRUSHOBJ_vCleanup(&pDC->eboText);
EBRUSHOBJ_vCleanup(&pDC->eboBackground);
return TRUE;
}
BOOL
FASTCALL
DC_SetOwnership(HDC hDC, PEPROCESS Owner)
{
INT Index;
PGDI_TABLE_ENTRY Entry;
PDC pDC;
if (!GDIOBJ_SetOwnership(hDC, Owner)) return FALSE;
pDC = DC_LockDc(hDC);
if (pDC)
{
/*
System Regions:
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->rosdc.hVisRgn)
{ // FIXME! HAX!!!
Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hVisRgn);
Entry = &GdiHandleTable->Entries[Index];
if (Entry->UserData) FreeObjectAttr(Entry->UserData);
Entry->UserData = NULL;
//
if (!GDIOBJ_SetOwnership(pDC->rosdc.hVisRgn, 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);
}
return TRUE;
}
HDC FASTCALL
IntGdiCreateDC(
PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PVOID pUMdhpdev,
CONST PDEVMODEW InitData,
BOOL CreateAsIC)
{
HDC hdc;
PDC pdc;
PDC_ATTR pdcattr;
HRGN hVisRgn;
UNICODE_STRING StdDriver;
BOOL calledFromUser;
RtlInitUnicodeString(&StdDriver, L"DISPLAY");
DPRINT("DriverName: %wZ, DeviceName: %wZ\n", Driver, Device);
if (NULL == Driver || 0 == RtlCompareUnicodeString(Driver, &StdDriver, TRUE))
{
if (CreateAsIC)
{
if (! IntPrepareDriverIfNeeded())
{
/* Here, we have two possibilities:
* a) return NULL, and hope that the caller
* won't call us in a loop
* b) bugcheck, but caller is unable to
* react on the problem
*/
/*DPRINT1("Unable to prepare graphics driver, returning NULL ic\n");
return NULL;*/
KeBugCheck(VIDEO_DRIVER_INIT_FAILURE);
}
}
else
{
calledFromUser = UserIsEntered();
if (!calledFromUser)
{
UserEnterExclusive();
}
if (! co_IntGraphicsCheck(TRUE))
{
if (!calledFromUser)
{
UserLeave();
}
DPRINT1("Unable to initialize graphics, returning NULL dc\n");
return NULL;
}
if (!calledFromUser)
{
UserLeave();
}
}
}
/* Check for existing DC object */
if ((hdc = DC_FindOpenDC(Driver)) != NULL)
{
hdc = NtGdiCreateCompatibleDC(hdc);
if (!hdc)
DPRINT1("NtGdiCreateCompatibleDC() failed\n");
return hdc;
}
/* Allocate a DC object */
pdc = DC_AllocDC(Driver);
if (pdc == NULL)
{
DPRINT1("DC_AllocDC() failed\n");
return NULL;
}
hdc = pdc->BaseObject.hHmgr;
pdcattr = pdc->pdcattr;
pdc->dctype = DC_TYPE_DIRECT;
pdc->dhpdev = PrimarySurface.dhpdev;
if (pUMdhpdev) pUMdhpdev = pdc->dhpdev; // set DHPDEV for device.
pdc->ppdev = (PVOID)&PrimarySurface;
// ATM we only have one display.
pdcattr->ulDirty_ |= DC_PRIMARY_DISPLAY;
pdc->rosdc.bitsPerPixel = pdc->ppdev->gdiinfo.cBitsPixel *
pdc->ppdev->gdiinfo.cPlanes;
DPRINT("Bits per pel: %u\n", pdc->rosdc.bitsPerPixel);
pdc->flGraphicsCaps = PrimarySurface.devinfo.flGraphicsCaps;
pdc->flGraphicsCaps2 = PrimarySurface.devinfo.flGraphicsCaps2;
pdc->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE);
pdcattr->jROP2 = R2_COPYPEN;
pdc->erclWindow.top = pdc->erclWindow.left = 0;
pdc->erclWindow.right = pdc->ppdev->gdiinfo.ulHorzRes;
pdc->erclWindow.bottom = pdc->ppdev->gdiinfo.ulVertRes;
pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE; // Default is CCW.
pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
hVisRgn = IntSysCreateRectRgn(0, 0, pdc->ppdev->gdiinfo.ulHorzRes,
pdc->ppdev->gdiinfo.ulVertRes);
if (!CreateAsIC)
{
pdc->pSurfInfo = NULL;
// pdc->dclevel.pSurface =
DC_UnlockDc(pdc);
/* Initialize the DC state */
IntGdiSetTextColor(hdc, RGB(0, 0, 0));
IntGdiSetBkColor(hdc, RGB(255, 255, 255));
}
else
{
/* From MSDN2:
The CreateIC function creates an information context for the specified device.
The information context provides a fast way to get information about the
device without creating a device context (DC). However, GDI drawing functions
cannot accept a handle to an information context.
*/
pdc->dctype = DC_TYPE_INFO;
// pdc->pSurfInfo =
XLATEOBJ rewrite. The new XLATEOBJ is not allocated from paged pool anymore, but instead allocated on the stack and Initialized. Only when we habe more than a color table with more than 6 entries, we need to allocate an additional buffer. The new interface: EXLATEOBJ_vInitialize is the main init function. It takes a source and destination palette and back and fore colors for monochome surfaces. EXLATEOBJ_vInitXlateFromDCs takes the source and dest DC and is for color translation between 2 surfaces represented by 2 DCs. EXLATEOBJ_vInitBrushXlate initializes an XLATEOBJ for a pattern brush. Finally EXLATEOBJ_vCleanup needs to be called when the XLATEOBJ is not needed anymore. Implement individual iXlate functions for certain cases and store a function pointer in the EXLATEOBJ structure for quick access. Change the usage of the PALETTE.Mode member to be a flag instead of an enum, add usage of PAL_MONOCHOME, PAL_RGB16_555 and PAL_RGB16_565. Add gpalMono, which *should* be used as palette for 1bpp DDBs. Currently there's a hack in the XLATEOBJ init code, to hack around the fact that this is missing. Fix the Hatch brush patterns, as they were inverted. Implement PALETTE_ulGetNearestBitFieldsIndex and PALETTE_ulGetNearestIndex. Get rid of the XLATEOBJ for the mouse pointer instead realize the pointer before usage. Get rid of logicalToSystem PALETTE member. NtGdiGetDIBitsInternal: Don't create a DIBBrush from the BITMAPINFO, when pvBits is NULL, as the function might be uninitualized. This fixes a crash of gdi_regtest. The whole function is quite ugly and needs to be rewritten (like probably the rest of the DIB code). This fixes the problem of artifacts in the selected desktop icons and some color problems. svn path=/trunk/; revision=42391
2009-08-04 20:37:10 +00:00
// DC_vSelectSurface(pdc, NULL);
pdcattr->crBackgroundClr = pdcattr->ulBackgroundClr = RGB(255, 255, 255);
pdcattr->crForegroundClr = RGB(0, 0, 0);
DC_UnlockDc(pdc);
}
DC_InitDC(hdc);
if (hVisRgn)
{
GdiSelectVisRgn(hdc, hVisRgn);
REGION_FreeRgnByHandle(hVisRgn);
}
IntGdiSetTextAlign(hdc, TA_TOP);
IntGdiSetBkMode(hdc, OPAQUE);
return hdc;
}
HDC APIENTRY
NtGdiOpenDCW(
PUNICODE_STRING Device,
DEVMODEW *InitData,
PUNICODE_STRING pustrLogAddr,
ULONG iType,
BOOL bDisplay,
HANDLE hspool,
VOID *pDriverInfo2,
VOID *pUMdhpdev)
{
UNICODE_STRING SafeDevice;
DEVMODEW SafeInitData;
PVOID Dhpdev;
HDC Ret;
NTSTATUS Status = STATUS_SUCCESS;
if (!Device) return UserGetDesktopDC(iType,FALSE,TRUE);
if (InitData)
{
_SEH2_TRY
{
if (pUMdhpdev)
{
ProbeForWrite(pUMdhpdev, sizeof(PVOID), 1);
}
ProbeForRead(InitData, sizeof(DEVMODEW), 1);
RtlCopyMemory(&SafeInitData, InitData, sizeof(DEVMODEW));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return NULL;
}
/* FIXME - InitData can have some more bytes! */
}
if (Device)
{
Status = IntSafeCopyUnicodeString(&SafeDevice, Device);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return NULL;
}
}
Ret = IntGdiCreateDC(Device ? &SafeDevice : NULL,
NULL,
pUMdhpdev ? &Dhpdev : NULL,
InitData ? &SafeInitData : NULL,
(BOOL) iType); // FALSE 0 DCW, TRUE 1 ICW
// FIXME!!!!
if (pUMdhpdev) pUMdhpdev = Dhpdev;
return Ret;
}
HDC FASTCALL
IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
{
HDC hDC;
UNICODE_STRING DriverName;
RtlInitUnicodeString(&DriverName, L"DISPLAY");
if (DcType != DC_TYPE_MEMORY)
hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, (DcType == DC_TYPE_INFO));
else
hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth!
//
// There is room to grow here~
//
//
// If NULL, first time through! Build the default (was window) dc!
// Setup clean DC state for the system.
//
if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG!
{ // This is a cheesy way to do this.
PDC dc = DC_LockDc(hDC);
XLATEOBJ rewrite. The new XLATEOBJ is not allocated from paged pool anymore, but instead allocated on the stack and Initialized. Only when we habe more than a color table with more than 6 entries, we need to allocate an additional buffer. The new interface: EXLATEOBJ_vInitialize is the main init function. It takes a source and destination palette and back and fore colors for monochome surfaces. EXLATEOBJ_vInitXlateFromDCs takes the source and dest DC and is for color translation between 2 surfaces represented by 2 DCs. EXLATEOBJ_vInitBrushXlate initializes an XLATEOBJ for a pattern brush. Finally EXLATEOBJ_vCleanup needs to be called when the XLATEOBJ is not needed anymore. Implement individual iXlate functions for certain cases and store a function pointer in the EXLATEOBJ structure for quick access. Change the usage of the PALETTE.Mode member to be a flag instead of an enum, add usage of PAL_MONOCHOME, PAL_RGB16_555 and PAL_RGB16_565. Add gpalMono, which *should* be used as palette for 1bpp DDBs. Currently there's a hack in the XLATEOBJ init code, to hack around the fact that this is missing. Fix the Hatch brush patterns, as they were inverted. Implement PALETTE_ulGetNearestBitFieldsIndex and PALETTE_ulGetNearestIndex. Get rid of the XLATEOBJ for the mouse pointer instead realize the pointer before usage. Get rid of logicalToSystem PALETTE member. NtGdiGetDIBitsInternal: Don't create a DIBBrush from the BITMAPINFO, when pvBits is NULL, as the function might be uninitualized. This fixes a crash of gdi_regtest. The whole function is quite ugly and needs to be rewritten (like probably the rest of the DIB code). This fixes the problem of artifacts in the selected desktop icons and some color problems. svn path=/trunk/; revision=42391
2009-08-04 20:37:10 +00:00
HSURF hsurf;
defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
if (!defaultDCstate)
{
DC_UnlockDc(dc);
return NULL;
}
RtlZeroMemory(defaultDCstate, sizeof(DC));
defaultDCstate->pdcattr = &defaultDCstate->dcattr;
XLATEOBJ rewrite. The new XLATEOBJ is not allocated from paged pool anymore, but instead allocated on the stack and Initialized. Only when we habe more than a color table with more than 6 entries, we need to allocate an additional buffer. The new interface: EXLATEOBJ_vInitialize is the main init function. It takes a source and destination palette and back and fore colors for monochome surfaces. EXLATEOBJ_vInitXlateFromDCs takes the source and dest DC and is for color translation between 2 surfaces represented by 2 DCs. EXLATEOBJ_vInitBrushXlate initializes an XLATEOBJ for a pattern brush. Finally EXLATEOBJ_vCleanup needs to be called when the XLATEOBJ is not needed anymore. Implement individual iXlate functions for certain cases and store a function pointer in the EXLATEOBJ structure for quick access. Change the usage of the PALETTE.Mode member to be a flag instead of an enum, add usage of PAL_MONOCHOME, PAL_RGB16_555 and PAL_RGB16_565. Add gpalMono, which *should* be used as palette for 1bpp DDBs. Currently there's a hack in the XLATEOBJ init code, to hack around the fact that this is missing. Fix the Hatch brush patterns, as they were inverted. Implement PALETTE_ulGetNearestBitFieldsIndex and PALETTE_ulGetNearestIndex. Get rid of the XLATEOBJ for the mouse pointer instead realize the pointer before usage. Get rid of logicalToSystem PALETTE member. NtGdiGetDIBitsInternal: Don't create a DIBBrush from the BITMAPINFO, when pvBits is NULL, as the function might be uninitualized. This fixes a crash of gdi_regtest. The whole function is quite ugly and needs to be rewritten (like probably the rest of the DIB code). This fixes the problem of artifacts in the selected desktop icons and some color problems. svn path=/trunk/; revision=42391
2009-08-04 20:37:10 +00:00
hsurf = (HSURF)PrimarySurface.pSurface; // HAX<41>
defaultDCstate->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
DC_vCopyState(dc, defaultDCstate);
DC_UnlockDc(dc);
}
return hDC;
}
BOOL
FASTCALL
IntGdiDeleteDC(HDC hDC, BOOL Force)
{
PDC DCToDelete = DC_LockDc(hDC);
if (DCToDelete == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (!Force)
{
if (DCToDelete->fs & DC_FLAG_PERMANENT)
{
DPRINT1("No! You Naughty Application!\n");
DC_UnlockDc(DCToDelete);
return UserReleaseDC(NULL, hDC, FALSE);
}
}
/* First delete all saved DCs */
while (DCToDelete->dclevel.lSaveDepth > 1)
{
PDC savedDC;
HDC savedHDC;
savedHDC = DCToDelete->hdcNext;
savedDC = DC_LockDc(savedHDC);
if (savedDC == NULL)
{
break;
}
DCToDelete->hdcNext = savedDC->hdcNext;
DCToDelete->dclevel.lSaveDepth--;
DC_UnlockDc(savedDC);
IntGdiDeleteDC(savedHDC, Force);
}
/* Free GDI resources allocated to this DC */
if (!(DCToDelete->dclevel.flPath & DCPATH_SAVESTATE))
{
/*
NtGdiSelectPen (DCHandle, STOCK_BLACK_PEN);
NtGdiSelectBrush (DCHandle, STOCK_WHITE_BRUSH);
NtGdiSelectFont (DCHandle, STOCK_SYSTEM_FONT);
DC_LockDC (DCHandle); NtGdiSelectXxx does not recognize stock objects yet */
}
if (DCToDelete->rosdc.hClipRgn)
{
GreDeleteObject(DCToDelete->rosdc.hClipRgn);
}
if (DCToDelete->rosdc.hVisRgn)
{
GreDeleteObject(DCToDelete->rosdc.hVisRgn);
}
if (NULL != DCToDelete->rosdc.CombinedClip)
{
IntEngDeleteClipRegion(DCToDelete->rosdc.CombinedClip);
}
if (DCToDelete->rosdc.hGCClipRgn)
{
GreDeleteObject(DCToDelete->rosdc.hGCClipRgn);
}
PATH_Delete(DCToDelete->dclevel.hPath);
DC_UnlockDc(DCToDelete);
GreDeleteObject(hDC);
return TRUE;
}
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);
//// Removed for now.. See above brush and pen.
// NtGdiSelectBrush(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
// NtGdiSelectPen(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
////
//NtGdiSelectFont(DCHandle, hFont);
/*
{
int res;
res = CLIPPING_UpdateGCRegion(DCToInit);
ASSERT ( res != ERROR );
}
*/
/* Set virtual resolution */
NtGdiSetVirtualResolution(DCHandle, 0, 0, 0, 0);
}
/*
* @unimplemented
*/
BOOL
APIENTRY
NtGdiMakeInfoDC(
IN HDC hdc,
IN BOOL bSet)
{
UNIMPLEMENTED;
return FALSE;
}
HDC APIENTRY
NtGdiCreateCompatibleDC(HDC hDC)
{
PDC pdcNew, pdcOld;
PDC_ATTR pdcattrNew, pdcattrOld;
HDC hdcNew, DisplayDC = NULL;
HRGN hVisRgn;
UNICODE_STRING DriverName;
DWORD Layout = 0;
HSURF hsurf;
if (hDC == NULL)
{
RtlInitUnicodeString(&DriverName, L"DISPLAY");
DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, TRUE);
if (NULL == DisplayDC)
{
DPRINT1("Failed to create DisplayDC\n");
return NULL;
}
hDC = DisplayDC;
}
/* Allocate a new DC based on the original DC's device */
pdcOld = DC_LockDc(hDC);
if (NULL == pdcOld)
{
if (NULL != DisplayDC)
{
NtGdiDeleteObjectApp(DisplayDC);
}
DPRINT1("Failed to lock hDC\n");
return NULL;
}
pdcNew = DC_AllocDC(&pdcOld->rosdc.DriverName);
if (!pdcNew)
{
DPRINT1("Failed to create pdcNew\n");
DC_UnlockDc(pdcOld);
if (DisplayDC)
{
NtGdiDeleteObjectApp(DisplayDC);
}
return NULL;
}
hdcNew = pdcNew->BaseObject.hHmgr;
pdcattrOld = pdcOld->pdcattr;
pdcattrNew = pdcNew->pdcattr;
/* Copy information from original DC to new DC */
pdcNew->dclevel.hdcSave = hdcNew;
pdcNew->dhpdev = pdcOld->dhpdev;
pdcNew->rosdc.bitsPerPixel = pdcOld->rosdc.bitsPerPixel;
/* DriverName is copied in the AllocDC routine */
pdcattrNew->ptlWindowOrg = pdcattrOld->ptlWindowOrg;
pdcattrNew->szlWindowExt = pdcattrOld->szlWindowExt;
pdcattrNew->ptlViewportOrg = pdcattrOld->ptlViewportOrg;
pdcattrNew->szlViewportExt = pdcattrOld->szlViewportExt;
pdcNew->dctype = DC_TYPE_MEMORY; // Always!
hsurf = NtGdiGetStockObject(DEFAULT_BITMAP);
pdcNew->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
pdcNew->ppdev = pdcOld->ppdev;
pdcNew->dclevel.hpal = pdcOld->dclevel.hpal;
pdcattrNew->lTextAlign = pdcattrOld->lTextAlign;
pdcattrNew->lBkMode = pdcattrOld->lBkMode;
pdcattrNew->jBkMode = pdcattrOld->jBkMode;
pdcattrNew->jROP2 = pdcattrOld->jROP2;
pdcattrNew->dwLayout = pdcattrOld->dwLayout;
if (pdcattrOld->dwLayout & LAYOUT_ORIENTATIONMASK) Layout = pdcattrOld->dwLayout;
pdcNew->dclevel.flPath = pdcOld->dclevel.flPath;
pdcattrNew->ulDirty_ = pdcattrOld->ulDirty_;
pdcattrNew->iCS_CP = pdcattrOld->iCS_CP;
pdcNew->erclWindow.left = pdcNew->erclWindow.top = 0;
pdcNew->erclWindow.right = pdcNew->erclWindow.bottom = 1;
DC_UnlockDc(pdcNew);
DC_UnlockDc(pdcOld);
if (NULL != DisplayDC)
{
NtGdiDeleteObjectApp(DisplayDC);
}
hVisRgn = IntSysCreateRectRgn(0, 0, 1, 1);
if (hVisRgn)
{
GdiSelectVisRgn(hdcNew, hVisRgn);
REGION_FreeRgnByHandle(hVisRgn);
}
if (Layout) NtGdiSetLayout(hdcNew, -1, Layout);
DC_InitDC(hdcNew);
return hdcNew;
}
BOOL
APIENTRY
NtGdiDeleteObjectApp(HANDLE DCHandle)
{
/* Complete all pending operations */
NtGdiFlushUserBatch();
if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
if (GDI_HANDLE_GET_TYPE(DCHandle) != GDI_OBJECT_TYPE_DC)
return GreDeleteObject((HGDIOBJ) DCHandle);
if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
if (!GDIOBJ_OwnedByCurrentProcess(DCHandle))
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
return IntGdiDeleteDC(DCHandle, FALSE);
}
BOOL
APIENTRY
NewNtGdiDeleteObjectApp(HANDLE DCHandle)
{
GDIOBJTYPE ObjType;
if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
ObjType = GDI_HANDLE_GET_TYPE(DCHandle) >> GDI_ENTRY_UPPER_SHIFT;
if (GreGetObjectOwner( DCHandle, ObjType))
{
switch(ObjType)
{
case GDIObjType_DC_TYPE:
return IntGdiDeleteDC(DCHandle, FALSE);
case GDIObjType_RGN_TYPE:
case GDIObjType_SURF_TYPE:
case GDIObjType_PAL_TYPE:
case GDIObjType_LFONT_TYPE:
case GDIObjType_BRUSH_TYPE:
return GreDeleteObject((HGDIOBJ) DCHandle);
default:
return FALSE;
}
}
return (DCHandle != NULL);
}