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