2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Support for physical devices
5 * FILE: subsystems/win32/win32k/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
);
57 ppdev
= ExAllocatePoolWithTag(PagedPool
, sizeof(PDEVOBJ
), GDITAG_PDEV
);
61 RtlZeroMemory(ppdev
, sizeof(PDEVOBJ
));
70 PDEVOBJ_vRelease(PPDEVOBJ ppdev
)
73 EngAcquireSemaphore(ghsemPDEV
);
75 /* Decrease reference count */
78 ASSERT(ppdev
->cPdevRefs
>= 0) ;
80 /* Check if references are left */
81 if (ppdev
->cPdevRefs
== 0)
83 /* Do we have a surface? */
86 /* Release the surface and let the driver free it */
87 SURFACE_ShareUnlockSurface(ppdev
->pSurface
);
88 ppdev
->pfn
.DisableSurface(ppdev
->dhpdev
);
91 /* Do we have a palette? */
94 PALETTE_ShareUnlockPalette(ppdev
->ppalSurf
);
98 ppdev
->pfn
.DisablePDEV(ppdev
->dhpdev
);
100 /* Remove it from list */
101 if( ppdev
== gppdevList
)
102 gppdevList
= ppdev
->ppdevNext
;
105 PPDEVOBJ ppdevCurrent
= gppdevList
;
107 while (!found
&& ppdevCurrent
->ppdevNext
)
109 if (ppdevCurrent
->ppdevNext
== ppdev
)
112 ppdevCurrent
= ppdevCurrent
->ppdevNext
;
115 ppdevCurrent
->ppdevNext
= ppdev
->ppdevNext
;
118 /* Is this the primary one ? */
119 if (ppdev
== gppdevPrimary
)
120 gppdevPrimary
= NULL
;
123 ExFreePoolWithTag(ppdev
, GDITAG_PDEV
);
127 EngReleaseSemaphore(ghsemPDEV
);
136 PWSTR pwszLogAddress
)
138 PFN_DrvEnablePDEV pfnEnablePDEV
;
141 DPRINT("PDEVOBJ_bEnablePDEV()\n");
143 /* Get the DrvEnablePDEV function */
144 pfnEnablePDEV
= ppdev
->pldev
->pfn
.EnablePDEV
;
146 /* Call the drivers DrvEnablePDEV function */
147 ppdev
->dhpdev
= pfnEnablePDEV(pdevmode
,
152 (PULONG
)&ppdev
->gdiinfo
,
156 ppdev
->pGraphicsDevice
->pwszDescription
,
157 ppdev
->pGraphicsDevice
->DeviceObject
);
159 /* Fix up some values */
160 if (ppdev
->gdiinfo
.ulLogPixelsX
== 0)
161 ppdev
->gdiinfo
.ulLogPixelsX
= 96;
163 if (ppdev
->gdiinfo
.ulLogPixelsY
== 0)
164 ppdev
->gdiinfo
.ulLogPixelsY
= 96;
167 ppdev
->ppalSurf
= PALETTE_ShareLockPalette(ppdev
->devinfo
.hpalDefault
);
169 /* Setup hatch brushes */
170 for (i
= 0; i
< HS_DDI_MAX
; i
++)
172 if (ppdev
->ahsurf
[i
] == NULL
)
173 ppdev
->ahsurf
[i
] = gahsurfHatch
[i
];
176 DPRINT("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev
->dhpdev
);
183 PDEVOBJ_vCompletePDEV(
186 /* Call the drivers DrvCompletePDEV function */
187 ppdev
->pldev
->pfn
.CompletePDEV(ppdev
->dhpdev
, (HDEV
)ppdev
);
197 /* Check if we already have a surface */
200 /* Increment reference count */
201 GDIOBJ_vReferenceObjectByPointer(&ppdev
->pSurface
->BaseObject
);
205 /* Call the drivers DrvEnableSurface */
206 hsurf
= ppdev
->pldev
->pfn
.EnableSurface(ppdev
->dhpdev
);
208 /* Lock the surface */
209 ppdev
->pSurface
= SURFACE_ShareLockSurface(hsurf
);
212 DPRINT("PDEVOBJ_pSurface() returning %p\n", ppdev
->pSurface
);
213 return ppdev
->pSurface
;
218 PDEVOBJ_pdmMatchDevMode(
222 PGRAPHICS_DEVICE pGraphicsDevice
;
223 PDEVMODEW pdmCurrent
;
227 pGraphicsDevice
= ppdev
->pGraphicsDevice
;
229 for (i
= 0; i
< pGraphicsDevice
->cDevModes
; i
++)
231 pdmCurrent
= pGraphicsDevice
->pDevModeList
[i
].pdm
;
233 /* Compare asked DEVMODE fields
234 * Only compare those that are valid in both DEVMODE structs */
235 dwFields
= pdmCurrent
->dmFields
& pdm
->dmFields
;
237 /* For now, we only need those */
238 if ((dwFields
& DM_BITSPERPEL
) &&
239 (pdmCurrent
->dmBitsPerPel
!= pdm
->dmBitsPerPel
)) continue;
240 if ((dwFields
& DM_PELSWIDTH
) &&
241 (pdmCurrent
->dmPelsWidth
!= pdm
->dmPelsWidth
)) continue;
242 if ((dwFields
& DM_PELSHEIGHT
) &&
243 (pdmCurrent
->dmPelsHeight
!= pdm
->dmPelsHeight
)) continue;
244 if ((dwFields
& DM_DISPLAYFREQUENCY
) &&
245 (pdmCurrent
->dmDisplayFrequency
!= pdm
->dmDisplayFrequency
)) continue;
247 /* Match! Return the DEVMODE */
258 PUNICODE_STRING pustrDeviceName
,
261 PGRAPHICS_DEVICE pGraphicsDevice
;
263 DPRINT("EngpCreatePDEV(%wZ, %p)\n", pustrDeviceName
, pdm
);
265 /* Try to find the GRAPHICS_DEVICE */
268 pGraphicsDevice
= EngpFindGraphicsDevice(pustrDeviceName
, 0, 0);
269 if (!pGraphicsDevice
)
271 DPRINT1("No GRAPHICS_DEVICE found for %ls!\n",
272 pustrDeviceName
? pustrDeviceName
->Buffer
: 0);
278 pGraphicsDevice
= gpPrimaryGraphicsDevice
;
281 /* Allocate a new PDEVOBJ */
282 ppdev
= PDEVOBJ_AllocPDEV();
285 DPRINT1("failed to allocate a PDEV\n");
289 /* If no DEVMODEW is given, ... */
292 /* ... use the device's default one */
293 pdm
= pGraphicsDevice
->pDevModeList
[pGraphicsDevice
->iDefaultMode
].pdm
;
294 DPRINT("Using iDefaultMode = %lu\n", pGraphicsDevice
->iDefaultMode
);
297 /* Try to get a diplay driver */
298 ppdev
->pldev
= EngLoadImageEx(pdm
->dmDeviceName
, LDEV_DEVICE_DISPLAY
);
301 DPRINT1("Could not load display driver '%ls', '%ls'\n",
302 pGraphicsDevice
->pDiplayDrivers
,
304 ExFreePoolWithTag(ppdev
, GDITAG_PDEV
);
308 /* Copy the function table */
309 ppdev
->pfn
= ppdev
->pldev
->pfn
;
311 /* Set MovePointer function */
312 ppdev
->pfnMovePointer
= ppdev
->pfn
.MovePointer
;
313 if (!ppdev
->pfnMovePointer
)
314 ppdev
->pfnMovePointer
= EngMovePointer
;
316 ppdev
->pGraphicsDevice
= pGraphicsDevice
;
317 ppdev
->hsemDevLock
= EngCreateSemaphore();
318 // Should we change the ative mode of pGraphicsDevice ?
319 ppdev
->pdmwDev
= PDEVOBJ_pdmMatchDevMode(ppdev
, pdm
) ;
322 ppdev
->flFlags
= PDEV_DISPLAY
;
324 /* HACK: Don't use the pointer */
325 ppdev
->Pointer
.Exclude
.right
= -1;
327 /* Call the driver to enable the PDEV */
328 if (!PDEVOBJ_bEnablePDEV(ppdev
, pdm
, NULL
))
330 DPRINT1("Failed to enable PDEV!\n");
334 /* FIXME: this must be done in a better way */
335 pGraphicsDevice
->StateFlags
|= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
;
337 /* Tell the driver that the PDEV is ready */
338 PDEVOBJ_vCompletePDEV(ppdev
);
340 /* Return the PDEV */
347 _Inout_ PVOID pvPointer1
,
348 _Inout_ PVOID pvPointer2
)
350 PVOID
*ppvPointer1
= pvPointer1
;
351 PVOID
*ppvPointer2
= pvPointer2
;
354 pvTemp
= *ppvPointer1
;
355 *ppvPointer1
= *ppvPointer2
;
356 *ppvPointer2
= pvTemp
;
367 DRIVER_FUNCTIONS pfn
;
373 /* Exchange driver functions */
374 temp
.pfn
= ppdev
->pfn
;
375 ppdev
->pfn
= ppdev2
->pfn
;
376 ppdev2
->pfn
= temp
.pfn
;
379 SwitchPointer(&ppdev
->pldev
, &ppdev2
->pldev
);
381 /* Exchange DHPDEV */
382 SwitchPointer(&ppdev
->dhpdev
, &ppdev2
->dhpdev
);
384 /* Exchange surfaces and associate them with their new PDEV */
385 SwitchPointer(&ppdev
->pSurface
, &ppdev2
->pSurface
);
386 ppdev
->pSurface
->SurfObj
.hdev
= (HDEV
)ppdev
;
387 ppdev2
->pSurface
->SurfObj
.hdev
= (HDEV
)ppdev2
;
389 /* Exchange devinfo */
390 temp
.devinfo
= ppdev
->devinfo
;
391 ppdev
->devinfo
= ppdev2
->devinfo
;
392 ppdev2
->devinfo
= temp
.devinfo
;
394 /* Exchange gdiinfo */
395 temp
.gdiinfo
= ppdev
->gdiinfo
;
396 ppdev
->gdiinfo
= ppdev2
->gdiinfo
;
397 ppdev2
->gdiinfo
= temp
.gdiinfo
;
399 /* Exchange DEVMODE */
400 SwitchPointer(&ppdev
->pdmwDev
, &ppdev2
->pdmwDev
);
402 /* Exchange state flags */
403 temp
.StateFlags
= ppdev
->pGraphicsDevice
->StateFlags
;
404 ppdev
->pGraphicsDevice
->StateFlags
= ppdev2
->pGraphicsDevice
->StateFlags
;
405 ppdev2
->pGraphicsDevice
->StateFlags
= temp
.StateFlags
;
407 /* Notify each driver instance of its new HDEV association */
408 ppdev
->pfn
.CompletePDEV(ppdev
->dhpdev
, (HDEV
)ppdev
);
409 ppdev2
->pfn
.CompletePDEV(ppdev2
->dhpdev
, (HDEV
)ppdev2
);
419 UNICODE_STRING ustrDevice
;
425 EngAcquireSemaphore(ppdev
->hsemDevLock
);
427 /* And everything else */
428 EngAcquireSemaphore(ghsemPDEV
);
430 DPRINT1("PDEVOBJ_bSwitchMode, ppdev = %p, pSurface = %p\n", ppdev
, ppdev
->pSurface
);
432 // Lookup the GraphicsDevice + select DEVMODE
433 // pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
435 /* 1. Temporarily disable the current PDEV */
436 if (!ppdev
->pfn
.AssertMode(ppdev
->dhpdev
, FALSE
))
438 DPRINT1("DrvAssertMode failed\n");
442 /* 2. Create new PDEV */
443 RtlInitUnicodeString(&ustrDevice
, ppdev
->pGraphicsDevice
->szWinDeviceName
);
444 ppdevTmp
= EngpCreatePDEV(&ustrDevice
, pdm
);
447 DPRINT1("Failed to create a new PDEV\n");
451 /* 3. Create a new surface */
452 pSurface
= PDEVOBJ_pSurface(ppdevTmp
);
455 DPRINT1("DrvEnableSurface failed\n");
459 /* 4. Get DirectDraw information */
460 /* 5. Enable DirectDraw Not traced */
461 /* 6. Copy old PDEV state to new PDEV instance */
463 /* 7. Switch the PDEVs */
464 PDEVOBJ_vSwitchPdev(ppdev
, ppdevTmp
);
466 /* 8. Disable DirectDraw */
468 PDEVOBJ_vRelease(ppdevTmp
);
470 /* Update primary display capabilities */
471 if(ppdev
== gppdevPrimary
)
473 PDEVOBJ_vGetDeviceCaps(ppdev
, &GdiHandleTable
->DevCaps
);
480 EngReleaseSemaphore(ppdev
->hsemDevLock
);
481 EngReleaseSemaphore(ghsemPDEV
);
483 DPRINT1("leave, ppdev = %p, pSurface = %p\n", ppdev
, ppdev
->pSurface
);
492 _In_opt_ PUNICODE_STRING pustrDeviceName
)
494 UNICODE_STRING ustrCurrent
;
496 PGRAPHICS_DEVICE pGraphicsDevice
;
498 /* Acquire PDEV lock */
499 EngAcquireSemaphore(ghsemPDEV
);
501 /* Did the caller pass a device name? */
504 /* Loop all present PDEVs */
505 for (ppdev
= gppdevList
; ppdev
; ppdev
= ppdev
->ppdevNext
)
507 /* Get a pointer to the GRAPHICS_DEVICE */
508 pGraphicsDevice
= ppdev
->pGraphicsDevice
;
510 /* Compare the name */
511 RtlInitUnicodeString(&ustrCurrent
, pGraphicsDevice
->szWinDeviceName
);
512 if (RtlEqualUnicodeString(pustrDeviceName
, &ustrCurrent
, FALSE
))
521 /* Otherwise use the primary PDEV */
522 ppdev
= gppdevPrimary
;
525 /* Did we find one? */
528 /* Yes, reference the PDEV */
529 InterlockedIncrement(&ppdev
->cPdevRefs
);
533 /* No, create a new PDEV for the given device */
534 ppdev
= EngpCreatePDEV(pustrDeviceName
, NULL
);
537 /* Insert the PDEV into the list */
538 ppdev
->ppdevNext
= gppdevList
;
541 /* Set as primary PDEV, if we don't have one yet */
544 gppdevPrimary
= ppdev
;
545 ppdev
->pGraphicsDevice
->StateFlags
|= DISPLAY_DEVICE_PRIMARY_DEVICE
;
550 /* Release PDEV lock */
551 EngReleaseSemaphore(ghsemPDEV
);
558 PDEVOBJ_iGetColorManagementCaps(PPDEVOBJ ppdev
)
562 if (ppdev
->flFlags
& PDEV_DISPLAY
)
564 if (ppdev
->devinfo
.iDitherFormat
== BMF_8BPP
||
565 ppdev
->devinfo
.flGraphicsCaps2
& GCAPS2_CHANGEGAMMARAMP
)
569 if (ppdev
->devinfo
.flGraphicsCaps
& GCAPS_CMYKCOLOR
)
570 ret
|= CM_CMYK_COLOR
;
571 if (ppdev
->devinfo
.flGraphicsCaps
& GCAPS_ICM
)
572 ret
|= CM_DEVICE_ICM
;
579 PDEVOBJ_vGetDeviceCaps(
581 OUT PDEVCAPS pDevCaps
)
583 PGDIINFO pGdiInfo
= &ppdev
->gdiinfo
;
585 pDevCaps
->ulVersion
= pGdiInfo
->ulVersion
;
586 pDevCaps
->ulTechnology
= pGdiInfo
->ulTechnology
;
587 pDevCaps
->ulHorzSizeM
= (pGdiInfo
->ulHorzSize
+ 500) / 1000;
588 pDevCaps
->ulVertSizeM
= (pGdiInfo
->ulVertSize
+ 500) / 1000;
589 pDevCaps
->ulHorzSize
= pGdiInfo
->ulHorzSize
;
590 pDevCaps
->ulVertSize
= pGdiInfo
->ulVertSize
;
591 pDevCaps
->ulHorzRes
= pGdiInfo
->ulHorzRes
;
592 pDevCaps
->ulVertRes
= pGdiInfo
->ulVertRes
;
593 pDevCaps
->ulBitsPixel
= pGdiInfo
->cBitsPixel
;
594 if (pDevCaps
->ulBitsPixel
== 15) pDevCaps
->ulBitsPixel
= 16;
595 pDevCaps
->ulPlanes
= pGdiInfo
->cPlanes
;
596 pDevCaps
->ulNumPens
= pGdiInfo
->ulNumColors
;
597 if (pDevCaps
->ulNumPens
!= -1) pDevCaps
->ulNumPens
*= 5;
598 pDevCaps
->ulNumFonts
= 0; // PDEVOBJ_cFonts(ppdev);
599 pDevCaps
->ulNumColors
= pGdiInfo
->ulNumColors
;
600 pDevCaps
->ulRasterCaps
= pGdiInfo
->flRaster
;
601 pDevCaps
->ulAspectX
= pGdiInfo
->ulAspectX
;
602 pDevCaps
->ulAspectY
= pGdiInfo
->ulAspectY
;
603 pDevCaps
->ulAspectXY
= pGdiInfo
->ulAspectXY
;
604 pDevCaps
->ulLogPixelsX
= pGdiInfo
->ulLogPixelsX
;
605 pDevCaps
->ulLogPixelsY
= pGdiInfo
->ulLogPixelsY
;
606 pDevCaps
->ulSizePalette
= pGdiInfo
->ulNumPalReg
;
607 pDevCaps
->ulColorRes
= pGdiInfo
->ulDACRed
+
608 pGdiInfo
->ulDACGreen
+
610 pDevCaps
->ulPhysicalWidth
= pGdiInfo
->szlPhysSize
.cx
;
611 pDevCaps
->ulPhysicalHeight
= pGdiInfo
->szlPhysSize
.cy
;
612 pDevCaps
->ulPhysicalOffsetX
= pGdiInfo
->ptlPhysOffset
.x
;
613 pDevCaps
->ulPhysicalOffsetY
= pGdiInfo
->ptlPhysOffset
.y
;
614 pDevCaps
->ulTextCaps
= pGdiInfo
->flTextCaps
;
615 pDevCaps
->ulTextCaps
|= (TC_SO_ABLE
|TC_UA_ABLE
|TC_CP_STROKE
|TC_OP_STROKE
|TC_OP_CHARACTER
);
616 if (pGdiInfo
->ulTechnology
!= DT_PLOTTER
)
617 pDevCaps
->ulTextCaps
|= TC_VA_ABLE
;
618 pDevCaps
->ulVRefresh
= pGdiInfo
->ulVRefresh
;
619 pDevCaps
->ulDesktopHorzRes
= pGdiInfo
->ulHorzRes
;
620 pDevCaps
->ulDesktopVertRes
= pGdiInfo
->ulVertRes
;
621 pDevCaps
->ulBltAlignment
= pGdiInfo
->ulBltAlignment
;
622 pDevCaps
->ulPanningHorzRes
= pGdiInfo
->ulPanningHorzRes
;
623 pDevCaps
->ulPanningVertRes
= pGdiInfo
->ulPanningVertRes
;
624 pDevCaps
->xPanningAlignment
= pGdiInfo
->xPanningAlignment
;
625 pDevCaps
->yPanningAlignment
= pGdiInfo
->yPanningAlignment
;
626 pDevCaps
->ulShadeBlend
= pGdiInfo
->flShadeBlend
;
627 pDevCaps
->ulColorMgmtCaps
= PDEVOBJ_iGetColorManagementCaps(ppdev
);
631 /** Exported functions ********************************************************/
633 _Must_inspect_result_ _Ret_z_
636 EngGetDriverName(_In_ HDEV hdev
)
638 PPDEVOBJ ppdev
= (PPDEVOBJ
)hdev
;
641 ASSERT(ppdev
->pldev
);
642 ASSERT(ppdev
->pldev
->pGdiDriverInfo
);
643 ASSERT(ppdev
->pldev
->pGdiDriverInfo
->DriverName
.Buffer
);
645 return ppdev
->pldev
->pGdiDriverInfo
->DriverName
.Buffer
;
658 /* Lock the given DC */
659 pdc
= DC_LockDc(hdc
);
662 EngSetLastError(ERROR_INVALID_HANDLE
);
667 PDEVOBJ_vGetDeviceCaps(pdc
->ppdev
, &devcaps
);
672 /* Return capability */
676 return devcaps
.ulVersion
;
679 return devcaps
.ulTechnology
;
682 return devcaps
.ulHorzSize
;
685 return devcaps
.ulVertSize
;
688 return devcaps
.ulHorzRes
;
691 return devcaps
.ulVertRes
;
694 return devcaps
.ulLogPixelsX
;
697 return devcaps
.ulLogPixelsY
;
700 return devcaps
.ulBitsPixel
;
703 return devcaps
.ulPlanes
;
709 return devcaps
.ulNumPens
;
712 return devcaps
.ulNumFonts
;
715 return devcaps
.ulNumColors
;
718 return devcaps
.ulAspectX
;
721 return devcaps
.ulAspectY
;
724 return devcaps
.ulAspectXY
;
730 return devcaps
.ulSizePalette
;
736 return devcaps
.ulColorRes
;
739 return devcaps
.ulVertRes
;
742 return devcaps
.ulHorzRes
;
745 return devcaps
.ulBltAlignment
;
748 return devcaps
.ulShadeBlend
;
751 return devcaps
.ulColorMgmtCaps
;
754 return devcaps
.ulPhysicalWidth
;
757 return devcaps
.ulPhysicalHeight
;
759 case PHYSICALOFFSETX
:
760 return devcaps
.ulPhysicalOffsetX
;
762 case PHYSICALOFFSETY
:
763 return devcaps
.ulPhysicalOffsetY
;
766 return devcaps
.ulVRefresh
;
769 return devcaps
.ulRasterCaps
;
772 return (CC_CIRCLES
| CC_PIE
| CC_CHORD
| CC_ELLIPSES
| CC_WIDE
|
773 CC_STYLED
| CC_WIDESTYLED
| CC_INTERIORS
| CC_ROUNDRECT
);
776 return (LC_POLYLINE
| LC_MARKER
| LC_POLYMARKER
| LC_WIDE
|
777 LC_STYLED
| LC_WIDESTYLED
| LC_INTERIORS
);
780 return (PC_POLYGON
| PC_RECTANGLE
| PC_WINDPOLYGON
| PC_SCANLINE
|
781 PC_WIDE
| PC_STYLED
| PC_WIDESTYLED
| PC_INTERIORS
);
784 return devcaps
.ulTextCaps
;
797 _Success_(return!=FALSE
)
800 NtGdiGetDeviceCapsAll(
802 OUT PDEVCAPS pDevCaps
)
808 /* Lock the given DC */
809 pdc
= DC_LockDc(hDC
);
812 EngSetLastError(ERROR_INVALID_HANDLE
);
817 PDEVOBJ_vGetDeviceCaps(pdc
->ppdev
, &devcaps
);
822 /* Copy data to caller */
825 ProbeForWrite(pDevCaps
, sizeof(DEVCAPS
), 1);
826 RtlCopyMemory(pDevCaps
, &devcaps
, sizeof(DEVCAPS
));
828 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
830 SetLastNtError(_SEH2_GetExceptionCode());
844 DHPDEV dhpdev
= NULL
;
846 /* Check parameter */
847 if (!hdev
|| (PCHAR
)hdev
< (PCHAR
)MmSystemRangeStart
)
851 EngAcquireSemaphoreShared(ghsemPDEV
);
853 /* Walk through the list of PDEVs */
854 for (ppdev
= gppdevList
; ppdev
; ppdev
= ppdev
->ppdevNext
)
856 /* Compare with the given HDEV */
857 if (ppdev
== (PPDEVOBJ
)hdev
)
859 /* Found the PDEV! Get it's dhpdev and break */
860 dhpdev
= ppdev
->dhpdev
;
865 /* Unlock PDEV list */
866 EngReleaseSemaphore(ghsemPDEV
);
873 PDEVOBJ_sizl(PPDEVOBJ ppdev
, PSIZEL psizl
)
875 if (ppdev
->flFlags
& PDEV_META_DEVICE
)
877 psizl
->cx
= ppdev
->ulHorzRes
;
878 psizl
->cy
= ppdev
->ulVertRes
;
882 psizl
->cx
= ppdev
->gdiinfo
.ulHorzRes
;
883 psizl
->cy
= ppdev
->gdiinfo
.ulVertRes
;