- Reordered IntGdiGet/SetDCState and separated the copy sections.

- When creating DCE for window handles, allocate a DC structure for the default window DC.
- Return Dhpdev if not zero for NtGdiOpenDCW.
- Reordered the DC object. 

svn path=/trunk/; revision=28918
This commit is contained in:
James Tabor 2007-09-07 12:21:26 +00:00
parent 5b0be27588
commit bd954074fa
4 changed files with 194 additions and 160 deletions

View file

@ -59,37 +59,42 @@ typedef struct _WIN_DC_INFO
typedef struct _DC
{
HDC hSelf;
HDC hNext;
PDC_ATTR pDc_Attr;
INT DC_Type;
INT DC_Flags;
DHPDEV PDev;
HSURF FillPatternSurfaces[HS_DDI_MAX];
PGDIINFO GDIInfo;
PDEVINFO DevInfo;
HDEV GDIDevice;
HGDIOBJ hHmgr;
PVOID pvEntry;
ULONG lucExcLock;
ULONG Tid;
DHPDEV PDev;
INT DC_Type;
INT DC_Flags;
PDC_ATTR pDc_Attr;
DC_ATTR Dc_Attr;
HDC hSelf;
HDC hNext;
HSURF FillPatternSurfaces[HS_DDI_MAX];
PGDIINFO GDIInfo;
PDEVINFO DevInfo;
HDEV GDIDevice;
DRIVER_FUNCTIONS DriverFunctions;
UNICODE_STRING DriverName;
HANDLE DeviceDriver;
HANDLE DeviceDriver;
CLIPOBJ *CombinedClip;
CLIPOBJ *CombinedClip;
XLATEOBJ *XlateBrush;
XLATEOBJ *XlatePen;
XLATEOBJ *XlateBrush;
XLATEOBJ *XlatePen;
INT saveLevel;
BOOL IsIC;
INT saveLevel;
BOOL IsIC;
HPALETTE PalIndexed;
HPALETTE PalIndexed;
WIN_DC_INFO w;
DC_ATTR Dc_Attr;
WIN_DC_INFO w;
HANDLE hFile;
HANDLE hFile;
LPENHMETAHEADER emh;
} DC, *PDC;
typedef struct _GDIPOINTER /* should stay private to ENG */
@ -151,6 +156,8 @@ BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody);
HDC FASTCALL DC_GetNextDC (PDC pDC);
VOID FASTCALL DC_SetNextDC (PDC pDC, HDC hNextDC);
VOID FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner);
VOID FASTCALL IntGdiCopyFromSaveState(PDC, PDC);
VOID FASTCALL IntGdiCopyToSaveState(PDC, PDC);
VOID FASTCALL DC_UpdateXforms(PDC dc);
BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest);

View file

@ -159,7 +159,7 @@ IntGdiGetObject(HANDLE handle, INT count, LPVOID buffer);
HDC FASTCALL
IntGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PUNICODE_STRING Output,
PVOID pUMdhpdev,
CONST PDEVMODEW InitData,
BOOL CreateAsIC);

View file

@ -39,7 +39,7 @@
/* NOTE - I think we should store this per window station (including gdi objects) */
static PDCE FirstDce = NULL;
static HDC defaultDCstate = NULL;
static PDC defaultDCstate = NULL;
//static INT DCECount = 0;
#define DCX_CACHECOMPAREMASK (DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | \
@ -126,12 +126,16 @@ DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type)
ExFreePoolWithTag(pDce, TAG_PDCE);
return NULL;
}
//
// If NULL, first time through! Build the default window dc!
//
if (NULL == defaultDCstate) // Ultra HAX! Dedicated to GvG!
{ // This is a cheesy way to do this.
// But, due to the right way of creating gdi handles there is no choice.
defaultDCstate = IntGdiGetDCState(pDce->hDC);
DC_SetOwnership( defaultDCstate, NULL);
PDC dc = DC_LockDc ( pDce->hDC );
defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
RtlZeroMemory(defaultDCstate, sizeof(DC));
IntGdiCopyToSaveState(dc, defaultDCstate);
DC_UnlockDc( dc );
}
pDce->hwndCurrent = (Window ? Window->hSelf : NULL);
@ -144,8 +148,7 @@ DceAllocDCE(PWINDOW_OBJECT Window OPTIONAL, DCE_TYPE Type)
KeLeaveCriticalRegion();
if (Type == DCE_WINDOW_DC) //Window DCE have ownership.
{
DC_SetOwnership(pDce->hDC, PsGetCurrentProcess());
{ // Process should already own it.
pDce->pProcess = PsGetCurrentProcess();
}
else
@ -248,13 +251,8 @@ DceReleaseDC(DCE* dce, BOOL EndPaint)
/* make the DC clean so that SetDCState doesn't try to update the vis rgn */
IntGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN);
if( dce->pProcess ) // Attempt to fix Dc_Attr problem.
DC_SetOwnership( defaultDCstate, dce->pProcess);
else
DC_SetOwnership( defaultDCstate, PsGetCurrentProcess());
IntGdiSetDCState(dce->hDC, defaultDCstate);
DC_SetOwnership( defaultDCstate, NULL); // Return default dc state to inaccessible mode.
PDC dc = DC_LockDc ( dce->hDC );
IntGdiCopyFromSaveState(dc, defaultDCstate); // Was SetDCState.
dce->DCXFlags &= ~DCX_DCEBUSY;
if (dce->DCXFlags & DCX_DCEDIRTY)

