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
);
123 NewDC
->dclevel
.hpal
= NtGdiGetStockObject(DEFAULT_PALETTE
);
124 NewDC
->dclevel
.ppal
= PALETTE_ShareLockPalette(NewDC
->dclevel
.hpal
);
125 /* This should never fail */
126 ASSERT(NewDC
->dclevel
.ppal
);
128 NewDC
->dclevel
.laPath
.eMiterLimit
= 10.0; // FIXME: use FLOATL or FLOATOBJ!
130 NewDC
->dclevel
.lSaveDepth
= 1;
132 hsurf
= (HBITMAP
)PrimarySurface
.pSurface
; // <- what kind of haxx0ry is that?
133 NewDC
->dclevel
.pSurface
= SURFACE_ShareLockSurface(hsurf
);
139 DC_Cleanup(PVOID ObjectBody
)
141 PDC pDC
= (PDC
)ObjectBody
;
143 /* Free driver name (HACK) */
144 if (pDC
->rosdc
.DriverName
.Buffer
)
145 ExFreePoolWithTag(pDC
->rosdc
.DriverName
.Buffer
, TAG_DC
);
147 /* Deselect dc objects */
148 DC_vSelectSurface(pDC
, NULL
);
149 DC_vSelectFillBrush(pDC
, NULL
);
150 DC_vSelectLineBrush(pDC
, NULL
);
151 DC_vSelectPalette(pDC
, NULL
);
153 /* Dereference default brushes */
154 BRUSH_ShareUnlockBrush(pDC
->eboText
.pbrush
);
155 BRUSH_ShareUnlockBrush(pDC
->eboBackground
.pbrush
);
157 /* Cleanup the dc brushes */
158 EBRUSHOBJ_vCleanup(&pDC
->eboFill
);
159 EBRUSHOBJ_vCleanup(&pDC
->eboLine
);
160 EBRUSHOBJ_vCleanup(&pDC
->eboText
);
161 EBRUSHOBJ_vCleanup(&pDC
->eboBackground
);
168 DC_SetOwnership(HDC hDC
, PEPROCESS Owner
)
171 PGDI_TABLE_ENTRY Entry
;
174 if (!GDIOBJ_SetOwnership(hDC
, Owner
)) return FALSE
;
175 pDC
= DC_LockDc(hDC
);
180 These regions do not use attribute sections and when allocated, use
181 gdiobj level functions.
183 if (pDC
->rosdc
.hClipRgn
)
185 KeEnterCriticalRegion();
186 Index
= GDI_HANDLE_GET_INDEX(pDC
->rosdc
.hClipRgn
);
187 Entry
= &GdiHandleTable
->Entries
[Index
];
188 if (Entry
->UserData
) FreeObjectAttr(Entry
->UserData
);
189 Entry
->UserData
= NULL
;
190 KeLeaveCriticalRegion();
192 if (!GDIOBJ_SetOwnership(pDC
->rosdc
.hClipRgn
, Owner
)) return FALSE
;
194 if (pDC
->rosdc
.hVisRgn
)
196 KeEnterCriticalRegion();
197 Index
= GDI_HANDLE_GET_INDEX(pDC
->rosdc
.hVisRgn
);
198 Entry
= &GdiHandleTable
->Entries
[Index
];
199 if (Entry
->UserData
) FreeObjectAttr(Entry
->UserData
);
200 Entry
->UserData
= NULL
;
201 KeLeaveCriticalRegion();
203 if (!GDIOBJ_SetOwnership(pDC
->rosdc
.hVisRgn
, Owner
)) return FALSE
;
205 if (pDC
->rosdc
.hGCClipRgn
)
207 KeEnterCriticalRegion();
208 Index
= GDI_HANDLE_GET_INDEX(pDC
->rosdc
.hGCClipRgn
);
209 Entry
= &GdiHandleTable
->Entries
[Index
];
210 if (Entry
->UserData
) FreeObjectAttr(Entry
->UserData
);
211 Entry
->UserData
= NULL
;
212 KeLeaveCriticalRegion();
214 if (!GDIOBJ_SetOwnership(pDC
->rosdc
.hGCClipRgn
, Owner
)) return FALSE
;
216 if (pDC
->dclevel
.hPath
)
218 if (!GDIOBJ_SetOwnership(pDC
->dclevel
.hPath
, Owner
)) return FALSE
;
229 PUNICODE_STRING Driver
,
230 PUNICODE_STRING Device
,
232 CONST PDEVMODEW InitData
,
239 UNICODE_STRING StdDriver
;
242 RtlInitUnicodeString(&StdDriver
, L
"DISPLAY");
244 DPRINT("DriverName: %wZ, DeviceName: %wZ\n", Driver
, Device
);
246 if (NULL
== Driver
|| 0 == RtlCompareUnicodeString(Driver
, &StdDriver
, TRUE
))
250 if (! IntPrepareDriverIfNeeded())
252 /* Here, we have two possibilities:
253 * a) return NULL, and hope that the caller
254 * won't call us in a loop
255 * b) bugcheck, but caller is unable to
256 * react on the problem
258 /*DPRINT1("Unable to prepare graphics driver, returning NULL ic\n");
260 KeBugCheck(VIDEO_DRIVER_INIT_FAILURE
);
265 calledFromUser
= UserIsEntered();
268 UserEnterExclusive();
271 if (! co_IntGraphicsCheck(TRUE
))
277 DPRINT1("Unable to initialize graphics, returning NULL dc\n");
289 /* Check for existing DC object */
290 if ((hdc
= DC_FindOpenDC(Driver
)) != NULL
)
292 hdc
= NtGdiCreateCompatibleDC(hdc
);
294 DPRINT1("NtGdiCreateCompatibleDC() failed\n");
298 /* Allocate a DC object */
299 pdc
= DC_AllocDC(Driver
);
302 DPRINT1("DC_AllocDC() failed\n");
305 hdc
= pdc
->BaseObject
.hHmgr
;
306 pdcattr
= pdc
->pdcattr
;
308 pdc
->dctype
= DC_TYPE_DIRECT
;
310 pdc
->dhpdev
= PrimarySurface
.dhpdev
;
311 if (pUMdhpdev
) pUMdhpdev
= pdc
->dhpdev
; // set DHPDEV for device.
312 pdc
->ppdev
= (PVOID
)&PrimarySurface
;
314 // ATM we only have one display.
315 pdcattr
->ulDirty_
|= DC_PRIMARY_DISPLAY
;
317 pdc
->rosdc
.bitsPerPixel
= pdc
->ppdev
->gdiinfo
.cBitsPixel
*
318 pdc
->ppdev
->gdiinfo
.cPlanes
;
319 DPRINT("Bits per pel: %u\n", pdc
->rosdc
.bitsPerPixel
);
321 pdc
->flGraphicsCaps
= PrimarySurface
.devinfo
.flGraphicsCaps
;
322 pdc
->flGraphicsCaps2
= PrimarySurface
.devinfo
.flGraphicsCaps2
;
324 pdc
->dclevel
.hpal
= NtGdiGetStockObject(DEFAULT_PALETTE
);
326 pdcattr
->jROP2
= R2_COPYPEN
;
328 pdc
->erclWindow
.top
= pdc
->erclWindow
.left
= 0;
329 pdc
->erclWindow
.right
= pdc
->ppdev
->gdiinfo
.ulHorzRes
;
330 pdc
->erclWindow
.bottom
= pdc
->ppdev
->gdiinfo
.ulVertRes
;
331 pdc
->dclevel
.flPath
&= ~DCPATH_CLOCKWISE
; // Default is CCW.
333 pdcattr
->iCS_CP
= ftGdiGetTextCharsetInfo(pdc
,NULL
,0);
335 hVisRgn
= NtGdiCreateRectRgn(0, 0, pdc
->ppdev
->gdiinfo
.ulHorzRes
,
336 pdc
->ppdev
->gdiinfo
.ulVertRes
);
340 pdc
->pSurfInfo
= NULL
;
341 // pdc->dclevel.pSurface =
344 /* Initialize the DC state */
345 IntGdiSetTextColor(hdc
, RGB(0, 0, 0));
346 IntGdiSetBkColor(hdc
, RGB(255, 255, 255));
351 The CreateIC function creates an information context for the specified device.
352 The information context provides a fast way to get information about the
353 device without creating a device context (DC). However, GDI drawing functions
354 cannot accept a handle to an information context.
356 pdc
->dctype
= DC_TYPE_INFO
;
358 // DC_vSelectSurface(pdc, NULL);
359 pdcattr
->crBackgroundClr
= pdcattr
->ulBackgroundClr
= RGB(255, 255, 255);
360 pdcattr
->crForegroundClr
= RGB(0, 0, 0);
367 GdiSelectVisRgn(hdc
, hVisRgn
);
368 GreDeleteObject(hVisRgn
);
371 IntGdiSetTextAlign(hdc
, TA_TOP
);
372 IntGdiSetBkMode(hdc
, OPAQUE
);
380 PUNICODE_STRING Device
,
382 PUNICODE_STRING pustrLogAddr
,
389 UNICODE_STRING SafeDevice
;
390 DEVMODEW SafeInitData
;
393 NTSTATUS Status
= STATUS_SUCCESS
;
395 if (!Device
) return UserGetDesktopDC(iType
,FALSE
,TRUE
);
403 ProbeForWrite(pUMdhpdev
, sizeof(PVOID
), 1);
405 ProbeForRead(InitData
, sizeof(DEVMODEW
), 1);
406 RtlCopyMemory(&SafeInitData
, InitData
, sizeof(DEVMODEW
));
408 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
410 Status
= _SEH2_GetExceptionCode();
414 if (!NT_SUCCESS(Status
))
416 SetLastNtError(Status
);
419 /* FIXME - InitData can have some more bytes! */
424 Status
= IntSafeCopyUnicodeString(&SafeDevice
, Device
);
425 if (!NT_SUCCESS(Status
))
427 SetLastNtError(Status
);
432 Ret
= IntGdiCreateDC(Device
? &SafeDevice
: NULL
,
434 pUMdhpdev
? &Dhpdev
: NULL
,
435 InitData
? &SafeInitData
: NULL
,
436 (BOOL
) iType
); // FALSE 0 DCW, TRUE 1 ICW
439 if (pUMdhpdev
) pUMdhpdev
= Dhpdev
;
445 IntGdiCreateDisplayDC(HDEV hDev
, ULONG DcType
, BOOL EmptyDC
)
448 UNICODE_STRING DriverName
;
449 RtlInitUnicodeString(&DriverName
, L
"DISPLAY");
451 if (DcType
!= DC_TYPE_MEMORY
)
452 hDC
= IntGdiCreateDC(&DriverName
, NULL
, NULL
, NULL
, (DcType
== DC_TYPE_INFO
));
454 hDC
= NtGdiCreateCompatibleDC(NULL
); // OH~ Yuck! I think I taste vomit in my mouth!
456 // There is room to grow here~
460 // If NULL, first time through! Build the default (was window) dc!
461 // Setup clean DC state for the system.
463 if (hDC
&& !defaultDCstate
) // Ultra HAX! Dedicated to GvG!
464 { // This is a cheesy way to do this.
465 PDC dc
= DC_LockDc(hDC
);
467 defaultDCstate
= ExAllocatePoolWithTag(PagedPool
, sizeof(DC
), TAG_DC
);
473 RtlZeroMemory(defaultDCstate
, sizeof(DC
));
474 defaultDCstate
->pdcattr
= &defaultDCstate
->dcattr
;
475 hsurf
= (HSURF
)PrimarySurface
.pSurface
; // HAX²
476 defaultDCstate
->dclevel
.pSurface
= SURFACE_ShareLockSurface(hsurf
);
477 DC_vCopyState(dc
, defaultDCstate
);
485 IntGdiDeleteDC(HDC hDC
, BOOL Force
)
487 PDC DCToDelete
= DC_LockDc(hDC
);
489 if (DCToDelete
== NULL
)
491 SetLastWin32Error(ERROR_INVALID_HANDLE
);
497 if (DCToDelete
->fs
& DC_FLAG_PERMANENT
)
499 DPRINT1("No! You Naughty Application!\n");
500 DC_UnlockDc(DCToDelete
);
501 return UserReleaseDC(NULL
, hDC
, FALSE
);
505 /* First delete all saved DCs */
506 while (DCToDelete
->dclevel
.lSaveDepth
> 1)
511 savedHDC
= DCToDelete
->hdcNext
;
512 savedDC
= DC_LockDc(savedHDC
);
517 DCToDelete
->hdcNext
= savedDC
->hdcNext
;
518 DCToDelete
->dclevel
.lSaveDepth
--;
519 DC_UnlockDc(savedDC
);
520 IntGdiDeleteDC(savedHDC
, Force
);
523 /* Free GDI resources allocated to this DC */
524 if (!(DCToDelete
->dclevel
.flPath
& DCPATH_SAVESTATE
))
527 NtGdiSelectPen (DCHandle, STOCK_BLACK_PEN);
528 NtGdiSelectBrush (DCHandle, STOCK_WHITE_BRUSH);
529 NtGdiSelectFont (DCHandle, STOCK_SYSTEM_FONT);
530 DC_LockDC (DCHandle); NtGdiSelectXxx does not recognize stock objects yet */
532 if (DCToDelete
->rosdc
.hClipRgn
)
534 GreDeleteObject(DCToDelete
->rosdc
.hClipRgn
);
536 if (DCToDelete
->rosdc
.hVisRgn
)
538 GreDeleteObject(DCToDelete
->rosdc
.hVisRgn
);
540 if (NULL
!= DCToDelete
->rosdc
.CombinedClip
)
542 IntEngDeleteClipRegion(DCToDelete
->rosdc
.CombinedClip
);
544 if (DCToDelete
->rosdc
.hGCClipRgn
)
546 GreDeleteObject(DCToDelete
->rosdc
.hGCClipRgn
);
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);
601 NtGdiCreateCompatibleDC(HDC hDC
)
604 PDC_ATTR pdcattrNew
, pdcattrOld
;
605 HDC hdcNew
, DisplayDC
= NULL
;
607 UNICODE_STRING DriverName
;
613 RtlInitUnicodeString(&DriverName
, L
"DISPLAY");
614 DisplayDC
= IntGdiCreateDC(&DriverName
, NULL
, NULL
, NULL
, TRUE
);
615 if (NULL
== DisplayDC
)
617 DPRINT1("Failed to create DisplayDC\n");
623 /* Allocate a new DC based on the original DC's device */
624 pdcOld
= DC_LockDc(hDC
);
627 if (NULL
!= DisplayDC
)
629 NtGdiDeleteObjectApp(DisplayDC
);
631 DPRINT1("Failed to lock hDC\n");
634 pdcNew
= DC_AllocDC(&pdcOld
->rosdc
.DriverName
);
637 DPRINT1("Failed to create pdcNew\n");
641 NtGdiDeleteObjectApp(DisplayDC
);
645 hdcNew
= pdcNew
->BaseObject
.hHmgr
;
647 pdcattrOld
= pdcOld
->pdcattr
;
648 pdcattrNew
= pdcNew
->pdcattr
;
650 /* Copy information from original DC to new DC */
651 pdcNew
->dclevel
.hdcSave
= hdcNew
;
653 pdcNew
->dhpdev
= pdcOld
->dhpdev
;
655 pdcNew
->rosdc
.bitsPerPixel
= pdcOld
->rosdc
.bitsPerPixel
;
657 /* DriverName is copied in the AllocDC routine */
658 pdcattrNew
->ptlWindowOrg
= pdcattrOld
->ptlWindowOrg
;
659 pdcattrNew
->szlWindowExt
= pdcattrOld
->szlWindowExt
;
660 pdcattrNew
->ptlViewportOrg
= pdcattrOld
->ptlViewportOrg
;
661 pdcattrNew
->szlViewportExt
= pdcattrOld
->szlViewportExt
;
663 pdcNew
->dctype
= DC_TYPE_MEMORY
; // Always!
664 hsurf
= NtGdiGetStockObject(DEFAULT_BITMAP
);
665 pdcNew
->dclevel
.pSurface
= SURFACE_ShareLockSurface(hsurf
);
666 pdcNew
->ppdev
= pdcOld
->ppdev
;
667 pdcNew
->dclevel
.hpal
= pdcOld
->dclevel
.hpal
;
669 pdcattrNew
->lTextAlign
= pdcattrOld
->lTextAlign
;
670 pdcattrNew
->lBkMode
= pdcattrOld
->lBkMode
;
671 pdcattrNew
->jBkMode
= pdcattrOld
->jBkMode
;
672 pdcattrNew
->jROP2
= pdcattrOld
->jROP2
;
673 pdcattrNew
->dwLayout
= pdcattrOld
->dwLayout
;
674 if (pdcattrOld
->dwLayout
& LAYOUT_ORIENTATIONMASK
) Layout
= pdcattrOld
->dwLayout
;
675 pdcNew
->dclevel
.flPath
= pdcOld
->dclevel
.flPath
;
676 pdcattrNew
->ulDirty_
= pdcattrOld
->ulDirty_
;
677 pdcattrNew
->iCS_CP
= pdcattrOld
->iCS_CP
;
679 pdcNew
->erclWindow
.left
= pdcNew
->erclWindow
.top
= 0;
680 pdcNew
->erclWindow
.right
= pdcNew
->erclWindow
.bottom
= 1;
684 if (NULL
!= DisplayDC
)
686 NtGdiDeleteObjectApp(DisplayDC
);
689 hVisRgn
= NtGdiCreateRectRgn(0, 0, 1, 1);
692 GdiSelectVisRgn(hdcNew
, hVisRgn
);
693 GreDeleteObject(hVisRgn
);
695 if (Layout
) NtGdiSetLayout(hdcNew
, -1, Layout
);
704 NtGdiDeleteObjectApp(HANDLE DCHandle
)
706 /* Complete all pending operations */
707 NtGdiFlushUserBatch();
709 if (GDI_HANDLE_IS_STOCKOBJ(DCHandle
)) return TRUE
;
711 if (GDI_HANDLE_GET_TYPE(DCHandle
) != GDI_OBJECT_TYPE_DC
)
712 return GreDeleteObject((HGDIOBJ
) DCHandle
);
714 if (IsObjectDead((HGDIOBJ
)DCHandle
)) return TRUE
;
716 if (!GDIOBJ_OwnedByCurrentProcess(DCHandle
))
718 SetLastWin32Error(ERROR_INVALID_HANDLE
);
722 return IntGdiDeleteDC(DCHandle
, FALSE
);
727 NewNtGdiDeleteObjectApp(HANDLE DCHandle
)
731 if (GDI_HANDLE_IS_STOCKOBJ(DCHandle
)) return TRUE
;
733 ObjType
= GDI_HANDLE_GET_TYPE(DCHandle
) >> GDI_ENTRY_UPPER_SHIFT
;
735 if (GreGetObjectOwner( DCHandle
, ObjType
))
739 case GDIObjType_DC_TYPE
:
740 return IntGdiDeleteDC(DCHandle
, FALSE
);
742 case GDIObjType_RGN_TYPE
:
743 case GDIObjType_SURF_TYPE
:
744 case GDIObjType_PAL_TYPE
:
745 case GDIObjType_LFONT_TYPE
:
746 case GDIObjType_BRUSH_TYPE
:
747 return GreDeleteObject((HGDIOBJ
) DCHandle
);
753 return (DCHandle
!= NULL
);