Get rid of the DCs XlateBrush and XlatePen. The resulting code isn't any better yet...
[reactos.git] / reactos / subsystems / win32 / win32k / objects / dclife.c
1 /*
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)
7 */
8
9 #include <w32k.h>
10 #include <bugcodes.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 /** Internal functions ********************************************************/
16
17 HDC FASTCALL
18 DC_AllocDC(PUNICODE_STRING Driver)
19 {
20 PDC NewDC;
21 PDC_ATTR pdcattr;
22 HDC hDC;
23 PWSTR Buf = NULL;
24 XFORM xformTemplate;
25 PBRUSH pbrush;
26
27 if (Driver != NULL)
28 {
29 Buf = ExAllocatePoolWithTag(PagedPool, Driver->MaximumLength, TAG_DC);
30 if (!Buf)
31 {
32 DPRINT1("ExAllocatePoolWithTag failed\n");
33 return NULL;
34 }
35 RtlCopyMemory(Buf, Driver->Buffer, Driver->MaximumLength);
36 }
37
38 NewDC = (PDC)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_DC);
39 if (!NewDC)
40 {
41 if (Buf)
42 {
43 ExFreePoolWithTag(Buf, TAG_DC);
44 }
45 DPRINT1("GDIOBJ_AllocObjWithHandle failed\n");
46 return NULL;
47 }
48
49 hDC = NewDC->BaseObject.hHmgr;
50
51 NewDC->pdcattr = &NewDC->dcattr;
52 DC_AllocateDcAttr(hDC);
53
54 if (Driver != NULL)
55 {
56 RtlCopyMemory(&NewDC->rosdc.DriverName, Driver, sizeof(UNICODE_STRING));
57 NewDC->rosdc.DriverName.Buffer = Buf;
58 }
59 pdcattr = NewDC->pdcattr;
60
61 // FIXME: no floating point in the kernel!
62 xformTemplate.eM11 = 1.0f;
63 xformTemplate.eM12 = 0.0f;
64 xformTemplate.eM21 = 0.0f;
65 xformTemplate.eM22 = 1.0f;
66 xformTemplate.eDx = 0.0f;
67 xformTemplate.eDy = 0.0f;
68 XForm2MatrixS(&NewDC->dclevel.mxWorldToDevice, &xformTemplate);
69 XForm2MatrixS(&NewDC->dclevel.mxDeviceToWorld, &xformTemplate);
70 XForm2MatrixS(&NewDC->dclevel.mxWorldToPage, &xformTemplate);
71
72 // Setup syncing bits for the dcattr data packets.
73 pdcattr->flXform = DEVICE_TO_PAGE_INVALID;
74
75 pdcattr->ulDirty_ = 0; // Server side
76
77 pdcattr->iMapMode = MM_TEXT;
78 pdcattr->iGraphicsMode = GM_COMPATIBLE;
79 pdcattr->jFillMode = ALTERNATE;
80
81 pdcattr->szlWindowExt.cx = 1; // Float to Int,,, WRONG!
82 pdcattr->szlWindowExt.cy = 1;
83 pdcattr->szlViewportExt.cx = 1;
84 pdcattr->szlViewportExt.cy = 1;
85
86 pdcattr->crForegroundClr = 0;
87 pdcattr->ulForegroundClr = 0;
88
89 pdcattr->ulBackgroundClr = 0xffffff;
90 pdcattr->crBackgroundClr = 0xffffff;
91
92 pdcattr->ulPenClr = RGB(0, 0, 0);
93 pdcattr->crPenClr = RGB(0, 0, 0);
94
95 pdcattr->ulBrushClr = RGB(255, 255, 255); // Do this way too.
96 pdcattr->crBrushClr = RGB(255, 255, 255);
97
98 //// This fixes the default brush and pen settings. See DC_InitDC.
99
100 /* Create the default fill brush */
101 pdcattr->hbrush = NtGdiGetStockObject(WHITE_BRUSH);
102 NewDC->dclevel.pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush);
103 EBRUSHOBJ_vInit(&NewDC->eboFill, NewDC->dclevel.pbrFill, NULL);
104
105 /* Create the default pen / line brush */
106 pdcattr->hpen = NtGdiGetStockObject(BLACK_PEN);
107 NewDC->dclevel.pbrLine = PEN_ShareLockPen(pdcattr->hpen);
108 EBRUSHOBJ_vInit(&NewDC->eboLine, NewDC->dclevel.pbrLine, NULL);
109
110 /* Create the default text brush */
111 pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(BLACK_BRUSH));
112 EBRUSHOBJ_vInit(&NewDC->eboText, pbrush, NULL);
113 pdcattr->ulDirty_ |= DIRTY_TEXT;
114
115 /* Create the default background brush */
116 pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(WHITE_BRUSH));
117 EBRUSHOBJ_vInit(&NewDC->eboBackground, pbrush, NULL);
118
119 pdcattr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT);
120 TextIntRealizeFont(pdcattr->hlfntNew,NULL);
121
122 NewDC->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE);
123 NewDC->dclevel.laPath.eMiterLimit = 10.0;
124
125 NewDC->dclevel.lSaveDepth = 1;
126
127 return NewDC;
128 }
129
130 VOID FASTCALL
131 DC_FreeDC(HDC DCToFree)
132 {
133 DC_FreeDcAttr(DCToFree);
134 if (!IsObjectDead(DCToFree))
135 {
136 if (!GDIOBJ_FreeObjByHandle(DCToFree, GDI_OBJECT_TYPE_DC))
137 {
138 DPRINT1("DC_FreeDC failed\n");
139 }
140 }
141 else
142 {
143 DPRINT1("Attempted to Delete 0x%x currently being destroyed!!!\n",DCToFree);
144 }
145 }
146
147 BOOL INTERNAL_CALL
148 DC_Cleanup(PVOID ObjectBody)
149 {
150 PDC pDC = (PDC)ObjectBody;
151
152 /* Free driver name (HACK) */
153 if (pDC->rosdc.DriverName.Buffer)
154 ExFreePoolWithTag(pDC->rosdc.DriverName.Buffer, TAG_DC);
155
156 /* Clean up selected objects */
157 DC_vSelectSurface(pDC, NULL);
158 DC_vSelectFillBrush(pDC, NULL);
159 DC_vSelectLineBrush(pDC, NULL);
160
161 /* Dereference default brushes */
162 BRUSH_ShareUnlockBrush(pDC->eboText.pbrush);
163 BRUSH_ShareUnlockBrush(pDC->eboBackground.pbrush);
164
165 return TRUE;
166 }
167
168 BOOL
169 FASTCALL
170 DC_SetOwnership(HDC hDC, PEPROCESS Owner)
171 {
172 PDC pDC;
173
174 if (!GDIOBJ_SetOwnership(hDC, Owner)) return FALSE;
175 pDC = DC_LockDc(hDC);
176 if (pDC)
177 {
178 if (pDC->rosdc.hClipRgn)
179 {
180 if (!GDIOBJ_SetOwnership(pDC->rosdc.hClipRgn, Owner)) return FALSE;
181 }
182 if (pDC->rosdc.hVisRgn)
183 {
184 if (!GDIOBJ_SetOwnership(pDC->rosdc.hVisRgn, Owner)) return FALSE;
185 }
186 if (pDC->rosdc.hGCClipRgn)
187 {
188 if (!GDIOBJ_SetOwnership(pDC->rosdc.hGCClipRgn, Owner)) return FALSE;
189 }
190 if (pDC->dclevel.hPath)
191 {
192 if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) return FALSE;
193 }
194 DC_UnlockDc(pDC);
195 }
196
197 return TRUE;
198 }
199
200
201 HDC FASTCALL
202 IntGdiCreateDC(
203 PUNICODE_STRING Driver,
204 PUNICODE_STRING Device,
205 PVOID pUMdhpdev,
206 CONST PDEVMODEW InitData,
207 BOOL CreateAsIC)
208 {
209 HDC hdc;
210 PDC pdc;
211 PDC_ATTR pdcattr;
212 HRGN hVisRgn;
213 UNICODE_STRING StdDriver;
214 BOOL calledFromUser;
215 HSURF hsurf;
216
217 RtlInitUnicodeString(&StdDriver, L"DISPLAY");
218
219 DPRINT("DriverName: %wZ, DeviceName: %wZ\n", Driver, Device);
220
221 if (NULL == Driver || 0 == RtlCompareUnicodeString(Driver, &StdDriver, TRUE))
222 {
223 if (CreateAsIC)
224 {
225 if (! IntPrepareDriverIfNeeded())
226 {
227 /* Here, we have two possibilities:
228 * a) return NULL, and hope that the caller
229 * won't call us in a loop
230 * b) bugcheck, but caller is unable to
231 * react on the problem
232 */
233 /*DPRINT1("Unable to prepare graphics driver, returning NULL ic\n");
234 return NULL;*/
235 KeBugCheck(VIDEO_DRIVER_INIT_FAILURE);
236 }
237 }
238 else
239 {
240 calledFromUser = UserIsEntered();
241 if (!calledFromUser)
242 {
243 UserEnterExclusive();
244 }
245
246 if (! co_IntGraphicsCheck(TRUE))
247 {
248 if (!calledFromUser)
249 {
250 UserLeave();
251 }
252 DPRINT1("Unable to initialize graphics, returning NULL dc\n");
253 return NULL;
254 }
255
256 if (!calledFromUser)
257 {
258 UserLeave();
259 }
260
261 }
262 }
263
264 /* Check for existing DC object */
265 if ((hdc = DC_FindOpenDC(Driver)) != NULL)
266 {
267 hdc = NtGdiCreateCompatibleDC(hdc);
268 if (!hdc)
269 DPRINT1("NtGdiCreateCompatibleDC() failed\n");
270 return hdc;
271 }
272
273 /* Allocate a DC object */
274 pdc = DC_AllocDC(Driver);
275 if (pdc == NULL)
276 {
277 DPRINT1("DC_AllocDC() failed\n");
278 return NULL;
279 }
280 hdc = pdc->BaseObject.hHmgr;
281 pdcattr = pdc->pdcattr;
282
283 pdc->dctype = DC_TYPE_DIRECT;
284
285 pdc->dhpdev = PrimarySurface.hPDev;
286 if (pUMdhpdev) pUMdhpdev = pdc->dhpdev; // set DHPDEV for device.
287 pdc->ppdev = (PVOID)&PrimarySurface;
288 hsurf = (HBITMAP)PrimarySurface.pSurface; // <- what kind of haxx0ry is that?
289 pdc->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
290
291 // ATM we only have one display.
292 pdcattr->ulDirty_ |= DC_PRIMARY_DISPLAY;
293
294 pdc->rosdc.bitsPerPixel = pdc->ppdev->GDIInfo.cBitsPixel *
295 pdc->ppdev->GDIInfo.cPlanes;
296 DPRINT("Bits per pel: %u\n", pdc->rosdc.bitsPerPixel);
297
298 pdc->flGraphicsCaps = PrimarySurface.DevInfo.flGraphicsCaps;
299 pdc->flGraphicsCaps2 = PrimarySurface.DevInfo.flGraphicsCaps2;
300
301 pdc->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE);
302
303 pdcattr->jROP2 = R2_COPYPEN;
304
305 pdc->erclWindow.top = pdc->erclWindow.left = 0;
306 pdc->erclWindow.right = pdc->ppdev->GDIInfo.ulHorzRes;
307 pdc->erclWindow.bottom = pdc->ppdev->GDIInfo.ulVertRes;
308 pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE; // Default is CCW.
309
310 pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
311
312 hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->ppdev->GDIInfo.ulHorzRes,
313 pdc->ppdev->GDIInfo.ulVertRes);
314
315 if (!CreateAsIC)
316 {
317 pdc->pSurfInfo = NULL;
318 // pdc->dclevel.pSurface =
319 DC_UnlockDc(pdc);
320
321 /* Initialize the DC state */
322 DC_InitDC(hdc);
323 IntGdiSetTextColor(hdc, RGB(0, 0, 0));
324 IntGdiSetBkColor(hdc, RGB(255, 255, 255));
325 }
326 else
327 {
328 /* From MSDN2:
329 The CreateIC function creates an information context for the specified device.
330 The information context provides a fast way to get information about the
331 device without creating a device context (DC). However, GDI drawing functions
332 cannot accept a handle to an information context.
333 */
334 pdc->dctype = DC_TYPE_INFO;
335 // pdc->pSurfInfo =
336 DC_vSelectSurface(pdc, NULL);
337 pdcattr->crBackgroundClr = pdcattr->ulBackgroundClr = RGB(255, 255, 255);
338 pdcattr->crForegroundClr = RGB(0, 0, 0);
339 DC_UnlockDc(pdc);
340 }
341
342 if (hVisRgn)
343 {
344 GdiSelectVisRgn(hdc, hVisRgn);
345 GreDeleteObject(hVisRgn);
346 }
347
348 IntGdiSetTextAlign(hdc, TA_TOP);
349 IntGdiSetBkMode(hdc, OPAQUE);
350
351 return hdc;
352 }
353
354
355 HDC APIENTRY
356 NtGdiOpenDCW(
357 PUNICODE_STRING Device,
358 DEVMODEW *InitData,
359 PUNICODE_STRING pustrLogAddr,
360 ULONG iType,
361 BOOL bDisplay,
362 HANDLE hspool,
363 VOID *pDriverInfo2,
364 VOID *pUMdhpdev)
365 {
366 UNICODE_STRING SafeDevice;
367 DEVMODEW SafeInitData;
368 PVOID Dhpdev;
369 HDC Ret;
370 NTSTATUS Status = STATUS_SUCCESS;
371
372 if (InitData)
373 {
374 _SEH2_TRY
375 {
376 if (pUMdhpdev)
377 {
378 ProbeForWrite(pUMdhpdev, sizeof(PVOID), 1);
379 }
380 ProbeForRead(InitData, sizeof(DEVMODEW), 1);
381 RtlCopyMemory(&SafeInitData, InitData, sizeof(DEVMODEW));
382 }
383 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
384 {
385 Status = _SEH2_GetExceptionCode();
386 }
387 _SEH2_END;
388
389 if (!NT_SUCCESS(Status))
390 {
391 SetLastNtError(Status);
392 return NULL;
393 }
394 /* FIXME - InitData can have some more bytes! */
395 }
396
397 if (Device)
398 {
399 Status = IntSafeCopyUnicodeString(&SafeDevice, Device);
400 if (!NT_SUCCESS(Status))
401 {
402 SetLastNtError(Status);
403 return NULL;
404 }
405 }
406
407 Ret = IntGdiCreateDC(Device ? &SafeDevice : NULL,
408 NULL,
409 pUMdhpdev ? &Dhpdev : NULL,
410 InitData ? &SafeInitData : NULL,
411 (BOOL) iType); // FALSE 0 DCW, TRUE 1 ICW
412
413 // FIXME!!!!
414 if (pUMdhpdev) pUMdhpdev = Dhpdev;
415
416 return Ret;
417 }
418
419 HDC FASTCALL
420 IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
421 {
422 HDC hDC;
423 UNICODE_STRING DriverName;
424 RtlInitUnicodeString(&DriverName, L"DISPLAY");
425
426 if (DcType != DC_TYPE_MEMORY)
427 hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, (DcType == DC_TYPE_INFO));
428 else
429 hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth!
430 //
431 // There is room to grow here~
432 //
433
434 //
435 // If NULL, first time through! Build the default (was window) dc!
436 // Setup clean DC state for the system.
437 //
438 if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG!
439 { // This is a cheesy way to do this.
440 PDC dc = DC_LockDc(hDC);
441 defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
442 if (!defaultDCstate)
443 {
444 DC_UnlockDc(dc);
445 return NULL;
446 }
447 RtlZeroMemory(defaultDCstate, sizeof(DC));
448 defaultDCstate->pdcattr = &defaultDCstate->dcattr;
449 DC_vCopyState(dc, defaultDCstate);
450 DC_UnlockDc(dc);
451 }
452 return hDC;
453 }
454
455 BOOL
456 FASTCALL
457 IntGdiDeleteDC(HDC hDC, BOOL Force)
458 {
459 PDC DCToDelete = DC_LockDc(hDC);
460
461 if (DCToDelete == NULL)
462 {
463 SetLastWin32Error(ERROR_INVALID_HANDLE);
464 return FALSE;
465 }
466
467 if (!Force)
468 {
469 if (DCToDelete->fs & DC_FLAG_PERMANENT)
470 {
471 DPRINT1("No! You Naughty Application!\n");
472 DC_UnlockDc(DCToDelete);
473 return UserReleaseDC(NULL, hDC, FALSE);
474 }
475 }
476
477 /* First delete all saved DCs */
478 while (DCToDelete->dclevel.lSaveDepth > 1)
479 {
480 PDC savedDC;
481 HDC savedHDC;
482
483 savedHDC = DCToDelete->hdcNext;
484 savedDC = DC_LockDc(savedHDC);
485 if (savedDC == NULL)
486 {
487 break;
488 }
489 DCToDelete->hdcNext = savedDC->hdcNext;
490 DCToDelete->dclevel.lSaveDepth--;
491 DC_UnlockDc(savedDC);
492 IntGdiDeleteDC(savedHDC, Force);
493 }
494
495 /* Free GDI resources allocated to this DC */
496 if (!(DCToDelete->dclevel.flPath & DCPATH_SAVESTATE))
497 {
498 /*
499 NtGdiSelectPen (DCHandle, STOCK_BLACK_PEN);
500 NtGdiSelectBrush (DCHandle, STOCK_WHITE_BRUSH);
501 NtGdiSelectFont (DCHandle, STOCK_SYSTEM_FONT);
502 DC_LockDC (DCHandle); NtGdiSelectXxx does not recognize stock objects yet */
503 }
504 if (DCToDelete->rosdc.hClipRgn)
505 {
506 GreDeleteObject(DCToDelete->rosdc.hClipRgn);
507 }
508 if (DCToDelete->rosdc.hVisRgn)
509 {
510 GreDeleteObject(DCToDelete->rosdc.hVisRgn);
511 }
512 if (NULL != DCToDelete->rosdc.CombinedClip)
513 {
514 IntEngDeleteClipRegion(DCToDelete->rosdc.CombinedClip);
515 }
516 if (DCToDelete->rosdc.hGCClipRgn)
517 {
518 GreDeleteObject(DCToDelete->rosdc.hGCClipRgn);
519 }
520 PATH_Delete(DCToDelete->dclevel.hPath);
521
522 DC_UnlockDc(DCToDelete);
523 DC_FreeDC(hDC);
524 return TRUE;
525 }
526
527 HDC FASTCALL
528 DC_FindOpenDC(PUNICODE_STRING Driver)
529 {
530 return NULL;
531 }
532
533 /*!
534 * Initialize some common fields in the Device Context structure.
535 */
536 VOID FASTCALL
537 DC_InitDC(HDC DCHandle)
538 {
539 // NtGdiRealizeDefaultPalette(DCHandle);
540
541 //// Removed for now.. See above brush and pen.
542 // NtGdiSelectBrush(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
543 // NtGdiSelectPen(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
544 ////
545 //NtGdiSelectFont(DCHandle, hFont);
546
547 /*
548 {
549 int res;
550 res = CLIPPING_UpdateGCRegion(DCToInit);
551 ASSERT ( res != ERROR );
552 }
553 */
554 }
555
556 /*
557 * @unimplemented
558 */
559 BOOL
560 APIENTRY
561 NtGdiMakeInfoDC(
562 IN HDC hdc,
563 IN BOOL bSet)
564 {
565 UNIMPLEMENTED;
566 return FALSE;
567 }
568
569 HDC APIENTRY
570 NtGdiCreateCompatibleDC(HDC hDC)
571 {
572 PDC pdcNew, pdcOld;
573 PDC_ATTR pdcattrNew, pdcattrOld;
574 HDC hdcNew, DisplayDC = NULL;
575 HRGN hVisRgn;
576 UNICODE_STRING DriverName;
577 DWORD Layout = 0;
578 HSURF hsurf;
579
580 if (hDC == NULL)
581 {
582 RtlInitUnicodeString(&DriverName, L"DISPLAY");
583 DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, TRUE);
584 if (NULL == DisplayDC)
585 {
586 DPRINT1("Failed to create DisplayDC\n");
587 return NULL;
588 }
589 hDC = DisplayDC;
590 }
591
592 /* Allocate a new DC based on the original DC's device */
593 pdcOld = DC_LockDc(hDC);
594 if (NULL == pdcOld)
595 {
596 if (NULL != DisplayDC)
597 {
598 NtGdiDeleteObjectApp(DisplayDC);
599 }
600 DPRINT1("Failed to lock hDC\n");
601 return NULL;
602 }
603 pdcNew = DC_AllocDC(&pdcOld->rosdc.DriverName);
604 if (!pdcNew)
605 {
606 DPRINT1("Failed to create pdcNew\n");
607 DC_UnlockDc(pdcOld);
608 if (DisplayDC)
609 {
610 NtGdiDeleteObjectApp(DisplayDC);
611 }
612 return NULL;
613 }
614 hdcNew = pdcNew->BaseObject.hHmgr;
615
616 pdcattrOld = pdcOld->pdcattr;
617 pdcattrNew = pdcNew->pdcattr;
618
619 /* Copy information from original DC to new DC */
620 pdcNew->dclevel.hdcSave = hdcNew;
621
622 pdcNew->dhpdev = pdcOld->dhpdev;
623
624 pdcNew->rosdc.bitsPerPixel = pdcOld->rosdc.bitsPerPixel;
625
626 /* DriverName is copied in the AllocDC routine */
627 pdcattrNew->ptlWindowOrg = pdcattrOld->ptlWindowOrg;
628 pdcattrNew->szlWindowExt = pdcattrOld->szlWindowExt;
629 pdcattrNew->ptlViewportOrg = pdcattrOld->ptlViewportOrg;
630 pdcattrNew->szlViewportExt = pdcattrOld->szlViewportExt;
631
632 pdcNew->dctype = DC_TYPE_MEMORY; // Always!
633 hsurf = NtGdiGetStockObject(DEFAULT_BITMAP);
634 pdcNew->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
635 pdcNew->ppdev = pdcOld->ppdev;
636 pdcNew->dclevel.hpal = pdcOld->dclevel.hpal;
637
638 pdcattrNew->lTextAlign = pdcattrOld->lTextAlign;
639 pdcattrNew->lBkMode = pdcattrOld->lBkMode;
640 pdcattrNew->jBkMode = pdcattrOld->jBkMode;
641 pdcattrNew->jROP2 = pdcattrOld->jROP2;
642 pdcattrNew->dwLayout = pdcattrOld->dwLayout;
643 if (pdcattrOld->dwLayout & LAYOUT_ORIENTATIONMASK) Layout = pdcattrOld->dwLayout;
644 pdcNew->dclevel.flPath = pdcOld->dclevel.flPath;
645 pdcattrNew->ulDirty_ = pdcattrOld->ulDirty_;
646 pdcattrNew->iCS_CP = pdcattrOld->iCS_CP;
647
648 pdcNew->erclWindow = (RECTL){0, 0, 1, 1};
649
650 DC_UnlockDc(pdcNew);
651 DC_UnlockDc(pdcOld);
652 if (NULL != DisplayDC)
653 {
654 NtGdiDeleteObjectApp(DisplayDC);
655 }
656
657 hVisRgn = NtGdiCreateRectRgn(0, 0, 1, 1);
658 if (hVisRgn)
659 {
660 GdiSelectVisRgn(hdcNew, hVisRgn);
661 GreDeleteObject(hVisRgn);
662 }
663 if (Layout) NtGdiSetLayout(hdcNew, -1, Layout);
664
665 DC_InitDC(hdcNew);
666 return hdcNew;
667 }
668
669
670 BOOL
671 APIENTRY
672 NtGdiDeleteObjectApp(HANDLE DCHandle)
673 {
674 /* Complete all pending operations */
675 NtGdiFlushUserBatch();
676
677 if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
678
679 if (GDI_HANDLE_GET_TYPE(DCHandle) != GDI_OBJECT_TYPE_DC)
680 return GreDeleteObject((HGDIOBJ) DCHandle);
681
682 if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
683
684 if (!GDIOBJ_OwnedByCurrentProcess(DCHandle))
685 {
686 SetLastWin32Error(ERROR_INVALID_HANDLE);
687 return FALSE;
688 }
689
690 return IntGdiDeleteDC(DCHandle, FALSE);
691 }
692
693 BOOL
694 APIENTRY
695 NewNtGdiDeleteObjectApp(HANDLE DCHandle)
696 {
697 GDIOBJTYPE ObjType;
698
699 if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
700
701 ObjType = GDI_HANDLE_GET_TYPE(DCHandle) >> GDI_ENTRY_UPPER_SHIFT;
702
703 if (GreGetObjectOwner( DCHandle, ObjType))
704 {
705 switch(ObjType)
706 {
707 case GDIObjType_DC_TYPE:
708 return IntGdiDeleteDC(DCHandle, FALSE);
709
710 case GDIObjType_RGN_TYPE:
711 case GDIObjType_SURF_TYPE:
712 case GDIObjType_PAL_TYPE:
713 case GDIObjType_LFONT_TYPE:
714 case GDIObjType_BRUSH_TYPE:
715 return GreDeleteObject((HGDIOBJ) DCHandle);
716
717 default:
718 return FALSE;
719 }
720 }
721 return (DCHandle != NULL);
722 }
723