2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Functions for creation and destruction of DCs
5 * FILE: subsystem/win32/win32k/objects/dclife.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@rectos.org)
15 /** Internal functions ********************************************************/
18 DC_AllocDC(PUNICODE_STRING Driver
)
30 Buf
= ExAllocatePoolWithTag(PagedPool
, Driver
->MaximumLength
, TAG_DC
);
33 DPRINT1("ExAllocatePoolWithTag failed\n");
36 RtlCopyMemory(Buf
, Driver
->Buffer
, Driver
->MaximumLength
);
39 NewDC
= (PDC
)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_DC
);
44 ExFreePoolWithTag(Buf
, TAG_DC
);
46 DPRINT1("GDIOBJ_AllocObjWithHandle failed\n");
50 hDC
= NewDC
->BaseObject
.hHmgr
;
52 NewDC
->pdcattr
= &NewDC
->dcattr
;
53 DC_AllocateDcAttr(hDC
);
57 RtlCopyMemory(&NewDC
->rosdc
.DriverName
, Driver
, sizeof(UNICODE_STRING
));
58 NewDC
->rosdc
.DriverName
.Buffer
= Buf
;
60 pdcattr
= NewDC
->pdcattr
;
62 // FIXME: no floating point in the kernel!
63 xformTemplate
.eM11
= 1.0f
;
64 xformTemplate
.eM12
= 0.0f
;
65 xformTemplate
.eM21
= 0.0f
;
66 xformTemplate
.eM22
= 1.0f
;
67 xformTemplate
.eDx
= 0.0f
;
68 xformTemplate
.eDy
= 0.0f
;
69 XForm2MatrixS(&NewDC
->dclevel
.mxWorldToDevice
, &xformTemplate
);
70 XForm2MatrixS(&NewDC
->dclevel
.mxDeviceToWorld
, &xformTemplate
);
71 XForm2MatrixS(&NewDC
->dclevel
.mxWorldToPage
, &xformTemplate
);
73 // Setup syncing bits for the dcattr data packets.
74 pdcattr
->flXform
= DEVICE_TO_PAGE_INVALID
;
76 pdcattr
->ulDirty_
= 0; // Server side
78 pdcattr
->iMapMode
= MM_TEXT
;
79 pdcattr
->iGraphicsMode
= GM_COMPATIBLE
;
80 pdcattr
->jFillMode
= ALTERNATE
;
82 pdcattr
->szlWindowExt
.cx
= 1; // Float to Int,,, WRONG!
83 pdcattr
->szlWindowExt
.cy
= 1;
84 pdcattr
->szlViewportExt
.cx
= 1;
85 pdcattr
->szlViewportExt
.cy
= 1;
87 pdcattr
->crForegroundClr
= 0;
88 pdcattr
->ulForegroundClr
= 0;
90 pdcattr
->ulBackgroundClr
= 0xffffff;
91 pdcattr
->crBackgroundClr
= 0xffffff;
93 pdcattr
->ulPenClr
= RGB(0, 0, 0);
94 pdcattr
->crPenClr
= RGB(0, 0, 0);
96 pdcattr
->ulBrushClr
= RGB(255, 255, 255); // Do this way too.
97 pdcattr
->crBrushClr
= RGB(255, 255, 255);
99 //// This fixes the default brush and pen settings. See DC_InitDC.
101 /* Create the default fill brush */
102 pdcattr
->hbrush
= NtGdiGetStockObject(WHITE_BRUSH
);
103 NewDC
->dclevel
.pbrFill
= BRUSH_ShareLockBrush(pdcattr
->hbrush
);
104 EBRUSHOBJ_vInit(&NewDC
->eboFill
, NewDC
->dclevel
.pbrFill
, NewDC
);
106 /* Create the default pen / line brush */
107 pdcattr
->hpen
= NtGdiGetStockObject(BLACK_PEN
);
108 NewDC
->dclevel
.pbrLine
= PEN_ShareLockPen(pdcattr
->hpen
);
109 EBRUSHOBJ_vInit(&NewDC
->eboLine
, NewDC
->dclevel
.pbrLine
, NewDC
);
111 /* Create the default text brush */
112 pbrush
= BRUSH_ShareLockBrush(NtGdiGetStockObject(BLACK_BRUSH
));
113 EBRUSHOBJ_vInit(&NewDC
->eboText
, pbrush
, NewDC
);
114 pdcattr
->ulDirty_
|= DIRTY_TEXT
;
116 /* Create the default background brush */
117 pbrush
= BRUSH_ShareLockBrush(NtGdiGetStockObject(WHITE_BRUSH
));
118 EBRUSHOBJ_vInit(&NewDC
->eboBackground
, pbrush
, NewDC
);
120 pdcattr
->hlfntNew
= NtGdiGetStockObject(SYSTEM_FONT
);
121 TextIntRealizeFont(pdcattr
->hlfntNew
,NULL
);
122 NewDC
->hlfntCur
= pdcattr
->hlfntNew
;
123 NewDC
->dclevel
.plfnt
= GDIOBJ_GetKernelObj(pdcattr
->hlfntNew
);
125 NewDC
->dclevel
.hpal
= NtGdiGetStockObject(DEFAULT_PALETTE
);
126 NewDC
->dclevel
.ppal
= PALETTE_ShareLockPalette(NewDC
->dclevel
.hpal
);
127 /* This should never fail */
128 ASSERT(NewDC
->dclevel
.ppal
);
130 NewDC
->dclevel
.laPath
.eMiterLimit
= 10.0; // FIXME: use FLOATL or FLOATOBJ!
132 NewDC
->dclevel
.lSaveDepth
= 1;
134 hsurf
= (HBITMAP
)PrimarySurface
.pSurface
; // <- what kind of haxx0ry is that?
135 NewDC
->dclevel
.pSurface
= SURFACE_ShareLockSurface(hsurf
);
141 DC_Cleanup(PVOID ObjectBody
)
143 PDC pDC
= (PDC
)ObjectBody
;
145 /* Free driver name (HACK) */
146 if (pDC
->rosdc
.DriverName
.Buffer
)
147 ExFreePoolWithTag(pDC
->rosdc
.DriverName
.Buffer
, TAG_DC
);
149 /* Deselect dc objects */
150 DC_vSelectSurface(pDC
, NULL
);
151 DC_vSelectFillBrush(pDC
, NULL
);
152 DC_vSelectLineBrush(pDC
, NULL
);
153 DC_vSelectPalette(pDC
, NULL
);
155 /* Dereference default brushes */
156 BRUSH_ShareUnlockBrush(pDC
->eboText
.pbrush
);
157 BRUSH_ShareUnlockBrush(pDC
->eboBackground
.pbrush
);
159 /* Cleanup the dc brushes */
160 EBRUSHOBJ_vCleanup(&pDC
->eboFill
);
161 EBRUSHOBJ_vCleanup(&pDC
->eboLine
);
162 EBRUSHOBJ_vCleanup(&pDC
->eboText
);
163 EBRUSHOBJ_vCleanup(&pDC
->eboBackground
);
170 DC_SetOwnership(HDC hDC
, PEPROCESS Owner
)
173 PGDI_TABLE_ENTRY Entry
;
176 if (!GDIOBJ_SetOwnership(hDC
, Owner
)) return FALSE
;
177 pDC
= DC_LockDc(hDC
);
182 These regions do not use attribute sections and when allocated, use
183 gdiobj level functions.
185 if (pDC
->rosdc
.hClipRgn
)
187 Index
= GDI_HANDLE_GET_INDEX(pDC
->rosdc
.hClipRgn
);
188 Entry
= &GdiHandleTable
->Entries
[Index
];
189 if (Entry
->UserData
) FreeObjectAttr(Entry
->UserData
);
190 Entry
->UserData
= NULL
;
192 if (!GDIOBJ_SetOwnership(pDC
->rosdc
.hClipRgn
, Owner
)) return FALSE
;
194 if (pDC
->rosdc
.hVisRgn
)
196 Index
= GDI_HANDLE_GET_INDEX(pDC
->rosdc
.hVisRgn
);
197 Entry
= &GdiHandleTable
->Entries
[Index
];
198 if (Entry
->UserData
) FreeObjectAttr(Entry
->UserData
);
199 Entry
->UserData
= NULL
;
201 if (!GDIOBJ_SetOwnership(pDC
->rosdc
.hVisRgn
, Owner
)) return FALSE
;
203 if (pDC
->rosdc
.hGCClipRgn
)
205 Index
= GDI_HANDLE_GET_INDEX(pDC
->rosdc
.hGCClipRgn
);
206 Entry
= &GdiHandleTable
->Entries
[Index
];
207 if (Entry
->UserData
) FreeObjectAttr(Entry
->UserData
);
208 Entry
->UserData
= NULL
;
210 if (!GDIOBJ_SetOwnership(pDC
->rosdc
.hGCClipRgn
, Owner
)) return FALSE
;
212 if (pDC
->dclevel
.hPath
)
214 if (!GDIOBJ_SetOwnership(pDC
->dclevel
.hPath
, Owner
)) return FALSE
;
225 PUNICODE_STRING Driver
,
226 PUNICODE_STRING Device
,
228 CONST PDEVMODEW InitData
,
235 UNICODE_STRING StdDriver
;
238 RtlInitUnicodeString(&StdDriver
, L
"DISPLAY");
240 DPRINT("DriverName: %wZ, DeviceName: %wZ\n", Driver
, Device
);
242 if (NULL
== Driver
|| 0 == RtlCompareUnicodeString(Driver
, &StdDriver
, TRUE
))
246 if (! IntPrepareDriverIfNeeded())
248 /* Here, we have two possibilities:
249 * a) return NULL, and hope that the caller
250 * won't call us in a loop
251 * b) bugcheck, but caller is unable to
252 * react on the problem
254 /*DPRINT1("Unable to prepare graphics driver, returning NULL ic\n");
256 KeBugCheck(VIDEO_DRIVER_INIT_FAILURE
);
261 calledFromUser
= UserIsEntered();
264 UserEnterExclusive();
267 if (! co_IntGraphicsCheck(TRUE
))
273 DPRINT1("Unable to initialize graphics, returning NULL dc\n");
285 /* Check for existing DC object */
286 if ((hdc
= DC_FindOpenDC(Driver
)) != NULL
)
288 hdc
= NtGdiCreateCompatibleDC(hdc
);
290 DPRINT1("NtGdiCreateCompatibleDC() failed\n");
294 /* Allocate a DC object */
295 pdc
= DC_AllocDC(Driver
);
298 DPRINT1("DC_AllocDC() failed\n");
301 hdc
= pdc
->BaseObject
.hHmgr
;
302 pdcattr
= pdc
->pdcattr
;
304 pdc
->dctype
= DC_TYPE_DIRECT
;
306 pdc
->dhpdev
= PrimarySurface
.dhpdev
;
307 if (pUMdhpdev
) pUMdhpdev
= pdc
->dhpdev
; // set DHPDEV for device.
308 pdc
->ppdev
= (PVOID
)&PrimarySurface
;
310 // ATM we only have one display.
311 pdcattr
->ulDirty_
|= DC_PRIMARY_DISPLAY
;
313 pdc
->flGraphicsCaps
= PrimarySurface
.devinfo
.flGraphicsCaps
;
314 pdc
->flGraphicsCaps2
= PrimarySurface
.devinfo
.flGraphicsCaps2
;
316 pdc
->dclevel
.hpal
= NtGdiGetStockObject(DEFAULT_PALETTE
);
318 pdcattr
->jROP2
= R2_COPYPEN
;
320 pdc
->erclWindow
.top
= pdc
->erclWindow
.left
= 0;
321 pdc
->erclWindow
.right
= pdc
->ppdev
->gdiinfo
.ulHorzRes
;
322 pdc
->erclWindow
.bottom
= pdc
->ppdev
->gdiinfo
.ulVertRes
;
323 pdc
->dclevel
.flPath
&= ~DCPATH_CLOCKWISE
; // Default is CCW.
325 pdcattr
->iCS_CP
= ftGdiGetTextCharsetInfo(pdc
,NULL
,0);
327 hVisRgn
= IntSysCreateRectRgn(0, 0, pdc
->ppdev
->gdiinfo
.ulHorzRes
,
328 pdc
->ppdev
->gdiinfo
.ulVertRes
);
332 pdc
->pSurfInfo
= NULL
;
333 // pdc->dclevel.pSurface =
336 /* Initialize the DC state */
337 IntGdiSetTextColor(hdc
, RGB(0, 0, 0));
338 IntGdiSetBkColor(hdc
, RGB(255, 255, 255));
343 The CreateIC function creates an information context for the specified device.
344 The information context provides a fast way to get information about the
345 device without creating a device context (DC). However, GDI drawing functions
346 cannot accept a handle to an information context.
348 pdc
->dctype
= DC_TYPE_INFO
;
350 // DC_vSelectSurface(pdc, NULL);
351 pdcattr
->crBackgroundClr
= pdcattr
->ulBackgroundClr
= RGB(255, 255, 255);
352 pdcattr
->crForegroundClr
= RGB(0, 0, 0);
359 GdiSelectVisRgn(hdc
, hVisRgn
);
360 REGION_FreeRgnByHandle(hVisRgn
);
363 IntGdiSetTextAlign(hdc
, TA_TOP
);
364 IntGdiSetBkMode(hdc
, OPAQUE
);
372 PUNICODE_STRING Device
,
374 PUNICODE_STRING pustrLogAddr
,
381 UNICODE_STRING SafeDevice
;
382 DEVMODEW SafeInitData
;
385 NTSTATUS Status
= STATUS_SUCCESS
;
387 if (!Device
) return UserGetDesktopDC(iType
,FALSE
,TRUE
);
395 ProbeForWrite(pUMdhpdev
, sizeof(PVOID
), 1);
397 ProbeForRead(InitData
, sizeof(DEVMODEW
), 1);
398 RtlCopyMemory(&SafeInitData
, InitData
, sizeof(DEVMODEW
));
400 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
402 Status
= _SEH2_GetExceptionCode();
406 if (!NT_SUCCESS(Status
))
408 SetLastNtError(Status
);
411 /* FIXME - InitData can have some more bytes! */
416 Status
= IntSafeCopyUnicodeString(&SafeDevice
, Device
);
417 if (!NT_SUCCESS(Status
))
419 SetLastNtError(Status
);
424 Ret
= IntGdiCreateDC(Device
? &SafeDevice
: NULL
,
426 pUMdhpdev
? &Dhpdev
: NULL
,
427 InitData
? &SafeInitData
: NULL
,
428 (BOOL
) iType
); // FALSE 0 DCW, TRUE 1 ICW
431 if (pUMdhpdev
) pUMdhpdev
= Dhpdev
;
437 IntGdiCreateDisplayDC(HDEV hDev
, ULONG DcType
, BOOL EmptyDC
)
440 UNICODE_STRING DriverName
;
441 RtlInitUnicodeString(&DriverName
, L
"DISPLAY");
443 if (DcType
!= DC_TYPE_MEMORY
)
444 hDC
= IntGdiCreateDC(&DriverName
, NULL
, NULL
, NULL
, (DcType
== DC_TYPE_INFO
));
446 hDC
= NtGdiCreateCompatibleDC(NULL
); // OH~ Yuck! I think I taste vomit in my mouth!
448 // There is room to grow here~
452 // If NULL, first time through! Build the default (was window) dc!
453 // Setup clean DC state for the system.
455 if (hDC
&& !defaultDCstate
) // Ultra HAX! Dedicated to GvG!
456 { // This is a cheesy way to do this.
457 PDC dc
= DC_LockDc(hDC
);
459 defaultDCstate
= ExAllocatePoolWithTag(PagedPool
, sizeof(DC
), TAG_DC
);
465 RtlZeroMemory(defaultDCstate
, sizeof(DC
));
466 defaultDCstate
->pdcattr
= &defaultDCstate
->dcattr
;
467 hsurf
= (HSURF
)PrimarySurface
.pSurface
; // HAX²
468 defaultDCstate
->dclevel
.pSurface
= SURFACE_ShareLockSurface(hsurf
);
469 DC_vCopyState(dc
, defaultDCstate
, TRUE
);
477 IntGdiDeleteDC(HDC hDC
, BOOL Force
)
479 PDC DCToDelete
= DC_LockDc(hDC
);
481 if (DCToDelete
== NULL
)
483 SetLastWin32Error(ERROR_INVALID_HANDLE
);
489 if (DCToDelete
->fs
& DC_FLAG_PERMANENT
)
491 DPRINT1("No! You Naughty Application!\n");
492 DC_UnlockDc(DCToDelete
);
493 return UserReleaseDC(NULL
, hDC
, FALSE
);
497 /* First delete all saved DCs */
498 while (DCToDelete
->dclevel
.lSaveDepth
> 1)
503 savedHDC
= DCToDelete
->hdcNext
;
504 savedDC
= DC_LockDc(savedHDC
);
509 DCToDelete
->hdcNext
= savedDC
->hdcNext
;
510 DCToDelete
->dclevel
.lSaveDepth
--;
511 DC_UnlockDc(savedDC
);
512 IntGdiDeleteDC(savedHDC
, Force
);
515 /* Free GDI resources allocated to this DC */
516 if (!(DCToDelete
->dclevel
.flPath
& DCPATH_SAVESTATE
))
519 NtGdiSelectPen (DCHandle, STOCK_BLACK_PEN);
520 NtGdiSelectBrush (DCHandle, STOCK_WHITE_BRUSH);
521 NtGdiSelectFont (DCHandle, STOCK_SYSTEM_FONT);
522 DC_LockDC (DCHandle); NtGdiSelectXxx does not recognize stock objects yet */
524 if (DCToDelete
->rosdc
.hClipRgn
)
526 GreDeleteObject(DCToDelete
->rosdc
.hClipRgn
);
528 if (DCToDelete
->rosdc
.hVisRgn
)
530 GreDeleteObject(DCToDelete
->rosdc
.hVisRgn
);
532 if (NULL
!= DCToDelete
->rosdc
.CombinedClip
)
534 IntEngDeleteClipRegion(DCToDelete
->rosdc
.CombinedClip
);
536 if (DCToDelete
->rosdc
.hGCClipRgn
)
538 GreDeleteObject(DCToDelete
->rosdc
.hGCClipRgn
);
540 if (DCToDelete
->dclevel
.prgnMeta
)
542 GreDeleteObject(((PROSRGNDATA
)DCToDelete
->dclevel
.prgnMeta
)->BaseObject
.hHmgr
);
544 if (DCToDelete
->prgnAPI
)
546 GreDeleteObject(((PROSRGNDATA
)DCToDelete
->prgnAPI
)->BaseObject
.hHmgr
);
548 PATH_Delete(DCToDelete
->dclevel
.hPath
);
550 DC_UnlockDc(DCToDelete
);
551 GreDeleteObject(hDC
);
556 DC_FindOpenDC(PUNICODE_STRING Driver
)
562 * Initialize some common fields in the Device Context structure.
565 DC_InitDC(HDC DCHandle
)
567 // NtGdiRealizeDefaultPalette(DCHandle);
569 //// Removed for now.. See above brush and pen.
570 // NtGdiSelectBrush(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
571 // NtGdiSelectPen(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
573 //NtGdiSelectFont(DCHandle, hFont);
578 res = CLIPPING_UpdateGCRegion(DCToInit);
579 ASSERT ( res != ERROR );
583 /* Set virtual resolution */
584 NtGdiSetVirtualResolution(DCHandle
, 0, 0, 0, 0);
589 MakeInfoDC(PDC pdc
, BOOL bSet
)
594 /* Can not be a display DC. */
595 if (pdc
->fs
& DC_FLAG_DISPLAY
) return FALSE
;
598 if (pdc
->fs
& DC_FLAG_TEMPINFODC
|| pdc
->dctype
== DC_TYPE_DIRECT
)
601 pSurface
= pdc
->dclevel
.pSurface
;
602 pdc
->fs
|= DC_FLAG_TEMPINFODC
;
603 pdc
->pSurfInfo
= pSurface
;
604 pdc
->dctype
= DC_TYPE_INFO
;
605 pdc
->dclevel
.pSurface
= NULL
;
607 PDEV_sizl(pdc
->ppdev
, &sizl
);
609 if ( sizl
.cx
== pdc
->dclevel
.sizl
.cx
&&
610 sizl
.cy
== pdc
->dclevel
.sizl
.cy
)
613 pdc
->dclevel
.sizl
.cx
= sizl
.cx
;
614 pdc
->dclevel
.sizl
.cy
= sizl
.cy
;
618 if (!(pdc
->fs
& DC_FLAG_TEMPINFODC
) || pdc
->dctype
!= DC_TYPE_INFO
)
621 pSurface
= pdc
->pSurfInfo
;
622 pdc
->fs
&= ~DC_FLAG_TEMPINFODC
;
623 pdc
->dclevel
.pSurface
= pSurface
;
624 pdc
->dctype
= DC_TYPE_DIRECT
;
625 pdc
->pSurfInfo
= NULL
;
628 (pSurface
->SurfObj
.sizlBitmap
.cx
== pdc
->dclevel
.sizl
.cx
&&
629 pSurface
->SurfObj
.sizlBitmap
.cy
== pdc
->dclevel
.sizl
.cy
) )
632 pdc
->dclevel
.sizl
.cx
= pSurface
->SurfObj
.sizlBitmap
.cx
;
633 pdc
->dclevel
.sizl
.cy
= pSurface
->SurfObj
.sizlBitmap
.cy
;
635 return IntSetDefaultRegion(pdc
);
648 PDC pdc
= DC_LockDc(hdc
);
651 Ret
= MakeInfoDC(pdc
, bSet
);
659 NtGdiCreateCompatibleDC(HDC hDC
)
662 PDC_ATTR pdcattrNew
, pdcattrOld
;
663 HDC hdcNew
, DisplayDC
= NULL
;
665 UNICODE_STRING DriverName
;
671 RtlInitUnicodeString(&DriverName
, L
"DISPLAY");
672 DisplayDC
= IntGdiCreateDC(&DriverName
, NULL
, NULL
, NULL
, TRUE
);
673 if (NULL
== DisplayDC
)
675 DPRINT1("Failed to create DisplayDC\n");
681 /* Allocate a new DC based on the original DC's device */
682 pdcOld
= DC_LockDc(hDC
);
685 if (NULL
!= DisplayDC
)
687 NtGdiDeleteObjectApp(DisplayDC
);
689 DPRINT1("Failed to lock hDC\n");
692 pdcNew
= DC_AllocDC(&pdcOld
->rosdc
.DriverName
);
695 DPRINT1("Failed to create pdcNew\n");
699 NtGdiDeleteObjectApp(DisplayDC
);
703 hdcNew
= pdcNew
->BaseObject
.hHmgr
;
705 pdcattrOld
= pdcOld
->pdcattr
;
706 pdcattrNew
= pdcNew
->pdcattr
;
708 /* Copy information from original DC to new DC */
709 pdcNew
->dclevel
.hdcSave
= hdcNew
;
711 pdcNew
->dhpdev
= pdcOld
->dhpdev
;
713 /* DriverName is copied in the AllocDC routine */
714 pdcattrNew
->ptlWindowOrg
= pdcattrOld
->ptlWindowOrg
;
715 pdcattrNew
->szlWindowExt
= pdcattrOld
->szlWindowExt
;
716 pdcattrNew
->ptlViewportOrg
= pdcattrOld
->ptlViewportOrg
;
717 pdcattrNew
->szlViewportExt
= pdcattrOld
->szlViewportExt
;
719 pdcNew
->dctype
= DC_TYPE_MEMORY
; // Always!
720 hsurf
= NtGdiGetStockObject(DEFAULT_BITMAP
);
721 pdcNew
->dclevel
.pSurface
= SURFACE_ShareLockSurface(hsurf
);
722 pdcNew
->ppdev
= pdcOld
->ppdev
;
723 pdcNew
->dclevel
.hpal
= pdcOld
->dclevel
.hpal
;
725 pdcattrNew
->lTextAlign
= pdcattrOld
->lTextAlign
;
726 pdcattrNew
->lBkMode
= pdcattrOld
->lBkMode
;
727 pdcattrNew
->jBkMode
= pdcattrOld
->jBkMode
;
728 pdcattrNew
->jROP2
= pdcattrOld
->jROP2
;
729 pdcattrNew
->dwLayout
= pdcattrOld
->dwLayout
;
730 if (pdcattrOld
->dwLayout
& LAYOUT_ORIENTATIONMASK
) Layout
= pdcattrOld
->dwLayout
;
731 pdcNew
->dclevel
.flPath
= pdcOld
->dclevel
.flPath
;
732 pdcattrNew
->ulDirty_
= pdcattrOld
->ulDirty_
;
733 pdcattrNew
->iCS_CP
= pdcattrOld
->iCS_CP
;
735 pdcNew
->erclWindow
.left
= pdcNew
->erclWindow
.top
= 0;
736 pdcNew
->erclWindow
.right
= pdcNew
->erclWindow
.bottom
= 1;
740 if (NULL
!= DisplayDC
)
742 NtGdiDeleteObjectApp(DisplayDC
);
745 hVisRgn
= IntSysCreateRectRgn(0, 0, 1, 1);
748 GdiSelectVisRgn(hdcNew
, hVisRgn
);
749 REGION_FreeRgnByHandle(hVisRgn
);
751 if (Layout
) NtGdiSetLayout(hdcNew
, -1, Layout
);
760 NtGdiDeleteObjectApp(HANDLE DCHandle
)
764 /* Complete all pending operations */
765 NtGdiFlushUserBatch();
767 if (GDI_HANDLE_IS_STOCKOBJ(DCHandle
)) return TRUE
;
769 if (IsObjectDead((HGDIOBJ
)DCHandle
)) return TRUE
;
771 ObjType
= GDI_HANDLE_GET_TYPE(DCHandle
) >> GDI_ENTRY_UPPER_SHIFT
;
773 if (GreGetObjectOwner( DCHandle
, ObjType
))
777 case GDIObjType_DC_TYPE
:
778 return IntGdiDeleteDC(DCHandle
, FALSE
);
780 case GDIObjType_RGN_TYPE
:
781 case GDIObjType_SURF_TYPE
:
782 case GDIObjType_PAL_TYPE
:
783 case GDIObjType_LFONT_TYPE
:
784 case GDIObjType_BRUSH_TYPE
:
785 return GreDeleteObject((HGDIOBJ
) DCHandle
);
791 return (DCHandle
!= NULL
);