View file

@ -809,7 +809,7 @@ IntDestroyPrimarySurface()
HDC FASTCALL
IntGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Device,
PUNICODE_STRING Output,
PVOID pUMdhpdev,
CONST PDEVMODEW InitData,
BOOL CreateAsIC)
{
@ -909,6 +909,7 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
memcpy(NewDC->FillPatternSurfaces, PrimarySurface.FillPatterns,
sizeof(NewDC->FillPatternSurfaces));
NewDC->PDev = PrimarySurface.PDev;
if(pUMdhpdev) pUMdhpdev = NewDC->PDev;
NewDC->GDIDevice = (HDEV)&PrimarySurface;
NewDC->DriverFunctions = PrimarySurface.DriverFunctions;
NewDC->w.hBitmap = PrimarySurface.Handle;
@ -963,6 +964,7 @@ NtGdiOpenDCW( PUNICODE_STRING Device,
{
UNICODE_STRING SafeDevice;
DEVMODEW SafeInitData;
PVOID Dhpdev;
HDC Ret;
NTSTATUS Status = STATUS_SUCCESS;
@ -970,6 +972,12 @@ NtGdiOpenDCW( PUNICODE_STRING Device,
{
_SEH_TRY
{
if (pUMdhpdev)
{
ProbeForWrite(pUMdhpdev,
sizeof(PVOID),
1);
}
ProbeForRead(InitData,
sizeof(DEVMODEW),
1);
@ -1002,10 +1010,12 @@ NtGdiOpenDCW( PUNICODE_STRING Device,
Ret = IntGdiCreateDC(NULL == Device ? NULL : &SafeDevice,
NULL,
NULL,
NULL == pUMdhpdev ? NULL : &Dhpdev,
NULL == InitData ? NULL : &SafeInitData,
(BOOL) iType); // FALSE 0 DCW, TRUE 1 ICW
if (pUMdhpdev) pUMdhpdev = Dhpdev;
return Ret;
}
@ -1281,29 +1291,11 @@ NtGdiSetBkColor(HDC hDC, COLORREF color)
return oldColor;
}
HDC STDCALL
IntGdiGetDCState(HDC hDC)
VOID
FASTCALL
IntGdiCopyToSaveState(PDC dc, PDC newdc)
{
PDC newdc, dc;
HDC hnewdc;
dc = DC_LockDc(hDC);
if (dc == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
hnewdc = DC_AllocDC(NULL);
if (hnewdc == NULL)
{
DC_UnlockDc(dc);
return 0;
}
newdc = DC_LockDc( hnewdc );
/* FIXME - newdc can be NULL!!!! Don't assert here!!! */
ASSERT( newdc );
newdc->w.flags = dc->w.flags | DC_SAVED;
newdc->Dc_Attr.hpen = dc->Dc_Attr.hpen;
newdc->Dc_Attr.hbrush = dc->Dc_Attr.hbrush;
@ -1344,7 +1336,6 @@ IntGdiGetDCState(HDC hDC)
newdc->w.xformWorld2Vport = dc->w.xformWorld2Vport;
newdc->w.xformVport2World = dc->w.xformVport2World;
newdc->w.vport2WorldValid = dc->w.vport2WorldValid;
DCU_UpdateUserXForms(newdc, WORLD_TO_PAGE_IDENTITY|DEVICE_TO_WORLD_INVALID|WORLD_XFORM_CHANGED );
newdc->Dc_Attr.ptlWindowOrg.x = dc->Dc_Attr.ptlWindowOrg.x;
newdc->Dc_Attr.ptlWindowOrg.y = dc->Dc_Attr.ptlWindowOrg.y;
newdc->Dc_Attr.szlWindowExt.cx = dc->Dc_Attr.szlWindowExt.cx;
@ -1354,7 +1345,6 @@ IntGdiGetDCState(HDC hDC)
newdc->Dc_Attr.szlViewportExt.cx = dc->Dc_Attr.szlViewportExt.cx;
newdc->Dc_Attr.szlViewportExt.cy = dc->Dc_Attr.szlViewportExt.cy;
newdc->hSelf = hnewdc;
newdc->saveLevel = 0;
newdc->IsIC = dc->IsIC;
@ -1370,6 +1360,136 @@ IntGdiGetDCState(HDC hDC)
newdc->w.hClipRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
NtGdiCombineRgn( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
}
}
VOID
FASTCALL
IntGdiCopyFromSaveState(PDC dc, PDC dcs)
{
HDC hDC = dc->hSelf;
dc->w.flags = dcs->w.flags & ~DC_SAVED;
dc->w.hFirstBitmap = dcs->w.hFirstBitmap;
#if 0
dc->w.hDevice = dcs->w.hDevice;
#endif
dc->w.totalExtent = dcs->w.totalExtent;
dc->Dc_Attr.jROP2 = dcs->Dc_Attr.jROP2;
dc->Dc_Attr.jFillMode = dcs->Dc_Attr.jFillMode;
dc->Dc_Attr.jStretchBltMode = dcs->Dc_Attr.jStretchBltMode;
dc->Dc_Attr.lRelAbs = dcs->Dc_Attr.lRelAbs;
dc->Dc_Attr.jBkMode = dcs->Dc_Attr.jBkMode;
dc->Dc_Attr.crBackgroundClr = dcs->Dc_Attr.crBackgroundClr;
dc->Dc_Attr.crForegroundClr = dcs->Dc_Attr.crForegroundClr;
dc->Dc_Attr.ptlBrushOrigin.x = dcs->Dc_Attr.ptlBrushOrigin.x;
dc->Dc_Attr.ptlBrushOrigin.y = dcs->Dc_Attr.ptlBrushOrigin.y;
dc->Dc_Attr.lTextAlign = dcs->Dc_Attr.lTextAlign;
dc->Dc_Attr.lTextExtra = dcs->Dc_Attr.lTextExtra;
dc->Dc_Attr.cBreak = dcs->Dc_Attr.cBreak;
dc->Dc_Attr.lBreakExtra = dcs->Dc_Attr.lBreakExtra;
dc->Dc_Attr.iMapMode = dcs->Dc_Attr.iMapMode;
dc->Dc_Attr.iGraphicsMode = dcs->Dc_Attr.iGraphicsMode;
#if 0
/* Apparently, the DC origin is not changed by [GS]etDCState */
dc->w.DCOrgX = dcs->w.DCOrgX;
dc->w.DCOrgY = dcs->w.DCOrgY;
#endif
dc->Dc_Attr.ptlCurrent.x = dcs->Dc_Attr.ptlCurrent.x;
dc->Dc_Attr.ptlCurrent.y = dcs->Dc_Attr.ptlCurrent.y;
dc->w.ArcDirection = dcs->w.ArcDirection;
dc->w.xformWorld2Wnd = dcs->w.xformWorld2Wnd;
dc->w.xformWorld2Vport = dcs->w.xformWorld2Vport;
dc->w.xformVport2World = dcs->w.xformVport2World;
dc->w.vport2WorldValid = dcs->w.vport2WorldValid;
dc->Dc_Attr.ptlWindowOrg.x = dcs->Dc_Attr.ptlWindowOrg.x;
dc->Dc_Attr.ptlWindowOrg.y = dcs->Dc_Attr.ptlWindowOrg.y;
dc->Dc_Attr.szlWindowExt.cx = dcs->Dc_Attr.szlWindowExt.cx;
dc->Dc_Attr.szlWindowExt.cy = dcs->Dc_Attr.szlWindowExt.cy;
dc->Dc_Attr.ptlViewportOrg.x = dcs->Dc_Attr.ptlViewportOrg.x;
dc->Dc_Attr.ptlViewportOrg.y = dcs->Dc_Attr.ptlViewportOrg.y;
dc->Dc_Attr.szlViewportExt.cx = dcs->Dc_Attr.szlViewportExt.cx;
dc->Dc_Attr.szlViewportExt.cy = dcs->Dc_Attr.szlViewportExt.cy;
dc->PalIndexed = dcs->PalIndexed;
if (!(dc->w.flags & DC_MEMORY))
{
dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
}
#if 0
if (dcs->w.hClipRgn)
{
if (!dc->w.hClipRgn)
{
dc->w.hClipRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
}
NtGdiCombineRgn( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY );
}
else
{
if (dc->w.hClipRgn)
{
NtGdiDeleteObject( dc->w.hClipRgn );
}
dc->w.hClipRgn = 0;
}
{
int res;
res = CLIPPING_UpdateGCRegion( dc );
ASSERT ( res != ERROR );
}
DC_UnlockDc ( dc );
#else
IntGdiExtSelectClipRgn(dc, dcs->w.hClipRgn, RGN_COPY);
DC_UnlockDc ( dc );
#endif
NtGdiSelectObject( hDC, dcs->w.hBitmap );
NtGdiSelectObject( hDC, dcs->Dc_Attr.hbrush );
NtGdiSelectObject( hDC, dcs->Dc_Attr.hlfntNew );
NtGdiSelectObject( hDC, dcs->Dc_Attr.hpen );
NtGdiSetBkColor( hDC, dcs->Dc_Attr.crBackgroundClr);
NtGdiSetTextColor( hDC, dcs->Dc_Attr.crForegroundClr);
NtUserSelectPalette( hDC, dcs->w.hPalette, FALSE );
#if 0
GDISelectPalette16( hDC, dcs->w.hPalette, FALSE );
#endif
}
HDC STDCALL
IntGdiGetDCState(HDC hDC)
{
PDC newdc, dc;
HDC hnewdc;
dc = DC_LockDc(hDC);
if (dc == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
hnewdc = DC_AllocDC(NULL);
if (hnewdc == NULL)
{
DC_UnlockDc(dc);
return 0;
}
newdc = DC_LockDc( hnewdc );
/* FIXME - newdc can be NULL!!!! Don't assert here!!! */
ASSERT( newdc );
newdc->hSelf = hnewdc;
IntGdiCopyToSaveState( dc, newdc);
DCU_SyncDcAttrtoUser(newdc, -1);
DC_UnlockDc( newdc );
DC_UnlockDc( dc );
@ -1391,105 +1511,16 @@ IntGdiSetDCState ( HDC hDC, HDC hDCSave )
{
if ( dcs->w.flags & DC_SAVED )
{
dc->w.flags = dcs->w.flags & ~DC_SAVED;
dc->w.hFirstBitmap = dcs->w.hFirstBitmap;
#if 0
dc->w.hDevice = dcs->w.hDevice;
#endif
dc->w.totalExtent = dcs->w.totalExtent;
dc->Dc_Attr.jROP2 = dcs->Dc_Attr.jROP2;
dc->Dc_Attr.jFillMode = dcs->Dc_Attr.jFillMode;
dc->Dc_Attr.jStretchBltMode = dcs->Dc_Attr.jStretchBltMode;
dc->Dc_Attr.lRelAbs = dcs->Dc_Attr.lRelAbs;
dc->Dc_Attr.jBkMode = dcs->Dc_Attr.jBkMode;
dc->Dc_Attr.crBackgroundClr = dcs->Dc_Attr.crBackgroundClr;
dc->Dc_Attr.crForegroundClr = dcs->Dc_Attr.crForegroundClr;
dc->Dc_Attr.ptlBrushOrigin.x = dcs->Dc_Attr.ptlBrushOrigin.x;
dc->Dc_Attr.ptlBrushOrigin.y = dcs->Dc_Attr.ptlBrushOrigin.y;
dc->Dc_Attr.lTextAlign = dcs->Dc_Attr.lTextAlign;
dc->Dc_Attr.lTextExtra = dcs->Dc_Attr.lTextExtra;
dc->Dc_Attr.cBreak = dcs->Dc_Attr.cBreak;
dc->Dc_Attr.lBreakExtra = dcs->Dc_Attr.lBreakExtra;
dc->Dc_Attr.iMapMode = dcs->Dc_Attr.iMapMode;
dc->Dc_Attr.iGraphicsMode = dcs->Dc_Attr.iGraphicsMode;
#if 0
/* Apparently, the DC origin is not changed by [GS]etDCState */
dc->w.DCOrgX = dcs->w.DCOrgX;
dc->w.DCOrgY = dcs->w.DCOrgY;
#endif
dc->Dc_Attr.ptlCurrent.x = dcs->Dc_Attr.ptlCurrent.x;
dc->Dc_Attr.ptlCurrent.y = dcs->Dc_Attr.ptlCurrent.y;
dc->w.ArcDirection = dcs->w.ArcDirection;
dc->w.xformWorld2Wnd = dcs->w.xformWorld2Wnd;
dc->w.xformWorld2Vport = dcs->w.xformWorld2Vport;
dc->w.xformVport2World = dcs->w.xformVport2World;
dc->w.vport2WorldValid = dcs->w.vport2WorldValid;
DCU_UpdateUserXForms(dc, WORLD_TO_PAGE_IDENTITY|DEVICE_TO_WORLD_INVALID|WORLD_XFORM_CHANGED );
dc->Dc_Attr.ptlWindowOrg.x = dcs->Dc_Attr.ptlWindowOrg.x;
dc->Dc_Attr.ptlWindowOrg.y = dcs->Dc_Attr.ptlWindowOrg.y;
dc->Dc_Attr.szlWindowExt.cx = dcs->Dc_Attr.szlWindowExt.cx;
dc->Dc_Attr.szlWindowExt.cy = dcs->Dc_Attr.szlWindowExt.cy;
dc->Dc_Attr.ptlViewportOrg.x = dcs->Dc_Attr.ptlViewportOrg.x;
dc->Dc_Attr.ptlViewportOrg.y = dcs->Dc_Attr.ptlViewportOrg.y;
dc->Dc_Attr.szlViewportExt.cx = dcs->Dc_Attr.szlViewportExt.cx;
dc->Dc_Attr.szlViewportExt.cy = dcs->Dc_Attr.szlViewportExt.cy;
dc->PalIndexed = dcs->PalIndexed;
if (!(dc->w.flags & DC_MEMORY))
{
dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
}
#if 0
if (dcs->w.hClipRgn)
{
if (!dc->w.hClipRgn)
{
dc->w.hClipRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
}
NtGdiCombineRgn( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY );
}
else
{
if (dc->w.hClipRgn)
{
NtGdiDeleteObject( dc->w.hClipRgn );
}
dc->w.hClipRgn = 0;
}
{
int res;
res = CLIPPING_UpdateGCRegion( dc );
ASSERT ( res != ERROR );
}
DC_UnlockDc ( dc );
#else
IntGdiExtSelectClipRgn(dc, dcs->w.hClipRgn, RGN_COPY);
DC_UnlockDc ( dc );
#endif
NtGdiSelectObject( hDC, dcs->w.hBitmap );
NtGdiSelectObject( hDC, dcs->Dc_Attr.hbrush );
NtGdiSelectObject( hDC, dcs->Dc_Attr.hlfntNew );
NtGdiSelectObject( hDC, dcs->Dc_Attr.hpen );
NtGdiSetBkColor( hDC, dcs->Dc_Attr.crBackgroundClr);
NtGdiSetTextColor( hDC, dcs->Dc_Attr.crForegroundClr);
NtUserSelectPalette( hDC, dcs->w.hPalette, FALSE );
#if 0
GDISelectPalette16( hDC, dcs->w.hPalette, FALSE );
#endif
} else {
IntGdiCopyFromSaveState( dc, dcs);
}
else
{
DC_UnlockDc(dc);
}
DC_UnlockDc ( dcs );
} else {
}
else
{
DC_UnlockDc ( dc );
SetLastWin32Error(ERROR_INVALID_HANDLE);
}
@ -2607,7 +2638,6 @@ DC_SetOwnership(HDC hDC, PEPROCESS Owner)
{
PDC DC;
// DC_FreeDcAttr(hDC, NULL);
GDIOBJ_SetOwnership(GdiHandleTable, hDC, Owner);
DC = DC_LockDc(hDC);
if (NULL != DC)
@ -2626,7 +2656,6 @@ DC_SetOwnership(HDC hDC, PEPROCESS Owner)
}
DC_UnlockDc(DC);
}
// DC_AllocateDcAttr(hDC, Owner);
}
BOOL FASTCALL