2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Support for physical devices
5 * FILE: win32ss/gdi/eng/pdevobj.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
13 PPDEVOBJ gppdevPrimary
= NULL
;
15 static PPDEVOBJ gppdevList
= NULL
;
16 static HSEMAPHORE ghsemPDEV
;
23 ghsemPDEV
= EngCreateSemaphore();
24 if (!ghsemPDEV
) return STATUS_INSUFFICIENT_RESOURCES
;
25 return STATUS_SUCCESS
;
31 DbgLookupDHPDEV(DHPDEV dhpdev
)
36 EngAcquireSemaphoreShared(ghsemPDEV
);
38 /* Walk through the list of PDEVs */
39 for (ppdev
= gppdevList
; ppdev
; ppdev
= ppdev
->ppdevNext
)
41 /* Compare with the given DHPDEV */
42 if (ppdev
->dhpdev
== dhpdev
) break;
45 /* Unlock PDEV list */
46 EngReleaseSemaphore(ghsemPDEV
);
53 PDEVOBJ_AllocPDEV(VOID
)
57 ppdev
= ExAllocatePoolWithTag(PagedPool
, sizeof(PDEVOBJ
), GDITAG_PDEV
);
61 RtlZeroMemory(ppdev
, sizeof(PDEVOBJ
));
63 ppdev
->hsemDevLock
= EngCreateSemaphore();
64 if (ppdev
->hsemDevLock
== NULL
)
66 ExFreePoolWithTag(ppdev
, GDITAG_PDEV
);
70 /* Allocate EDD_DIRECTDRAW_GLOBAL for our ReactX driver */
71 ppdev
->pEDDgpl
= ExAllocatePoolWithTag(PagedPool
, sizeof(EDD_DIRECTDRAW_GLOBAL
), GDITAG_PDEV
);
73 RtlZeroMemory(ppdev
->pEDDgpl
, sizeof(EDD_DIRECTDRAW_GLOBAL
));
85 EngDeleteSemaphore(ppdev
->hsemDevLock
);
87 ExFreePoolWithTag(ppdev
->pEDDgpl
, GDITAG_PDEV
);
88 ExFreePoolWithTag(ppdev
, GDITAG_PDEV
);
93 PDEVOBJ_vRelease(PPDEVOBJ ppdev
)
96 EngAcquireSemaphore(ghsemPDEV
);
98 /* Decrease reference count */
101 ASSERT(ppdev
->cPdevRefs
>= 0) ;
103 /* Check if references are left */
104 if (ppdev
->cPdevRefs
== 0)
106 /* Do we have a surface? */
109 /* Release the surface and let the driver free it */
110 SURFACE_ShareUnlockSurface(ppdev
->pSurface
);
111 ppdev
->pfn
.DisableSurface(ppdev
->dhpdev
);
114 /* Do we have a palette? */
117 PALETTE_ShareUnlockPalette(ppdev
->ppalSurf
);
120 /* Check if the PDEV was enabled */
121 if (ppdev
->dhpdev
!= NULL
)
123 /* Disable the PDEV */
124 ppdev
->pfn
.DisablePDEV(ppdev
->dhpdev
);
127 /* Remove it from list */
128 if( ppdev
== gppdevList
)
129 gppdevList
= ppdev
->ppdevNext
;
132 PPDEVOBJ ppdevCurrent
= gppdevList
;
134 while (!found
&& ppdevCurrent
->ppdevNext
)
136 if (ppdevCurrent
->ppdevNext
== ppdev
)
139 ppdevCurrent
= ppdevCurrent
->ppdevNext
;
142 ppdevCurrent
->ppdevNext
= ppdev
->ppdevNext
;
145 /* Is this the primary one ? */
146 if (ppdev
== gppdevPrimary
)
147 gppdevPrimary
= NULL
;
150 PDEVOBJ_vDeletePDEV(ppdev
);
154 EngReleaseSemaphore(ghsemPDEV
);
163 PWSTR pwszLogAddress
)
165 PFN_DrvEnablePDEV pfnEnablePDEV
;
168 DPRINT("PDEVOBJ_bEnablePDEV()\n");
170 /* Get the DrvEnablePDEV function */
171 pfnEnablePDEV
= ppdev
->pldev
->pfn
.EnablePDEV
;
173 /* Call the drivers DrvEnablePDEV function */
174 ppdev
->dhpdev
= pfnEnablePDEV(pdevmode
,
179 (PULONG
)&ppdev
->gdiinfo
,
183 ppdev
->pGraphicsDevice
->pwszDescription
,
184 ppdev
->pGraphicsDevice
->DeviceObject
);
185 if (ppdev
->dhpdev
== NULL
)
187 DPRINT1("Failed to enable PDEV\n");
191 /* Fix up some values */
192 if (ppdev
->gdiinfo
.ulLogPixelsX
== 0)
193 ppdev
->gdiinfo
.ulLogPixelsX
= 96;
195 if (ppdev
->gdiinfo
.ulLogPixelsY
== 0)
196 ppdev
->gdiinfo
.ulLogPixelsY
= 96;
198 /* Set raster caps */
199 ppdev
->gdiinfo
.flRaster
= RC_OP_DX_OUTPUT
| RC_GDI20_OUTPUT
| RC_BIGFONT
;
200 if ((ppdev
->gdiinfo
.ulTechnology
!= DT_PLOTTER
) && (ppdev
->gdiinfo
.ulTechnology
!= DT_CHARSTREAM
))
201 ppdev
->gdiinfo
.flRaster
|= RC_STRETCHDIB
| RC_STRETCHBLT
| RC_DIBTODEV
| RC_DI_BITMAP
| RC_BITMAP64
| RC_BITBLT
;
202 if (ppdev
->gdiinfo
.ulTechnology
== DT_RASDISPLAY
)
203 ppdev
->gdiinfo
.flRaster
|= RC_FLOODFILL
;
204 if (ppdev
->devinfo
.flGraphicsCaps
& GCAPS_PALMANAGED
)
205 ppdev
->gdiinfo
.flRaster
|= RC_PALETTE
;
208 ppdev
->ppalSurf
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
210 /* Setup hatch brushes */
211 for (i
= 0; i
< HS_DDI_MAX
; i
++)
213 if (ppdev
->ahsurf
[i
] == NULL
)
214 ppdev
->ahsurf
[i
] = gahsurfHatch
[i
];
217 DPRINT("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev
->dhpdev
);
224 PDEVOBJ_vCompletePDEV(
227 /* Call the drivers DrvCompletePDEV function */
228 ppdev
->pldev
->pfn
.CompletePDEV(ppdev
->dhpdev
, (HDEV
)ppdev
);
238 /* Check if there is no surface for this PDEV yet */
239 if (ppdev
->pSurface
== NULL
)
241 /* Call the drivers DrvEnableSurface */
242 hsurf
= ppdev
->pldev
->pfn
.EnableSurface(ppdev
->dhpdev
);
245 DPRINT1("Failed to create PDEV surface!\n");
249 /* Get a reference to the surface */
250 ppdev
->pSurface
= SURFACE_ShareLockSurface(hsurf
);
251 NT_ASSERT(ppdev
->pSurface
!= NULL
);
254 /* Increment reference count */
255 GDIOBJ_vReferenceObjectByPointer(&ppdev
->pSurface
->BaseObject
);
257 DPRINT("PDEVOBJ_pSurface() returning %p\n", ppdev
->pSurface
);
258 return ppdev
->pSurface
;
263 PDEVOBJ_vRefreshModeList(
266 PGRAPHICS_DEVICE pGraphicsDevice
;
267 PDEVMODEINFO pdminfo
, pdmiNext
;
272 EngAcquireSemaphore(ppdev
->hsemDevLock
);
274 pGraphicsDevice
= ppdev
->pGraphicsDevice
;
276 /* Remember our default mode */
277 dmDefault
= *pGraphicsDevice
->pDevModeList
[pGraphicsDevice
->iDefaultMode
].pdm
;
278 dmCurrent
= *ppdev
->pdmwDev
;
280 /* Clear out the modes */
281 for (pdminfo
= pGraphicsDevice
->pdevmodeInfo
;
285 pdmiNext
= pdminfo
->pdmiNext
;
286 ExFreePoolWithTag(pdminfo
, GDITAG_DEVMODE
);
288 pGraphicsDevice
->pdevmodeInfo
= NULL
;
289 ExFreePoolWithTag(pGraphicsDevice
->pDevModeList
, GDITAG_GDEVICE
);
290 pGraphicsDevice
->pDevModeList
= NULL
;
292 /* Now re-populate the list */
293 if (!EngpPopulateDeviceModeList(pGraphicsDevice
, &dmDefault
))
295 DPRINT1("FIXME: EngpPopulateDeviceModeList failed, we just destroyed a perfectly good mode list\n");
298 ppdev
->pdmwDev
= PDEVOBJ_pdmMatchDevMode(ppdev
, &dmCurrent
);
301 EngReleaseSemaphore(ppdev
->hsemDevLock
);
306 PDEVOBJ_pdmMatchDevMode(
310 PGRAPHICS_DEVICE pGraphicsDevice
;
311 PDEVMODEW pdmCurrent
;
315 pGraphicsDevice
= ppdev
->pGraphicsDevice
;
317 for (i
= 0; i
< pGraphicsDevice
->cDevModes
; i
++)
319 pdmCurrent
= pGraphicsDevice
->pDevModeList
[i
].pdm
;
321 /* Compare asked DEVMODE fields
322 * Only compare those that are valid in both DEVMODE structs */
323 dwFields
= pdmCurrent
->dmFields
& pdm
->dmFields
;
325 /* For now, we only need those */
326 if ((dwFields
& DM_BITSPERPEL
) &&
327 (pdmCurrent
->dmBitsPerPel
!= pdm
->dmBitsPerPel
)) continue;
328 if ((dwFields
& DM_PELSWIDTH
) &&
329 (pdmCurrent
->dmPelsWidth
!= pdm
->dmPelsWidth
)) continue;
330 if ((dwFields
& DM_PELSHEIGHT
) &&
331 (pdmCurrent
->dmPelsHeight
!= pdm
->dmPelsHeight
)) continue;
332 if ((dwFields
& DM_DISPLAYFREQUENCY
) &&
333 (pdmCurrent
->dmDisplayFrequency
!= pdm
->dmDisplayFrequency
)) continue;
335 /* Match! Return the DEVMODE */
346 PUNICODE_STRING pustrDeviceName
,
349 PGRAPHICS_DEVICE pGraphicsDevice
;
351 DPRINT("EngpCreatePDEV(%wZ, %p)\n", pustrDeviceName
, pdm
);
353 /* Try to find the GRAPHICS_DEVICE */
356 pGraphicsDevice
= EngpFindGraphicsDevice(pustrDeviceName
, 0, 0);
357 if (!pGraphicsDevice
)
359 DPRINT1("No GRAPHICS_DEVICE found for %ls!\n",
360 pustrDeviceName
? pustrDeviceName
->Buffer
: 0);
366 pGraphicsDevice
= gpPrimaryGraphicsDevice
;
369 /* Allocate a new PDEVOBJ */
370 ppdev
= PDEVOBJ_AllocPDEV();
373 DPRINT1("failed to allocate a PDEV\n");
377 /* If no DEVMODEW is given, ... */
380 /* ... use the device's default one */
381 pdm
= pGraphicsDevice
->pDevModeList
[pGraphicsDevice
->iDefaultMode
].pdm
;
382 DPRINT("Using iDefaultMode = %lu\n", pGraphicsDevice
->iDefaultMode
);
385 /* Try to get a diplay driver */
386 ppdev
->pldev
= EngLoadImageEx(pdm
->dmDeviceName
, LDEV_DEVICE_DISPLAY
);
389 DPRINT1("Could not load display driver '%ls', '%ls'\n",
390 pGraphicsDevice
->pDiplayDrivers
,
392 PDEVOBJ_vRelease(ppdev
);
396 /* Copy the function table */
397 ppdev
->pfn
= ppdev
->pldev
->pfn
;
399 /* Set MovePointer function */
400 ppdev
->pfnMovePointer
= ppdev
->pfn
.MovePointer
;
401 if (!ppdev
->pfnMovePointer
)
402 ppdev
->pfnMovePointer
= EngMovePointer
;
404 ppdev
->pGraphicsDevice
= pGraphicsDevice
;
406 // DxEngGetHdevData asks for Graphics DeviceObject in hSpooler field
407 ppdev
->hSpooler
= ppdev
->pGraphicsDevice
->DeviceObject
;
409 // Should we change the ative mode of pGraphicsDevice ?
410 ppdev
->pdmwDev
= PDEVOBJ_pdmMatchDevMode(ppdev
, pdm
) ;
413 ppdev
->flFlags
= PDEV_DISPLAY
;
415 /* HACK: Don't use the pointer */
416 ppdev
->Pointer
.Exclude
.right
= -1;
418 /* Call the driver to enable the PDEV */
419 if (!PDEVOBJ_bEnablePDEV(ppdev
, pdm
, NULL
))
421 DPRINT1("Failed to enable PDEV!\n");
422 PDEVOBJ_vRelease(ppdev
);
426 /* FIXME: this must be done in a better way */
427 pGraphicsDevice
->StateFlags
|= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
;
429 /* Tell the driver that the PDEV is ready */
430 PDEVOBJ_vCompletePDEV(ppdev
);
432 /* Return the PDEV */
439 _Inout_ PVOID pvPointer1
,
440 _Inout_ PVOID pvPointer2
)
442 PVOID
*ppvPointer1
= pvPointer1
;
443 PVOID
*ppvPointer2
= pvPointer2
;
446 pvTemp
= *ppvPointer1
;
447 *ppvPointer1
= *ppvPointer2
;
448 *ppvPointer2
= pvTemp
;
459 DRIVER_FUNCTIONS pfn
;
465 /* Exchange driver functions */
466 temp
.pfn
= ppdev
->pfn
;
467 ppdev
->pfn
= ppdev2
->pfn
;
468 ppdev2
->pfn
= temp
.pfn
;
471 SwitchPointer(&ppdev
->pldev
, &ppdev2
->pldev
);
473 /* Exchange DHPDEV */
474 SwitchPointer(&ppdev
->dhpdev
, &ppdev2
->dhpdev
);
476 /* Exchange surfaces and associate them with their new PDEV */
477 SwitchPointer(&ppdev
->pSurface
, &ppdev2
->pSurface
);
478 ppdev
->pSurface
->SurfObj
.hdev
= (HDEV
)ppdev
;
479 ppdev2
->pSurface
->SurfObj
.hdev
= (HDEV
)ppdev2
;
481 /* Exchange devinfo */
482 temp
.devinfo
= ppdev
->devinfo
;
483 ppdev
->devinfo
= ppdev2
->devinfo
;
484 ppdev2
->devinfo
= temp
.devinfo
;
486 /* Exchange gdiinfo */
487 temp
.gdiinfo
= ppdev
->gdiinfo
;
488 ppdev
->gdiinfo
= ppdev2
->gdiinfo
;
489 ppdev2
->gdiinfo
= temp
.gdiinfo
;
491 /* Exchange DEVMODE */
492 SwitchPointer(&ppdev
->pdmwDev
, &ppdev2
->pdmwDev
);
494 /* Exchange state flags */
495 temp
.StateFlags
= ppdev
->pGraphicsDevice
->StateFlags
;
496 ppdev
->pGraphicsDevice
->StateFlags
= ppdev2
->pGraphicsDevice
->StateFlags
;
497 ppdev2
->pGraphicsDevice
->StateFlags
= temp
.StateFlags
;
499 /* Notify each driver instance of its new HDEV association */
500 ppdev
->pfn
.CompletePDEV(ppdev
->dhpdev
, (HDEV
)ppdev
);
501 ppdev2
->pfn
.CompletePDEV(ppdev2
->dhpdev
, (HDEV
)ppdev2
);
511 UNICODE_STRING ustrDevice
;
517 EngAcquireSemaphore(ppdev
->hsemDevLock
);
519 /* And everything else */
520 EngAcquireSemaphore(ghsemPDEV
);
522 DPRINT1("PDEVOBJ_bSwitchMode, ppdev = %p, pSurface = %p\n", ppdev
, ppdev
->pSurface
);
524 // Lookup the GraphicsDevice + select DEVMODE
525 // pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
527 /* 1. Temporarily disable the current PDEV and reset video to its default mode */
528 if (!ppdev
->pfn
.AssertMode(ppdev
->dhpdev
, FALSE
))
530 DPRINT1("DrvAssertMode(FALSE) failed\n");
534 /* 2. Create new PDEV */
535 RtlInitUnicodeString(&ustrDevice
, ppdev
->pGraphicsDevice
->szWinDeviceName
);
536 ppdevTmp
= EngpCreatePDEV(&ustrDevice
, pdm
);
539 DPRINT1("Failed to create a new PDEV\n");
543 /* 3. Create a new surface */
544 pSurface
= PDEVOBJ_pSurface(ppdevTmp
);
547 DPRINT1("PDEVOBJ_pSurface failed\n");
548 PDEVOBJ_vRelease(ppdevTmp
);
552 /* 4. Get DirectDraw information */
553 /* 5. Enable DirectDraw Not traced */
554 /* 6. Copy old PDEV state to new PDEV instance */
556 /* 7. Switch the PDEVs */
557 PDEVOBJ_vSwitchPdev(ppdev
, ppdevTmp
);
559 /* 8. Disable DirectDraw */
561 PDEVOBJ_vRelease(ppdevTmp
);
563 /* Update primary display capabilities */
564 if(ppdev
== gppdevPrimary
)
566 PDEVOBJ_vGetDeviceCaps(ppdev
, &GdiHandleTable
->DevCaps
);
573 /* Set the new video mode, or restore the original one in case of failure */
574 if (!ppdev
->pfn
.AssertMode(ppdev
->dhpdev
, TRUE
))
576 DPRINT1("DrvAssertMode(TRUE) failed\n");
580 /* Unlock everything else */
581 EngReleaseSemaphore(ghsemPDEV
);
582 /* Unlock the PDEV */
583 EngReleaseSemaphore(ppdev
->hsemDevLock
);
585 DPRINT1("leave, ppdev = %p, pSurface = %p\n", ppdev
, ppdev
->pSurface
);
594 _In_opt_ PUNICODE_STRING pustrDeviceName
)
596 UNICODE_STRING ustrCurrent
;
598 PGRAPHICS_DEVICE pGraphicsDevice
;
600 /* Acquire PDEV lock */
601 EngAcquireSemaphore(ghsemPDEV
);
603 /* Did the caller pass a device name? */
606 /* Loop all present PDEVs */
607 for (ppdev
= gppdevList
; ppdev
; ppdev
= ppdev
->ppdevNext
)
609 /* Get a pointer to the GRAPHICS_DEVICE */
610 pGraphicsDevice
= ppdev
->pGraphicsDevice
;
612 /* Compare the name */
613 RtlInitUnicodeString(&ustrCurrent
, pGraphicsDevice
->szWinDeviceName
);
614 if (RtlEqualUnicodeString(pustrDeviceName
, &ustrCurrent
, FALSE
))
623 /* Otherwise use the primary PDEV */
624 ppdev
= gppdevPrimary
;
627 /* Did we find one? */
630 /* Yes, reference the PDEV */
631 InterlockedIncrement(&ppdev
->cPdevRefs
);
635 /* No, create a new PDEV for the given device */
636 ppdev
= EngpCreatePDEV(pustrDeviceName
, NULL
);
639 /* Insert the PDEV into the list */
640 ppdev
->ppdevNext
= gppdevList
;
643 /* Set as primary PDEV, if we don't have one yet */
646 gppdevPrimary
= ppdev
;
647 ppdev
->pGraphicsDevice
->StateFlags
|= DISPLAY_DEVICE_PRIMARY_DEVICE
;
652 /* Release PDEV lock */
653 EngReleaseSemaphore(ghsemPDEV
);
660 PDEVOBJ_iGetColorManagementCaps(PPDEVOBJ ppdev
)
664 if (ppdev
->flFlags
& PDEV_DISPLAY
)
666 if (ppdev
->devinfo
.iDitherFormat
== BMF_8BPP
||
667 ppdev
->devinfo
.flGraphicsCaps2
& GCAPS2_CHANGEGAMMARAMP
)
671 if (ppdev
->devinfo
.flGraphicsCaps
& GCAPS_CMYKCOLOR
)
672 ret
|= CM_CMYK_COLOR
;
673 if (ppdev
->devinfo
.flGraphicsCaps
& GCAPS_ICM
)
674 ret
|= CM_DEVICE_ICM
;
681 PDEVOBJ_vGetDeviceCaps(
683 OUT PDEVCAPS pDevCaps
)
685 PGDIINFO pGdiInfo
= &ppdev
->gdiinfo
;
687 pDevCaps
->ulVersion
= pGdiInfo
->ulVersion
;
688 pDevCaps
->ulTechnology
= pGdiInfo
->ulTechnology
;
689 pDevCaps
->ulHorzSizeM
= (pGdiInfo
->ulHorzSize
+ 500) / 1000;
690 pDevCaps
->ulVertSizeM
= (pGdiInfo
->ulVertSize
+ 500) / 1000;
691 pDevCaps
->ulHorzSize
= pGdiInfo
->ulHorzSize
;
692 pDevCaps
->ulVertSize
= pGdiInfo
->ulVertSize
;
693 pDevCaps
->ulHorzRes
= pGdiInfo
->ulHorzRes
;
694 pDevCaps
->ulVertRes
= pGdiInfo
->ulVertRes
;
695 pDevCaps
->ulBitsPixel
= pGdiInfo
->cBitsPixel
;
696 if (pDevCaps
->ulBitsPixel
== 15) pDevCaps
->ulBitsPixel
= 16;
697 pDevCaps
->ulPlanes
= pGdiInfo
->cPlanes
;
698 pDevCaps
->ulNumPens
= pGdiInfo
->ulNumColors
;
699 if (pDevCaps
->ulNumPens
!= -1) pDevCaps
->ulNumPens
*= 5;
700 pDevCaps
->ulNumFonts
= 0; // PDEVOBJ_cFonts(ppdev);
701 pDevCaps
->ulNumColors
= pGdiInfo
->ulNumColors
;
702 pDevCaps
->ulRasterCaps
= pGdiInfo
->flRaster
;
703 pDevCaps
->ulAspectX
= pGdiInfo
->ulAspectX
;
704 pDevCaps
->ulAspectY
= pGdiInfo
->ulAspectY
;
705 pDevCaps
->ulAspectXY
= pGdiInfo
->ulAspectXY
;
706 pDevCaps
->ulLogPixelsX
= pGdiInfo
->ulLogPixelsX
;
707 pDevCaps
->ulLogPixelsY
= pGdiInfo
->ulLogPixelsY
;
708 pDevCaps
->ulSizePalette
= pGdiInfo
->ulNumPalReg
;
709 pDevCaps
->ulColorRes
= pGdiInfo
->ulDACRed
+
710 pGdiInfo
->ulDACGreen
+
712 pDevCaps
->ulPhysicalWidth
= pGdiInfo
->szlPhysSize
.cx
;
713 pDevCaps
->ulPhysicalHeight
= pGdiInfo
->szlPhysSize
.cy
;
714 pDevCaps
->ulPhysicalOffsetX
= pGdiInfo
->ptlPhysOffset
.x
;
715 pDevCaps
->ulPhysicalOffsetY
= pGdiInfo
->ptlPhysOffset
.y
;
716 pDevCaps
->ulTextCaps
= pGdiInfo
->flTextCaps
;
717 pDevCaps
->ulTextCaps
|= (TC_SO_ABLE
|TC_UA_ABLE
|TC_CP_STROKE
|TC_OP_STROKE
|TC_OP_CHARACTER
);
718 if (pGdiInfo
->ulTechnology
!= DT_PLOTTER
)
719 pDevCaps
->ulTextCaps
|= TC_VA_ABLE
;
720 pDevCaps
->ulVRefresh
= pGdiInfo
->ulVRefresh
;
721 pDevCaps
->ulDesktopHorzRes
= pGdiInfo
->ulHorzRes
;
722 pDevCaps
->ulDesktopVertRes
= pGdiInfo
->ulVertRes
;
723 pDevCaps
->ulBltAlignment
= pGdiInfo
->ulBltAlignment
;
724 pDevCaps
->ulPanningHorzRes
= pGdiInfo
->ulPanningHorzRes
;
725 pDevCaps
->ulPanningVertRes
= pGdiInfo
->ulPanningVertRes
;
726 pDevCaps
->xPanningAlignment
= pGdiInfo
->xPanningAlignment
;
727 pDevCaps
->yPanningAlignment
= pGdiInfo
->yPanningAlignment
;
728 pDevCaps
->ulShadeBlend
= pGdiInfo
->flShadeBlend
;
729 pDevCaps
->ulColorMgmtCaps
= PDEVOBJ_iGetColorManagementCaps(ppdev
);
733 /** Exported functions ********************************************************/
735 _Must_inspect_result_ _Ret_z_
738 EngGetDriverName(_In_ HDEV hdev
)
740 PPDEVOBJ ppdev
= (PPDEVOBJ
)hdev
;
743 ASSERT(ppdev
->pldev
);
744 ASSERT(ppdev
->pldev
->pGdiDriverInfo
);
745 ASSERT(ppdev
->pldev
->pGdiDriverInfo
->DriverName
.Buffer
);
747 return ppdev
->pldev
->pGdiDriverInfo
->DriverName
.Buffer
;
760 /* Lock the given DC */
761 pdc
= DC_LockDc(hdc
);
764 EngSetLastError(ERROR_INVALID_HANDLE
);
769 PDEVOBJ_vGetDeviceCaps(pdc
->ppdev
, &devcaps
);
774 /* Return capability */
778 return devcaps
.ulVersion
;
781 return devcaps
.ulTechnology
;
784 return devcaps
.ulHorzSize
;
787 return devcaps
.ulVertSize
;
790 return devcaps
.ulHorzRes
;
793 return devcaps
.ulVertRes
;
796 return devcaps
.ulLogPixelsX
;
799 return devcaps
.ulLogPixelsY
;
802 return devcaps
.ulBitsPixel
;
805 return devcaps
.ulPlanes
;
811 return devcaps
.ulNumPens
;
814 return devcaps
.ulNumFonts
;
817 return devcaps
.ulNumColors
;
820 return devcaps
.ulAspectX
;
823 return devcaps
.ulAspectY
;
826 return devcaps
.ulAspectXY
;
832 return devcaps
.ulSizePalette
;
838 return devcaps
.ulColorRes
;
841 return devcaps
.ulVertRes
;
844 return devcaps
.ulHorzRes
;
847 return devcaps
.ulBltAlignment
;
850 return devcaps
.ulShadeBlend
;
853 return devcaps
.ulColorMgmtCaps
;
856 return devcaps
.ulPhysicalWidth
;
859 return devcaps
.ulPhysicalHeight
;
861 case PHYSICALOFFSETX
:
862 return devcaps
.ulPhysicalOffsetX
;
864 case PHYSICALOFFSETY
:
865 return devcaps
.ulPhysicalOffsetY
;
868 return devcaps
.ulVRefresh
;
871 return devcaps
.ulRasterCaps
;
874 return (CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
| CC_WIDE
|
875 CC_STYLED
| CC_WIDESTYLED
| CC_INTERIORS
| CC_ROUNDRECT
);
878 return (LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
879 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
);
882 return (PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
| PC_SCANLINE
|
883 PC_WIDE
| PC_STYLED
| PC_WIDESTYLED
| PC_INTERIORS
);
886 return devcaps
.ulTextCaps
;
899 _Success_(return!=FALSE
)
902 NtGdiGetDeviceCapsAll(
904 OUT PDEVCAPS pDevCaps
)
910 /* Lock the given DC */
911 pdc
= DC_LockDc(hDC
);
914 EngSetLastError(ERROR_INVALID_HANDLE
);
919 PDEVOBJ_vGetDeviceCaps(pdc
->ppdev
, &devcaps
);
924 /* Copy data to caller */
927 ProbeForWrite(pDevCaps
, sizeof(DEVCAPS
), 1);
928 RtlCopyMemory(pDevCaps
, &devcaps
, sizeof(DEVCAPS
));
930 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
932 SetLastNtError(_SEH2_GetExceptionCode());
946 DHPDEV dhpdev
= NULL
;
948 /* Check parameter */
949 if (!hdev
|| (PCHAR
)hdev
< (PCHAR
)MmSystemRangeStart
)
953 EngAcquireSemaphoreShared(ghsemPDEV
);
955 /* Walk through the list of PDEVs */
956 for (ppdev
= gppdevList
; ppdev
; ppdev
= ppdev
->ppdevNext
)
958 /* Compare with the given HDEV */
959 if (ppdev
== (PPDEVOBJ
)hdev
)
961 /* Found the PDEV! Get it's dhpdev and break */
962 dhpdev
= ppdev
->dhpdev
;
967 /* Unlock PDEV list */
968 EngReleaseSemaphore(ghsemPDEV
);
975 PDEVOBJ_sizl(PPDEVOBJ ppdev
, PSIZEL psizl
)
977 if (ppdev
->flFlags
& PDEV_META_DEVICE
)
979 psizl
->cx
= ppdev
->ulHorzRes
;
980 psizl
->cy
= ppdev
->ulVertRes
;
984 psizl
->cx
= ppdev
->gdiinfo
.ulHorzRes
;
985 psizl
->cy
= ppdev
->gdiinfo
.ulVertRes
;