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 //FIXME: windows uses 0x0012009f
16 #define DIRTY_DEFAULT DIRTY_CHARSET|DIRTY_BACKGROUND|DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL
18 PSURFACE psurfDefaultBitmap
= NULL
;
19 PBRUSH pbrDefaultBrush
= NULL
;
21 // FIXME: these should go to floatobj.h or something
22 #define FLOATOBJ_0 {0x00000000, 0x00000000}
23 #define FLOATOBJ_1 {0x40000000, 0x00000002}
24 #define FLOATOBJ_16 {0x40000000, 0x00000006}
25 #define FLOATOBJ_1_16 {0x40000000, 0xfffffffe}
27 static const FLOATOBJ gef0
= FLOATOBJ_0
;
28 static const FLOATOBJ gef1
= FLOATOBJ_1
;
29 static const FLOATOBJ gef16
= FLOATOBJ_16
;
31 static const MATRIX gmxWorldToDeviceDefault
=
33 FLOATOBJ_16
, FLOATOBJ_0
,
34 FLOATOBJ_0
, FLOATOBJ_16
,
35 FLOATOBJ_0
, FLOATOBJ_0
,
39 static const MATRIX gmxDeviceToWorldDefault
=
41 FLOATOBJ_1_16
, FLOATOBJ_0
,
42 FLOATOBJ_0
, FLOATOBJ_1_16
,
43 FLOATOBJ_0
, FLOATOBJ_0
,
47 static const MATRIX gmxWorldToPageDefault
=
49 FLOATOBJ_1
, FLOATOBJ_0
,
50 FLOATOBJ_0
, FLOATOBJ_1
,
51 FLOATOBJ_0
, FLOATOBJ_0
,
55 // HACK!! Fix XFORMOBJ then use 1:16 / 16:1
56 #define gmxWorldToDeviceDefault gmxWorldToPageDefault
57 #define gmxDeviceToWorldDefault gmxWorldToPageDefault
59 /** Internal functions ********************************************************/
64 psurfDefaultBitmap
= SURFACE_ShareLockSurface(StockObjects
[DEFAULT_BITMAP
]);
65 if (!psurfDefaultBitmap
)
66 return STATUS_UNSUCCESSFUL
;
68 pbrDefaultBrush
= BRUSH_ShareLockBrush(StockObjects
[BLACK_BRUSH
]);
70 return STATUS_UNSUCCESSFUL
;
72 return STATUS_SUCCESS
;
78 DC_AllocDcWithHandle()
81 pdc
= (PDC
)GDIOBJ_AllocObjWithHandle(GDILoObjType_LO_DC_TYPE
);
83 pdc
->pdcattr
= &pdc
->dcattr
;
94 TextIntRealizeFont(pdc
->pdcattr
->hlfntNew
,NULL
);
95 pdc
->pdcattr
->iCS_CP
= ftGdiGetTextCharsetInfo(pdc
,NULL
,0);
97 /* This should never fail */
98 ASSERT(pdc
->dclevel
.ppal
);
101 // FIXME: too complicated, broken error handling
102 pdc
->rosdc
.hClipRgn
= NULL
;
103 pdc
->rosdc
.hGCClipRgn
= NULL
;
104 hVisRgn
= NtGdiCreateRectRgn(0, 0, pdc
->dclevel
.sizl
.cx
, pdc
->dclevel
.sizl
.cy
);
106 GdiSelectVisRgn(pdc
->BaseObject
.hHmgr
, hVisRgn
);
107 GreDeleteObject(hVisRgn
);
108 ASSERT(pdc
->prgnVis
);
118 if (dctype
== DCTYPE_DIRECT
)
120 /* Lock ppdev exclusively */
121 EngAcquireSemaphore(ppdev
->hsemDevLock
);
124 /* Setup some basic fields */
125 pdc
->dctype
= dctype
;
127 pdc
->dhpdev
= ppdev
->dhpdev
;
128 pdc
->hsem
= ppdev
->hsemDevLock
;
129 pdc
->flGraphicsCaps
= ppdev
->devinfo
.flGraphicsCaps
;
130 pdc
->flGraphicsCaps2
= ppdev
->devinfo
.flGraphicsCaps2
;
131 pdc
->fs
= DC_DIRTY_RAO
;
133 /* Setup dc attribute */
134 pdc
->pdcattr
= &pdc
->dcattr
;
135 pdc
->dcattr
.pvLDC
= NULL
;
136 pdc
->dcattr
.ulDirty_
= DIRTY_DEFAULT
;
137 if (ppdev
== gppdevPrimary
)
138 pdc
->dcattr
.ulDirty_
|= DC_PRIMARY_DISPLAY
;
140 /* Setup the DC size */
141 if (dctype
== DCTYPE_MEMORY
)
143 /* Memory DCs have a 1 x 1 bitmap by default */
144 pdc
->dclevel
.sizl
.cx
= 1;
145 pdc
->dclevel
.sizl
.cy
= 1;
149 /* Other DC's are as big as the related PDEV */
150 pdc
->dclevel
.sizl
.cx
= ppdev
->gdiinfo
.ulHorzRes
;
151 pdc
->dclevel
.sizl
.cy
= ppdev
->gdiinfo
.ulVertRes
;
154 /* Setup Window rect based on DC size */
155 pdc
->erclWindow
.left
= 0;
156 pdc
->erclWindow
.top
= 0;
157 pdc
->erclWindow
.right
= pdc
->dclevel
.sizl
.cx
;
158 pdc
->erclWindow
.bottom
= pdc
->dclevel
.sizl
.cy
;
160 if (dctype
== DCTYPE_DIRECT
)
163 /* Direct DCs get the surface from the PDEV */
164 pdc
->dclevel
.pSurface
= PDEVOBJ_pSurface(ppdev
);
166 /* Maintain a list of DC attached to this device */
167 /* We must sort them so when locking them one after the other we don't risk deadlocks */
168 /* The greatest the first, as in GDIOBJ_LockMultiplObjs */
169 if((ULONG_PTR
)pdc
->dclevel
.pSurface
->hDC
< (ULONG_PTR
)pdc
->BaseObject
.hHmgr
)
171 /* Insert it at the head of the list */
172 pdc
->hdcNext
= pdc
->dclevel
.pSurface
->hDC
;
173 pdc
->dclevel
.pSurface
->hDC
= pdc
->BaseObject
.hHmgr
;
174 pdcTmp
= DC_LockDc(pdc
->hdcNext
);
177 pdcTmp
->hdcPrev
= pdc
->BaseObject
.hHmgr
;
183 HDC hdcTmp
= pdc
->dclevel
.pSurface
->hDC
;
187 while((ULONG_PTR
)hdcTmp
> (ULONG_PTR
)pdc
->BaseObject
.hHmgr
)
189 pdcTmp
= DC_LockDc(hdcTmp
);
191 hdcPrev
= pdcTmp
->hdcPrev
;
192 hdcTmp
= pdcTmp
->hdcNext
;
195 pdc
->hdcPrev
= hdcPrev
;
196 pdc
->hdcNext
= hdcNext
;
198 pdcTmp
= DC_LockDc(hdcPrev
);
199 ASSERT(pdcTmp
) ; /* There should always be a previous */
200 pdcTmp
->hdcNext
= pdc
->BaseObject
.hHmgr
;
201 DC_UnlockDc(pdcTmp
) ;
203 pdcTmp
= DC_LockDc(hdcNext
);
204 if(pdcTmp
) /* Last one is NULL */
206 pdcTmp
->hdcPrev
= pdc
->BaseObject
.hHmgr
;
211 pdc
->erclBounds
.left
= 0x7fffffff;
212 pdc
->erclBounds
.top
= 0x7fffffff;
213 pdc
->erclBounds
.right
= 0x80000000;
214 pdc
->erclBounds
.bottom
= 0x80000000;
215 pdc
->erclBoundsApp
.left
= 0xffffffff;
216 pdc
->erclBoundsApp
.top
= 0xfffffffc;
217 pdc
->erclBoundsApp
.right
= 0x00007ffc; // FIXME
218 pdc
->erclBoundsApp
.bottom
= 0x00000333; // FIXME
219 pdc
->erclClip
= pdc
->erclBounds
;
222 pdc
->fs
|= DC_SYNCHRONIZEACCESS
| DC_ACCUM_APP
| DC_PERMANANT
| DC_DISPLAY
;
226 /* Non-direct DCs don't have a surface by default */
227 pdc
->dclevel
.pSurface
= NULL
;
229 // FIXME: HACK, because our code expects a surface
230 pdc
->dclevel
.pSurface
= SURFACE_ShareLockSurface(StockObjects
[DEFAULT_BITMAP
]);
232 pdc
->erclBounds
.left
= 0;
233 pdc
->erclBounds
.top
= 0;
234 pdc
->erclBounds
.right
= 0;
235 pdc
->erclBounds
.bottom
= 0;
236 pdc
->erclBoundsApp
= pdc
->erclBounds
;
237 pdc
->erclClip
= pdc
->erclWindow
;
241 // pdc->dcattr.VisRectRegion:
243 /* Setup coordinate transformation data */
244 pdc
->dclevel
.mxWorldToDevice
= gmxWorldToDeviceDefault
;
245 pdc
->dclevel
.mxDeviceToWorld
= gmxDeviceToWorldDefault
;
246 pdc
->dclevel
.mxWorldToPage
= gmxWorldToPageDefault
;
247 pdc
->dclevel
.efM11PtoD
= gef16
;
248 pdc
->dclevel
.efM22PtoD
= gef16
;
249 pdc
->dclevel
.efDxPtoD
= gef0
;
250 pdc
->dclevel
.efDyPtoD
= gef0
;
251 pdc
->dclevel
.efM11_TWIPS
= gef0
;
252 pdc
->dclevel
.efM22_TWIPS
= gef0
;
253 pdc
->dclevel
.efPr11
= gef0
;
254 pdc
->dclevel
.efPr22
= gef0
;
255 pdc
->dcattr
.mxWorldToDevice
= pdc
->dclevel
.mxWorldToDevice
;
256 pdc
->dcattr
.mxDeviceToWorld
= pdc
->dclevel
.mxDeviceToWorld
;
257 pdc
->dcattr
.mxWorldToPage
= pdc
->dclevel
.mxWorldToPage
;
258 pdc
->dcattr
.efM11PtoD
= pdc
->dclevel
.efM11PtoD
;
259 pdc
->dcattr
.efM22PtoD
= pdc
->dclevel
.efM22PtoD
;
260 pdc
->dcattr
.efDxPtoD
= pdc
->dclevel
.efDxPtoD
;
261 pdc
->dcattr
.efDyPtoD
= pdc
->dclevel
.efDyPtoD
;
262 pdc
->dcattr
.iMapMode
= MM_TEXT
;
263 pdc
->dcattr
.dwLayout
= 0;
264 pdc
->dcattr
.flXform
= PAGE_TO_DEVICE_SCALE_IDENTITY
|
265 PAGE_TO_DEVICE_IDENTITY
|
266 WORLD_TO_PAGE_IDENTITY
;
268 /* Setup more coordinates */
269 pdc
->ptlDCOrig
.x
= 0;
270 pdc
->ptlDCOrig
.y
= 0;
271 pdc
->dcattr
.lWindowOrgx
= 0;
272 pdc
->dcattr
.ptlWindowOrg
.x
= 0;
273 pdc
->dcattr
.ptlWindowOrg
.y
= 0;
274 pdc
->dcattr
.szlWindowExt
.cx
= 1;
275 pdc
->dcattr
.szlWindowExt
.cy
= 1;
276 pdc
->dcattr
.ptlViewportOrg
.x
= 0;
277 pdc
->dcattr
.ptlViewportOrg
.y
= 0;
278 pdc
->dcattr
.szlViewportExt
.cx
= 1;
279 pdc
->dcattr
.szlViewportExt
.cy
= 1;
280 pdc
->dcattr
.szlVirtualDevicePixel
.cx
= 0;
281 pdc
->dcattr
.szlVirtualDevicePixel
.cy
= 0;
282 pdc
->dcattr
.szlVirtualDeviceMm
.cx
= 0;
283 pdc
->dcattr
.szlVirtualDeviceMm
.cy
= 0;
284 pdc
->dcattr
.szlVirtualDeviceSize
.cx
= 0;
285 pdc
->dcattr
.szlVirtualDeviceSize
.cy
= 0;
289 pdc
->prgnVis
= NULL
; // FIXME
293 pdc
->dclevel
.hpal
= StockObjects
[DEFAULT_PALETTE
];
294 pdc
->dclevel
.ppal
= PALETTE_ShareLockPalette(pdc
->dclevel
.hpal
);
297 pdc
->dclevel
.hPath
= NULL
;
298 pdc
->dclevel
.flPath
= 0;
299 // pdc->dclevel.lapath:
302 pdc
->dcattr
.crBackgroundClr
= RGB(0xff, 0xff, 0xff);
303 pdc
->dcattr
.ulBackgroundClr
= RGB(0xff, 0xff, 0xff);
304 pdc
->dcattr
.crForegroundClr
= RGB(0, 0, 0);
305 pdc
->dcattr
.ulForegroundClr
= RGB(0, 0, 0);
306 pdc
->dcattr
.crBrushClr
= RGB(0xff, 0xff, 0xff);
307 pdc
->dcattr
.ulBrushClr
= RGB(0xff, 0xff, 0xff);
308 pdc
->dcattr
.crPenClr
= RGB(0, 0, 0);
309 pdc
->dcattr
.ulPenClr
= RGB(0, 0, 0);
311 /* Select the default fill and line brush */
312 pdc
->dcattr
.hbrush
= StockObjects
[WHITE_BRUSH
];
313 pdc
->dcattr
.hpen
= StockObjects
[BLACK_PEN
];
314 pdc
->dclevel
.pbrFill
= BRUSH_ShareLockBrush(pdc
->pdcattr
->hbrush
);
315 pdc
->dclevel
.pbrLine
= PEN_ShareLockPen(pdc
->pdcattr
->hpen
);
316 pdc
->dclevel
.ptlBrushOrigin
.x
= 0;
317 pdc
->dclevel
.ptlBrushOrigin
.y
= 0;
318 pdc
->dcattr
.ptlBrushOrigin
= pdc
->dclevel
.ptlBrushOrigin
;
320 /* Initialize EBRUSHOBJs */
321 EBRUSHOBJ_vInit(&pdc
->eboFill
, pdc
->dclevel
.pbrFill
, pdc
);
322 EBRUSHOBJ_vInit(&pdc
->eboLine
, pdc
->dclevel
.pbrLine
, pdc
);
323 EBRUSHOBJ_vInit(&pdc
->eboText
, pbrDefaultBrush
, pdc
);
324 EBRUSHOBJ_vInit(&pdc
->eboBackground
, pbrDefaultBrush
, pdc
);
326 /* Setup fill data */
327 pdc
->dcattr
.jROP2
= R2_COPYPEN
;
328 pdc
->dcattr
.jBkMode
= 2;
329 pdc
->dcattr
.lBkMode
= 2;
330 pdc
->dcattr
.jFillMode
= ALTERNATE
;
331 pdc
->dcattr
.lFillMode
= 1;
332 pdc
->dcattr
.jStretchBltMode
= 1;
333 pdc
->dcattr
.lStretchBltMode
= 1;
334 pdc
->ptlFillOrigin
.x
= 0;
335 pdc
->ptlFillOrigin
.y
= 0;
337 /* Setup drawing position */
338 pdc
->dcattr
.ptlCurrent
.x
= 0;
339 pdc
->dcattr
.ptlCurrent
.y
= 0;
340 pdc
->dcattr
.ptfxCurrent
.x
= 0;
341 pdc
->dcattr
.ptfxCurrent
.y
= 0;
344 pdc
->dclevel
.lIcmMode
= 0;
345 pdc
->dcattr
.lIcmMode
= 0;
346 pdc
->dcattr
.hcmXform
= NULL
;
347 pdc
->dcattr
.flIcmFlags
= 0;
348 pdc
->dcattr
.IcmBrushColor
= CLR_INVALID
;
349 pdc
->dcattr
.IcmPenColor
= CLR_INVALID
;
350 pdc
->dcattr
.pvLIcm
= NULL
;
351 pdc
->dcattr
.hColorSpace
= NULL
; // FIXME: 0189001f
352 pdc
->dclevel
.pColorSpace
= NULL
; // FIXME
353 pdc
->pClrxFormLnk
= NULL
;
356 /* Setup font data */
357 pdc
->hlfntCur
= NULL
; // FIXME: 2f0a0cf8
358 pdc
->pPFFList
= NULL
;
359 pdc
->flSimulationFlags
= 0;
360 pdc
->lEscapement
= 0;
362 pdc
->dcattr
.flFontMapper
= 0;
363 pdc
->dcattr
.flTextAlign
= 0;
364 pdc
->dcattr
.lTextAlign
= 0;
365 pdc
->dcattr
.lTextExtra
= 0;
366 pdc
->dcattr
.lRelAbs
= 1;
367 pdc
->dcattr
.lBreakExtra
= 0;
368 pdc
->dcattr
.cBreak
= 0;
369 pdc
->dcattr
.hlfntNew
= StockObjects
[SYSTEM_FONT
];
370 // pdc->dclevel.pFont = LFONT_ShareLockFont(pdc->dcattr.hlfntNew);
373 pdc
->ipfdDevMax
= 0x0000ffff;
374 pdc
->ulCopyCount
= -1;
375 pdc
->ptlDoBanding
.x
= 0;
376 pdc
->ptlDoBanding
.y
= 0;
377 pdc
->dclevel
.lSaveDepth
= 1;
378 pdc
->dclevel
.hdcSave
= NULL
;
379 pdc
->dcattr
.iGraphicsMode
= GM_COMPATIBLE
;
380 pdc
->dcattr
.iCS_CP
= 0;
381 pdc
->pSurfInfo
= NULL
;
387 DC_Cleanup(PVOID ObjectBody
)
389 PDC pdc
= (PDC
)ObjectBody
;
394 /* Delete saved DCs */
395 DC_vRestoreDC(pdc
, 1);
397 /* Deselect dc objects */
398 DC_vSelectSurface(pdc
, NULL
);
399 DC_vSelectFillBrush(pdc
, NULL
);
400 DC_vSelectLineBrush(pdc
, NULL
);
401 DC_vSelectPalette(pdc
, NULL
);
403 /* Cleanup the dc brushes */
404 EBRUSHOBJ_vCleanup(&pdc
->eboFill
);
405 EBRUSHOBJ_vCleanup(&pdc
->eboLine
);
406 EBRUSHOBJ_vCleanup(&pdc
->eboText
);
407 EBRUSHOBJ_vCleanup(&pdc
->eboBackground
);
410 if (pdc
->rosdc
.hClipRgn
)
411 GreDeleteObject(pdc
->rosdc
.hClipRgn
);
413 REGION_FreeRgnByHandle(pdc
->prgnVis
->BaseObject
.hHmgr
);
414 ASSERT(pdc
->rosdc
.hGCClipRgn
);
415 if (pdc
->rosdc
.hGCClipRgn
)
416 GreDeleteObject(pdc
->rosdc
.hGCClipRgn
);
417 if (NULL
!= pdc
->rosdc
.CombinedClip
)
418 IntEngDeleteClipRegion(pdc
->rosdc
.CombinedClip
);
420 PATH_Delete(pdc
->dclevel
.hPath
);
422 if(pdc
->dctype
== DCTYPE_DIRECT
)
424 EngAcquireSemaphore(pdc
->ppdev
->hsemDevLock
);
425 /* Remove it from the list of DC attached to the Device */
426 PDC tmpDC
= DC_LockDc(pdc
->hdcNext
);
429 tmpDC
->hdcPrev
= pdc
->hdcPrev
;
432 tmpDC
= DC_LockDc(pdc
->hdcPrev
);
435 tmpDC
->hdcNext
= pdc
->hdcNext
;
438 /* Reassign list head if needed */
439 if(pdc
->BaseObject
.hHmgr
== pdc
->dclevel
.pSurface
->hDC
)
442 ASSERT(pdc
->hdcPrev
== NULL
);
443 pdc
->dclevel
.pSurface
->hDC
= pdc
->hdcNext
;
445 EngReleaseSemaphore(pdc
->ppdev
->hsemDevLock
) ;
448 if(pdc
->dclevel
.pSurface
)
449 SURFACE_ShareUnlockSurface(pdc
->dclevel
.pSurface
);
450 PDEVOBJ_vRelease(pdc
->ppdev
) ;
457 DC_SetOwnership(HDC hDC
, PEPROCESS Owner
)
460 PGDI_TABLE_ENTRY Entry
;
464 /* FIXME: This function has broken error handling */
466 if (!GDIOBJ_SetOwnership(hDC
, Owner
))
468 DPRINT1("GDIOBJ_SetOwnership failed\n");
472 pDC
= DC_LockDc(hDC
);
475 DPRINT1("Could not lock DC\n");
481 These regions do not use attribute sections and when allocated, use
482 gdiobj level functions.
484 if (pDC
->rosdc
.hClipRgn
)
486 Index
= GDI_HANDLE_GET_INDEX(pDC
->rosdc
.hClipRgn
);
487 Entry
= &GdiHandleTable
->Entries
[Index
];
488 if (Entry
->UserData
) FreeObjectAttr(Entry
->UserData
);
489 Entry
->UserData
= NULL
;
491 if (!GDIOBJ_SetOwnership(pDC
->rosdc
.hClipRgn
, Owner
)) goto leave
;
495 Index
= GDI_HANDLE_GET_INDEX(pDC
->prgnVis
->BaseObject
.hHmgr
);
496 Entry
= &GdiHandleTable
->Entries
[Index
];
497 if (Entry
->UserData
) FreeObjectAttr(Entry
->UserData
);
498 Entry
->UserData
= NULL
;
500 if (!GDIOBJ_SetOwnership(pDC
->prgnVis
->BaseObject
.hHmgr
, Owner
)) goto leave
;
502 if (pDC
->rosdc
.hGCClipRgn
)
504 Index
= GDI_HANDLE_GET_INDEX(pDC
->rosdc
.hGCClipRgn
);
505 Entry
= &GdiHandleTable
->Entries
[Index
];
506 if (Entry
->UserData
) FreeObjectAttr(Entry
->UserData
);
507 Entry
->UserData
= NULL
;
509 if (!GDIOBJ_SetOwnership(pDC
->rosdc
.hGCClipRgn
, Owner
)) goto leave
;
511 if (pDC
->dclevel
.hPath
)
513 if (!GDIOBJ_SetOwnership(pDC
->dclevel
.hPath
, Owner
)) goto leave
;
526 PUNICODE_STRING pustrDevice
,
528 PUNICODE_STRING pustrLogAddr
,
539 DPRINT("GreOpenDCW(%S, iType=%ld)\n",
540 pustrDevice
? pustrDevice
->Buffer
: NULL
, iType
);
542 /* Get a PDEVOBJ for the device */
543 ppdev
= EngpGetPDEV(pustrDevice
);
546 DPRINT1("Didn't find a suitable PDEV\n");
550 DPRINT("GreOpenDCW - ppdev = %p\n", ppdev
);
552 pdc
= DC_AllocDcWithHandle();
555 DPRINT1("Could not Allocate a DC\n");
556 PDEVOBJ_vRelease(ppdev
);
559 hdc
= pdc
->BaseObject
.hHmgr
;
561 /* Lock ppdev and initialize the new DC */
562 DC_vInitDc(pdc
, iType
, ppdev
);
570 DPRINT("returning hdc = %p\n", hdc
);
578 PUNICODE_STRING pustrDevice
,
580 PUNICODE_STRING pustrLogAddr
,
587 UNICODE_STRING ustrDevice
;
588 WCHAR awcDevice
[CCHDEVICENAME
];
593 /* Only if a devicename is given, we need any data */
596 /* Initialize destination string */
597 RtlInitEmptyUnicodeString(&ustrDevice
, awcDevice
, sizeof(awcDevice
));
601 /* Probe the UNICODE_STRING and the buffer */
602 ProbeForRead(pustrDevice
, sizeof(UNICODE_STRING
), 1);
603 ProbeForRead(pustrDevice
->Buffer
, pustrDevice
->Length
, 1);
605 /* Copy the string */
606 RtlCopyUnicodeString(&ustrDevice
, pustrDevice
);
610 /* FIXME: could be larger */
611 ProbeForRead(pdmInit
, sizeof(DEVMODEW
), 1);
612 RtlCopyMemory(&dmInit
, pdmInit
, sizeof(DEVMODEW
));
617 ProbeForWrite(pUMdhpdev
, sizeof(HANDLE
), 1);
620 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
622 SetLastNtError(_SEH2_GetExceptionCode());
623 _SEH2_YIELD(return NULL
);
636 UNICODE_STRING ustrDISPLAY
= RTL_CONSTANT_STRING(L
"DISPLAY");
637 if (RtlEqualUnicodeString(&ustrDevice
, &ustrDISPLAY
, TRUE
))
643 /* Call the internal function */
644 hdc
= GreOpenDCW(pustrDevice
? &ustrDevice
: NULL
,
645 pdmInit
? &dmInit
: NULL
,
646 NULL
, // fixme pwszLogAddress
650 NULL
, //FIXME: pDriverInfo2
651 pUMdhpdev
? &dhpdev
: NULL
);
653 /* If we got a HDC and a UM dhpdev is requested,... */
654 if (hdc
&& pUMdhpdev
)
656 /* Copy dhpdev to caller (FIXME: use dhpdev?? */
659 /* Pointer was already probed */
660 *(HANDLE
*)pUMdhpdev
= dhpdev
;
662 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
675 NtGdiCreateCompatibleDC(HDC hdc
)
681 DPRINT("NtGdiCreateCompatibleDC(0x%p)\n", hdc
);
683 /* Did the caller provide a DC? */
686 /* Yes, try to lock it */
687 pdc
= DC_LockDc(hdc
);
690 DPRINT1("Could not lock source DC %p\n", hdc
);
694 /* Get the pdev from the DC */
696 InterlockedIncrement(&ppdev
->cPdevRefs
);
698 /* Unlock the source DC */
703 /* No DC given, get default device */
704 ppdev
= EngpGetPDEV(NULL
);
709 DPRINT1("Didn't find a suitable PDEV\n");
713 /* Allocate a new DC */
714 pdcNew
= DC_AllocDcWithHandle();
717 DPRINT1("Could not allocate a new DC\n");
718 PDEVOBJ_vRelease(ppdev
);
721 hdcNew
= pdcNew
->BaseObject
.hHmgr
;
723 /* Lock ppdev and initialize the new DC */
724 DC_vInitDc(pdcNew
, DCTYPE_MEMORY
, ppdev
);
728 /* Allocate a dc attribute */
729 DC_AllocDcAttr(pdcNew
);
732 DC_vSelectSurface(pdcNew
, psurfDefaultBitmap
);
736 DPRINT("Leave NtGdiCreateCompatibleDC hdcNew = %p\n", hdcNew
);
743 IntGdiDeleteDC(HDC hDC
, BOOL Force
)
745 PDC DCToDelete
= DC_LockDc(hDC
);
747 if (DCToDelete
== NULL
)
749 SetLastWin32Error(ERROR_INVALID_HANDLE
);
755 if (DCToDelete
->fs
& DC_FLAG_PERMANENT
)
757 DPRINT1("No! You Naughty Application!\n");
758 DC_UnlockDc(DCToDelete
);
759 return UserReleaseDC(NULL
, hDC
, FALSE
);
763 DC_UnlockDc(DCToDelete
);
765 if (!IsObjectDead(hDC
))
767 if (!GDIOBJ_FreeObjByHandle(hDC
, GDI_OBJECT_TYPE_DC
))
769 DPRINT1("DC_FreeDC failed\n");
774 DPRINT1("Attempted to Delete 0x%x currently being destroyed!!!\n", hDC
);
782 NtGdiDeleteObjectApp(HANDLE DCHandle
)
784 /* Complete all pending operations */
785 NtGdiFlushUserBatch();
787 if (GDI_HANDLE_IS_STOCKOBJ(DCHandle
)) return TRUE
;
789 if (GDI_HANDLE_GET_TYPE(DCHandle
) != GDI_OBJECT_TYPE_DC
)
790 return GreDeleteObject((HGDIOBJ
) DCHandle
);
792 if (IsObjectDead((HGDIOBJ
)DCHandle
)) return TRUE
;
794 if (!GDIOBJ_OwnedByCurrentProcess(DCHandle
))
796 SetLastWin32Error(ERROR_INVALID_HANDLE
);
800 return IntGdiDeleteDC(DCHandle
, FALSE
);
805 MakeInfoDC(PDC pdc
, BOOL bSet
)
810 /* Can not be a display DC. */
811 if (pdc
->fs
& DC_FLAG_DISPLAY
) return FALSE
;
814 if (pdc
->fs
& DC_FLAG_TEMPINFODC
|| pdc
->dctype
== DC_TYPE_DIRECT
)
817 pSurface
= pdc
->dclevel
.pSurface
;
818 pdc
->fs
|= DC_FLAG_TEMPINFODC
;
819 pdc
->pSurfInfo
= pSurface
;
820 pdc
->dctype
= DC_TYPE_INFO
;
821 pdc
->dclevel
.pSurface
= NULL
;
823 PDEVOBJ_sizl(pdc
->ppdev
, &sizl
);
825 if ( sizl
.cx
== pdc
->dclevel
.sizl
.cx
&&
826 sizl
.cy
== pdc
->dclevel
.sizl
.cy
)
829 pdc
->dclevel
.sizl
.cx
= sizl
.cx
;
830 pdc
->dclevel
.sizl
.cy
= sizl
.cy
;
834 if (!(pdc
->fs
& DC_FLAG_TEMPINFODC
) || pdc
->dctype
!= DC_TYPE_INFO
)
837 pSurface
= pdc
->pSurfInfo
;
838 pdc
->fs
&= ~DC_FLAG_TEMPINFODC
;
839 pdc
->dclevel
.pSurface
= pSurface
;
840 pdc
->dctype
= DC_TYPE_DIRECT
;
841 pdc
->pSurfInfo
= NULL
;
844 (pSurface
->SurfObj
.sizlBitmap
.cx
== pdc
->dclevel
.sizl
.cx
&&
845 pSurface
->SurfObj
.sizlBitmap
.cy
== pdc
->dclevel
.sizl
.cy
) )
848 pdc
->dclevel
.sizl
.cx
= pSurface
->SurfObj
.sizlBitmap
.cx
;
849 pdc
->dclevel
.sizl
.cy
= pSurface
->SurfObj
.sizlBitmap
.cy
;
851 return IntSetDefaultRegion(pdc
);
864 PDC pdc
= DC_LockDc(hdc
);
867 Ret
= MakeInfoDC(pdc
, bSet
);
877 PUNICODE_STRING Driver
,
878 PUNICODE_STRING pustrDevice
,
880 CONST PDEVMODEW pdmInit
,
885 hdc
= GreOpenDCW(pustrDevice
,
888 CreateAsIC
? DCTYPE_INFO
:
889 (Driver
? DC_TYPE_DIRECT
: DC_TYPE_DIRECT
),
899 IntGdiCreateDisplayDC(HDEV hDev
, ULONG DcType
, BOOL EmptyDC
)
905 if (DcType
== DC_TYPE_MEMORY
)
906 hDC
= NtGdiCreateCompatibleDC(NULL
); // OH~ Yuck! I think I taste vomit in my mouth!
908 hDC
= IntGdiCreateDC(NULL
, NULL
, NULL
, NULL
, (DcType
== DC_TYPE_INFO
));