Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3102 lines
98 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: pdevobj.cxx
  3. *
  4. * Non-inline methods of PDEVOBJ objects.
  5. *
  6. * Copyright (c) 1990-1999 Microsoft Corporation
  7. \**************************************************************************/
  8. #include "precomp.hxx"
  9. extern DRVFN gadrvfnPanning[];
  10. extern ULONG gcdrvfnPanning;
  11. //
  12. // This flag is TRUE if the default GUI stock font is partially intialized.
  13. // During stock font initialization there is no display driver and therefore
  14. // we do not have one of the parameters (vertical DPI) needed to compute
  15. // the font height. Therefore, we do it when the first display driver is
  16. // initialized.
  17. //
  18. extern BOOL gbFinishDefGUIFontInit;
  19. //
  20. // This is size of DirectDraw context which we keep in PDEV.
  21. //
  22. extern DWORD gdwDirectDrawContext;
  23. // Use this as the default height if LOGFONTs provided by DEVINFO do not
  24. // specify.
  25. #define DEFAULT_POINT_SIZE 12L
  26. #define DEFAULT_DPI 72L
  27. #if ((HT_PATSIZE_2x2 != HTPAT_SIZE_2x2) || \
  28. (HT_PATSIZE_2x2_M != HTPAT_SIZE_2x2_M) || \
  29. (HT_PATSIZE_4x4 != HTPAT_SIZE_4x4) || \
  30. (HT_PATSIZE_4x4_M != HTPAT_SIZE_4x4_M) || \
  31. (HT_PATSIZE_6x6 != HTPAT_SIZE_6x6) || \
  32. (HT_PATSIZE_6x6_M != HTPAT_SIZE_6x6_M) || \
  33. (HT_PATSIZE_8x8 != HTPAT_SIZE_8x8) || \
  34. (HT_PATSIZE_8x8_M != HTPAT_SIZE_8x8_M) || \
  35. (HT_PATSIZE_10x10 != HTPAT_SIZE_10x10) || \
  36. (HT_PATSIZE_10x10_M != HTPAT_SIZE_10x10_M) || \
  37. (HT_PATSIZE_12x12 != HTPAT_SIZE_12x12) || \
  38. (HT_PATSIZE_12x12_M != HTPAT_SIZE_12x12_M) || \
  39. (HT_PATSIZE_14x14 != HTPAT_SIZE_14x14) || \
  40. (HT_PATSIZE_14x14_M != HTPAT_SIZE_14x14_M) || \
  41. (HT_PATSIZE_16x16 != HTPAT_SIZE_16x16) || \
  42. (HT_PATSIZE_16x16_M != HTPAT_SIZE_16x16_M) || \
  43. (HT_PATSIZE_SUPERCELL != HTPAT_SIZE_SUPERCELL) || \
  44. (HT_PATSIZE_SUPERCELL_M != HTPAT_SIZE_SUPERCELL_M) || \
  45. (HT_PATSIZE_USER != HTPAT_SIZE_USER))
  46. #error * HT_PATSIZE different in winddi.h and ht.h *
  47. #endif
  48. #if ((HT_FLAG_SQUARE_DEVICE_PEL != HIF_SQUARE_DEVICE_PEL) || \
  49. (HT_FLAG_HAS_BLACK_DYE != HIF_HAS_BLACK_DYE) || \
  50. (HT_FLAG_ADDITIVE_PRIMS != HIF_ADDITIVE_PRIMS))
  51. #error * HT_FLAG different in winddi.h and ht.h *
  52. #endif
  53. //
  54. // Global linked list of all PDEVs in the system.
  55. //
  56. extern "C"
  57. {
  58. extern HFASTMUTEX ghfmMemory;
  59. }
  60. PPDEV gppdevList = NULL;
  61. PPDEV gppdevTrueType = NULL;
  62. PPDEV gppdevATMFD = NULL;
  63. VOID
  64. vDeleteBitmapClone(
  65. SURFOBJ *pso
  66. );
  67. /******************************Member*Function*****************************\
  68. * PDEVOBJ::bMakeSurface ()
  69. *
  70. * Asks the device driver to create a surface for the PDEV. This function
  71. * can be called even if the PDEV already has a surface.
  72. *
  73. \**************************************************************************/
  74. BOOL PDEVOBJ::bMakeSurface()
  75. {
  76. TRACE_INIT(("PDEVOBJ::bMakeSurface: ENTERING\n"));
  77. BOOL bRet;
  78. if (ppdev->pSurface != NULL)
  79. return(TRUE);
  80. HSURF hTemp = (HSURF) 0;
  81. // Ask the driver for a surface.
  82. PDEVOBJ po((HDEV)ppdev);
  83. GreEnterMonitoredSection(ppdev, WD_DEVLOCK);
  84. hTemp = (*PPFNDRV(po,EnableSurface))(ppdev->dhpdev);
  85. GreExitMonitoredSection(ppdev, WD_DEVLOCK);
  86. if (hTemp == (HSURF) 0)
  87. {
  88. WARNING("EnableSurface on device return hsurf 0\n");
  89. return(FALSE);
  90. }
  91. SURFREF sr(hTemp);
  92. ASSERTGDI(sr.bValid(),"Bad surface for device");
  93. // Mark this as a device surface.
  94. sr.ps->vPDEVSurface();
  95. sr.vKeepIt();
  96. ppdev->pSurface = sr.ps;
  97. // For 1.0 compatibility, set the pSurface iFormat to iDitherFormat. This can
  98. // be changed to an ASSERT if we no longer wants to support NT 1.0 drivers,
  99. // which has BMF_DEVICE in the iFormat for device surfaces.
  100. if (sr.ps->iFormat() == BMF_DEVICE)
  101. {
  102. sr.ps->iFormat(ppdev->devinfo.iDitherFormat);
  103. ASSERTGDI(ppdev->devinfo.iDitherFormat != BMF_DEVICE,
  104. "ERROR iformat is hosed\n");
  105. }
  106. // Put the PDEV's palette in the main device surface.
  107. // Reference count the palette, it has a new user.
  108. ppdev->pSurface->ppal(ppdev->ppalSurf);
  109. // If this is surface for layered driver, mark it as mirrored surface.
  110. if (flGraphicsCaps() & GCAPS_LAYERED)
  111. {
  112. sr.ps->vSetMirror();
  113. }
  114. HmgShareLock((HOBJ) ppdev->ppalSurf->hGet(), PAL_TYPE);
  115. TRACE_INIT(("PDEVOBJ::bMakeSurface: SUCCESS\n"));
  116. // We move the mouse point off-screen in order to set an initial position and
  117. // to fix a common driver bug, which is to show uninitialized garbage until
  118. // the first DrvSetPointerShape call occurs.
  119. if (bDisplayPDEV())
  120. {
  121. GreMovePointer(po.hdev(), -1, -1, MP_PROCEDURAL);
  122. }
  123. // Enable PDEV components.
  124. bRet = DxDdEnableDirectDraw(po.hdev(),TRUE);
  125. // Filter the driver hooks after DirectDraw has loaded but before we
  126. // enable sprites, so that the filter can filter DirectX calls and
  127. // the sprite code gets the filtered result.
  128. vFilterDriverHooks();
  129. bRet &= bSpEnableSprites(po.hdev());
  130. vEnableSynchronize(po.hdev());
  131. vNotify(DN_DRAWING_BEGIN, NULL);
  132. return(bRet);
  133. }
  134. /******************************Member*Function*****************************\
  135. * PDEVOBJ::bEnableHalftone(pca)
  136. *
  137. * Creates and initializes a device halftone info. The space is allocated
  138. * by the halftone.dll with heapCreate() and heapAlloc() calls. All
  139. * the halftone resources are managed by the halftone.dll.
  140. *
  141. * History:
  142. * 07-Nov-1991 -by- Wendy Wu [wendywu]
  143. * Wrote it.
  144. \**************************************************************************/
  145. COLORADJUSTMENT gcaDefault =
  146. {
  147. sizeof(COLORADJUSTMENT), // WORD caSize
  148. 0, // WORD caFlags
  149. ILLUMINANT_DEFAULT, // WORD caIlluminantIndex
  150. HT_DEF_RGB_GAMMA, // WORD caRedPowerGamma
  151. HT_DEF_RGB_GAMMA, // WORD caGreenPowerGamma
  152. HT_DEF_RGB_GAMMA, // WORD caBluePowerGamma
  153. REFERENCE_BLACK_DEFAULT, // WORD caReferenceBlack
  154. REFERENCE_WHITE_DEFAULT, // WORD caReferenceWhite
  155. CONTRAST_ADJ_DEFAULT, // SHORT caContrast
  156. BRIGHTNESS_ADJ_DEFAULT, // SHORT caBrightness
  157. COLORFULNESS_ADJ_DEFAULT, // SHORT caColorfulness
  158. REDGREENTINT_ADJ_DEFAULT, // SHORT caRedGreenTint
  159. };
  160. BOOL PDEVOBJ::bEnableHalftone(PCOLORADJUSTMENT pca)
  161. {
  162. ASSERTGDI(pDevHTInfo() == NULL, "bEnableHalftone: pDevHTInfo not null\n");
  163. //
  164. // Create a halftone palette based on the format specified in GDIINFO.
  165. //
  166. PALMEMOBJ palHT;
  167. if (!palHT.bCreateHTPalette(GdiInfo()->ulHTOutputFormat, GdiInfo()))
  168. return(FALSE);
  169. //
  170. // Create the device halftone info.
  171. //
  172. HTINITINFO htInitInfo;
  173. HALFTONEPATTERN HTPat;
  174. htInitInfo.Version = HTINITINFO_VERSION;
  175. htInitInfo.Flags = (WORD)(ppdev->GdiInfo.flHTFlags & 0xFFFF);
  176. htInitInfo.CMYBitMask8BPP = (BYTE)((ppdev->GdiInfo.flHTFlags &
  177. HT_FLAG_8BPP_CMY332_MASK) >> 24);
  178. htInitInfo.bReserved = 0;
  179. if (ppdev->GdiInfo.ulHTPatternSize <= HTPAT_SIZE_MAX_INDEX)
  180. htInitInfo.HTPatternIndex = (BYTE)ppdev->GdiInfo.ulHTPatternSize;
  181. else
  182. htInitInfo.HTPatternIndex = HTPAT_SIZE_DEFAULT;
  183. PCOLORINFO pci = &GdiInfo()->ciDevice;
  184. htInitInfo.DevicePowerGamma = (UDECI4)((pci->RedGamma + pci->GreenGamma +
  185. pci->BlueGamma) / 3);
  186. htInitInfo.DeviceRGamma = (UDECI4)pci->RedGamma;
  187. htInitInfo.DeviceGGamma = (UDECI4)pci->GreenGamma;
  188. htInitInfo.DeviceBGamma = (UDECI4)pci->BlueGamma;
  189. htInitInfo.HTCallBackFunction = NULL;
  190. htInitInfo.pHalftonePattern = NULL;
  191. htInitInfo.pInputRGBInfo = NULL;
  192. if (htInitInfo.HTPatternIndex == HTPAT_SIZE_USER) {
  193. if ((ppdev->GdiInfo.cxHTPat >= HT_USERPAT_CX_MIN) &&
  194. (ppdev->GdiInfo.cxHTPat <= HT_USERPAT_CX_MAX) &&
  195. (ppdev->GdiInfo.cyHTPat >= HT_USERPAT_CY_MIN) &&
  196. (ppdev->GdiInfo.cyHTPat <= HT_USERPAT_CY_MAX) &&
  197. (ppdev->GdiInfo.pHTPatA) &&
  198. (ppdev->GdiInfo.pHTPatB) &&
  199. (ppdev->GdiInfo.pHTPatC)) {
  200. HTPat.cbSize = sizeof(HALFTONEPATTERN);
  201. HTPat.Flags = 0;
  202. HTPat.Width = (WORD)ppdev->GdiInfo.cxHTPat;
  203. HTPat.Height = (WORD)ppdev->GdiInfo.cyHTPat;
  204. HTPat.pHTPatA = (LPBYTE)ppdev->GdiInfo.pHTPatA;
  205. HTPat.pHTPatB = (LPBYTE)ppdev->GdiInfo.pHTPatB;
  206. HTPat.pHTPatC = (LPBYTE)ppdev->GdiInfo.pHTPatC;
  207. htInitInfo.pHalftonePattern = &HTPat;
  208. } else {
  209. htInitInfo.HTPatternIndex = HTPAT_SIZE_DEFAULT;
  210. }
  211. }
  212. CIEINFO cie;
  213. cie.Red.x = (DECI4)pci->Red.x;
  214. cie.Red.y = (DECI4)pci->Red.y;
  215. cie.Red.Y = (DECI4)pci->Red.Y;
  216. cie.Green.x = (DECI4)pci->Green.x;
  217. cie.Green.y = (DECI4)pci->Green.y;
  218. cie.Green.Y = (DECI4)pci->Green.Y;
  219. cie.Blue.x = (DECI4)pci->Blue.x;
  220. cie.Blue.y = (DECI4)pci->Blue.y;
  221. cie.Blue.Y = (DECI4)pci->Blue.Y;
  222. cie.Cyan.x = (DECI4)pci->Cyan.x;
  223. cie.Cyan.y = (DECI4)pci->Cyan.y;
  224. cie.Cyan.Y = (DECI4)pci->Cyan.Y;
  225. cie.Magenta.x = (DECI4)pci->Magenta.x;
  226. cie.Magenta.y = (DECI4)pci->Magenta.y;
  227. cie.Magenta.Y = (DECI4)pci->Magenta.Y;
  228. cie.Yellow.x = (DECI4)pci->Yellow.x;
  229. cie.Yellow.y = (DECI4)pci->Yellow.y;
  230. cie.Yellow.Y = (DECI4)pci->Yellow.Y;
  231. cie.AlignmentWhite.x = (DECI4)pci->AlignmentWhite.x;
  232. cie.AlignmentWhite.y = (DECI4)pci->AlignmentWhite.y;
  233. cie.AlignmentWhite.Y = (DECI4)pci->AlignmentWhite.Y;
  234. htInitInfo.pDeviceCIEInfo = &cie;
  235. SOLIDDYESINFO DeviceSolidDyesInfo;
  236. DeviceSolidDyesInfo.MagentaInCyanDye = (UDECI4)pci->MagentaInCyanDye;
  237. DeviceSolidDyesInfo.YellowInCyanDye = (UDECI4)pci->YellowInCyanDye;
  238. DeviceSolidDyesInfo.CyanInMagentaDye = (UDECI4)pci->CyanInMagentaDye;
  239. DeviceSolidDyesInfo.YellowInMagentaDye = (UDECI4)pci->YellowInMagentaDye;
  240. DeviceSolidDyesInfo.CyanInYellowDye = (UDECI4)pci->CyanInYellowDye;
  241. DeviceSolidDyesInfo.MagentaInYellowDye = (UDECI4)pci->MagentaInYellowDye;
  242. htInitInfo.pDeviceSolidDyesInfo = &DeviceSolidDyesInfo;
  243. htInitInfo.DeviceResXDPI = (WORD)ppdev->GdiInfo.ulLogPixelsX;
  244. htInitInfo.DeviceResYDPI = (WORD)ppdev->GdiInfo.ulLogPixelsY;
  245. htInitInfo.DevicePelsDPI = (WORD)ppdev->GdiInfo.ulDevicePelsDPI;
  246. if (pca == NULL)
  247. htInitInfo.DefHTColorAdjustment = gcaDefault;
  248. else
  249. htInitInfo.DefHTColorAdjustment = *pca;
  250. if (HT_CreateDeviceHalftoneInfo(&htInitInfo,
  251. (PPDEVICEHALFTONEINFO)&(ppdev->pDevHTInfo)) <= 0L)
  252. {
  253. SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
  254. ppdev->pDevHTInfo = NULL;
  255. return(FALSE);
  256. }
  257. // Check if halftone palette is the same as the device palette.
  258. //
  259. // For now, don't do display devices because dynamic mode changes may
  260. // cause their palette to change at any time.
  261. vHTPalIsDevPal(FALSE);
  262. if (!bDisplayPDEV())
  263. {
  264. XEPALOBJ palSurf(ppalSurf());
  265. if (palHT.bEqualEntries(palSurf))
  266. vHTPalIsDevPal(TRUE);
  267. }
  268. // Keep the halftone palette since this function won't fail.
  269. ((DEVICEHALFTONEINFO *)pDevHTInfo())->DeviceOwnData = (ULONG_PTR)palHT.hpal();
  270. palHT.vSetPID(OBJECT_OWNER_PUBLIC);
  271. palHT.vKeepIt();
  272. return(TRUE);
  273. }
  274. /******************************Member*Function*****************************\
  275. * PDEVOBJ::bDisableHalftone()
  276. *
  277. * Delete the device halftone info structure.
  278. *
  279. * History:
  280. * 07-Nov-1991 -by- Wendy Wu [wendywu]
  281. * Wrote it.
  282. \**************************************************************************/
  283. BOOL PDEVOBJ::bDisableHalftone()
  284. {
  285. ASSERTGDI((pDevHTInfo() != NULL), "bDisableHalftone: DevHTInfo null\n");
  286. DEVICEHALFTONEINFO *pDevHTInfo_ = (DEVICEHALFTONEINFO *)pDevHTInfo();
  287. if (fl(PDEV_ALLOCATEDBRUSHES))
  288. {
  289. for(int iPat = 0; iPat < HS_DDI_MAX; iPat++)
  290. {
  291. bDeleteSurface(ppdev->ahsurf[iPat]);
  292. }
  293. }
  294. ppdev->pDevHTInfo = NULL;
  295. // Delete the halftone palette.
  296. BOOL bStatusPal = bDeletePalette((HPAL)pDevHTInfo_->DeviceOwnData);
  297. BOOL bStatusHT = HT_DestroyDeviceHalftoneInfo(pDevHTInfo_);
  298. return(bStatusPal && bStatusHT);
  299. }
  300. ULONG gaaulPat[HS_DDI_MAX][8] = {
  301. // Scans have to be DWORD aligned:
  302. { 0x00, // ........ HS_HORIZONTAL 0
  303. 0x00, // ........
  304. 0x00, // ........
  305. 0xff, // ********
  306. 0x00, // ........
  307. 0x00, // ........
  308. 0x00, // ........
  309. 0x00 }, // ........
  310. { 0x08, // ....*... HS_VERTICAL 1
  311. 0x08, // ....*...
  312. 0x08, // ....*...
  313. 0x08, // ....*...
  314. 0x08, // ....*...
  315. 0x08, // ....*...
  316. 0x08, // ....*...
  317. 0x08 }, // ....*...
  318. { 0x80, // *....... HS_FDIAGONAL 2
  319. 0x40, // .*......
  320. 0x20, // ..*.....
  321. 0x10, // ...*....
  322. 0x08, // ....*...
  323. 0x04, // .....*..
  324. 0x02, // ......*.
  325. 0x01 }, // .......*
  326. { 0x01, // .......* HS_BDIAGONAL 3
  327. 0x02, // ......*.
  328. 0x04, // .....*..
  329. 0x08, // ....*...
  330. 0x10, // ...*....
  331. 0x20, // ..*.....
  332. 0x40, // .*......
  333. 0x80 }, // *.......
  334. { 0x08, // ....*... HS_CROSS 4
  335. 0x08, // ....*...
  336. 0x08, // ....*...
  337. 0xff, // ********
  338. 0x08, // ....*...
  339. 0x08, // ....*...
  340. 0x08, // ....*...
  341. 0x08 }, // ....*...
  342. { 0x81, // *......* HS_DIAGCROSS 5
  343. 0x42, // .*....*.
  344. 0x24, // ..*..*..
  345. 0x18, // ...**...
  346. 0x18, // ...**...
  347. 0x24, // ..*..*..
  348. 0x42, // .*....*.
  349. 0x81 } // *......*
  350. };
  351. /**************************************************************************\
  352. * PDEVOBJ::bCreateDefaultBrushes()
  353. *
  354. \**************************************************************************/
  355. BOOL PDEVOBJ::bCreateDefaultBrushes()
  356. {
  357. SIZEL sizl;
  358. LONG i;
  359. sizl.cx = 8;
  360. sizl.cy = 8;
  361. for (i = 0; i < HS_DDI_MAX; i++)
  362. {
  363. ppdev->ahsurf[i] = (HSURF) EngCreateBitmap(sizl,
  364. (LONG) sizeof(ULONG),
  365. BMF_1BPP,
  366. BMF_TOPDOWN,
  367. &gaaulPat[i][0]);
  368. if (ppdev->ahsurf[i] == NULL)
  369. {
  370. TRACE_INIT(("Failed bCreateDefaultBrushes - BAD !"));
  371. return(FALSE);
  372. }
  373. }
  374. return(TRUE);
  375. }
  376. /******************************Member*Function*****************************\
  377. * PDEVOBJ::bCreateHalftoneBrushes()
  378. *
  379. * History:
  380. * The standard patterns for the NT/window has following order
  381. *
  382. * Index 0 - Horizontal Line
  383. * Index 1 - Vertical Line
  384. * Index 2 - 45 degree line going up
  385. * Index 3 - 45 degree line going down
  386. * Index 4 - Horizontal/Vertical cross
  387. * Index 5 - 45 degree line up/down cross
  388. * Index 6 - 30 degree line going up
  389. * Index 7 - 30 degree line going down
  390. * Index 8 - 0% Lightness (BLACK)
  391. * Index 9 - 11% Lightness (very light Gray)
  392. * Index 10 - 22% Lightness
  393. * Index 11 - 33% Lightness
  394. * Index 12 - 44% Lightness
  395. * Index 13 - 56% Lightness
  396. * Index 14 - 67% Lightness
  397. * Index 15 - 78% Lightness
  398. * Index 16 - 89% Lightness
  399. * Index 17 - 100% Lightness (White)
  400. * Index 18 - 50% Lightness (GRAY)
  401. *
  402. *Return Value:
  403. *
  404. * return value is total patterns created, if return value is <= 0 then an
  405. * error occurred.
  406. *
  407. *
  408. *Author:
  409. *
  410. * 10-Mar-1992 Tue 20:30:44 created -by- Daniel Chou (danielc)
  411. *
  412. * 24-Nov-1992 -by- Eric Kutter [erick] and DanielChou (danielc)
  413. * moved from printers\lib
  414. \**************************************************************************/
  415. BOOL PDEVOBJ::bCreateHalftoneBrushes()
  416. {
  417. STDMONOPATTERN SMP;
  418. LONG cbPat;
  419. LONG cb2;
  420. INT cPatRet;
  421. static BYTE HTStdPatIndex[HS_DDI_MAX] = {
  422. HT_SMP_HORZ_LINE,
  423. HT_SMP_VERT_LINE,
  424. HT_SMP_DIAG_45_LINE_DOWN,
  425. HT_SMP_DIAG_45_LINE_UP,
  426. HT_SMP_HORZ_VERT_CROSS,
  427. HT_SMP_DIAG_45_CROSS
  428. };
  429. // better initialize the halftone stuff if it isn't already
  430. if ((pDevHTInfo() == NULL) && !bEnableHalftone(NULL))
  431. return(FALSE);
  432. cbPat = (LONG)sizeof(LPBYTE) * (LONG)(HS_DDI_MAX + 1);
  433. // go through all the standard patterns
  434. for(cPatRet = 0; cPatRet < HS_DDI_MAX;)
  435. {
  436. // We will using default 0.01" line width and 10 lines per inch
  437. // halftone default
  438. SMP.Flags = SMP_TOPDOWN;
  439. SMP.ScanLineAlignBytes = BMF_ALIGN_DWORD;
  440. SMP.PatternIndex = HTStdPatIndex[cPatRet];
  441. SMP.LineWidth = 8;
  442. SMP.LinesPerInch = 15;
  443. // Get the cx/cy size of the pattern and total bytes required
  444. // to stored the pattern
  445. SMP.pPattern = NULL; /* To find the size */
  446. if ((cbPat = HT_CreateStandardMonoPattern((PDEVICEHALFTONEINFO)pDevHTInfo(), &SMP)) <= 0)
  447. {
  448. break;
  449. }
  450. //
  451. // create the bitmap
  452. //
  453. DEVBITMAPINFO dbmi;
  454. dbmi.iFormat = BMF_1BPP;
  455. dbmi.cxBitmap = SMP.cxPels;
  456. dbmi.cyBitmap = SMP.cyPels;
  457. dbmi.hpal = (HPALETTE) 0;
  458. dbmi.fl = BMF_TOPDOWN;
  459. SURFMEM SurfDimo;
  460. SurfDimo.bCreateDIB(&dbmi, NULL);
  461. if (!SurfDimo.bValid())
  462. {
  463. break;
  464. }
  465. SurfDimo.vKeepIt();
  466. SurfDimo.vSetPID(OBJECT_OWNER_PUBLIC);
  467. ppdev->ahsurf[cPatRet] = SurfDimo.ps->hsurf();
  468. SMP.pPattern = (PBYTE)SurfDimo.ps->pvBits();
  469. //
  470. // advance the count now so we clean up as appropriate
  471. //
  472. ++cPatRet;
  473. // now set the bits
  474. if ((cb2 = HT_CreateStandardMonoPattern((PDEVICEHALFTONEINFO)pDevHTInfo(), &SMP)) != cbPat)
  475. {
  476. break;
  477. }
  478. }
  479. // if we failed, we had better delete what we created.
  480. if (cPatRet < HS_DDI_MAX)
  481. {
  482. while (cPatRet-- > 0)
  483. {
  484. bDeleteSurface(ppdev->ahsurf[cPatRet]);
  485. }
  486. return(FALSE);
  487. }
  488. setfl(TRUE, PDEV_ALLOCATEDBRUSHES);
  489. return(TRUE);
  490. }
  491. /******************************Public*Routine******************************\
  492. * FLONG flRaster(ulTechnology, flGraphicsCaps)
  493. *
  494. * Computes the appropriate Win3.1 style 'flRaster' flags for the device
  495. * given GDIINFO data.
  496. *
  497. * History:
  498. * 1-Feb-1993 -by- J. Andrew Goossen [andrewgo]
  499. * Wrote it.
  500. *
  501. \**************************************************************************/
  502. FLONG flRaster(ULONG ulTechnology, FLONG flGraphicsCaps)
  503. {
  504. // Flags Win32 never sets:
  505. // -----------------------
  506. //
  507. // RC_BANDING -- Banding is always transparent to programmer
  508. // RC_SCALING -- Special scaling support is never required
  509. // RC_GDI20_OUTPUT -- Win2.0 state blocks in device contexts not supported
  510. // RC_SAVEBITMAP -- Bitmap saving is transparent and SaveScreenBitmap not
  511. // exported
  512. // RC_DEVBITS -- Drivers don't export BitmapBits or SelectBitmap
  513. // Flags Win32 always sets:
  514. // ------------------------
  515. FLONG fl = (RC_BIGFONT | // All devices support fonts > 64k
  516. RC_GDI20_OUTPUT | // We handle most Win 2.0 features
  517. // Set that not-terribly-well documented text flag:
  518. RC_OP_DX_OUTPUT); // Can do opaque ExtTextOuts with dx array
  519. // Line printers and pen plotters can't support any bitmap BitBlt's:
  520. if ((ulTechnology != DT_PLOTTER) && (ulTechnology != DT_CHARSTREAM))
  521. {
  522. fl |= (RC_BITBLT | // Can transfer bitmaps
  523. RC_BITMAP64 | // Can support bitmaps > 64k
  524. RC_DI_BITMAP | // Support SetDIBIts and GetDIBits
  525. RC_DIBTODEV | // Support SetDIBitsToDevice
  526. RC_STRETCHBLT | // Support StretchBlts
  527. RC_STRETCHDIB); // Support SetchDIBits
  528. }
  529. // Printers can't journal FloodFill cals, so only allow raster displays:
  530. if (ulTechnology == DT_RASDISPLAY)
  531. fl |= RC_FLOODFILL;
  532. // Set palette flag from capabilities bit:
  533. if (flGraphicsCaps & GCAPS_PALMANAGED)
  534. fl |= RC_PALETTE;
  535. return(fl);
  536. }
  537. /*
  538. *
  539. * HACK
  540. *
  541. */
  542. LPWSTR
  543. EngGetPrinterDataFileName(
  544. HDEV hdev)
  545. {
  546. return ((PPDEV)hdev)->pwszDataFile;
  547. }
  548. /*
  549. *
  550. * HACK
  551. *
  552. */
  553. LPWSTR
  554. EngGetDriverName(
  555. HDEV hdev)
  556. {
  557. return ((PPDEV)hdev)->pldev->pGdiDriverInfo->DriverName.Buffer;
  558. }
  559. /******************************Public*Routine******************************\
  560. * EngQueryAttribute
  561. *
  562. * This is the engine entry point for device drivers to query device
  563. * attributes.
  564. *
  565. * hDev must always be a valid device.
  566. *
  567. * This call will return TRUE for success and FALSE for failure.
  568. *
  569. * QDA_ACCELERATION_LEVEL:
  570. * pvIn - ignored
  571. * pvInSize - ignored
  572. * pvOut - pointer to DWORD
  573. * pvOutSize - sizeof(DWORD)
  574. *
  575. * The current device acceleration level is returned in pvOut. Please
  576. * see ??? for a discussion of acceleration levels.
  577. *
  578. * NOTE: we should have an enumeration in winddi.h for acceleration
  579. * levels.
  580. *
  581. *
  582. * History:
  583. * 07-Nov-1998 -by- Bart House bhouse
  584. * Wrote it.
  585. \**************************************************************************/
  586. BOOL
  587. EngQueryDeviceAttribute(
  588. HDEV hdev,
  589. ENG_DEVICE_ATTRIBUTE devAttr,
  590. VOID * pvIn,
  591. ULONG ulInSize,
  592. VOID * pvOut,
  593. ULONG ulOutSize)
  594. {
  595. BOOL bResult = FALSE; // assume failure
  596. PPDEV ppdev = (PPDEV) hdev;
  597. if(pvOut != NULL)
  598. {
  599. switch(devAttr)
  600. {
  601. case QDA_ACCELERATION_LEVEL:
  602. if(ulOutSize == sizeof(DWORD))
  603. {
  604. *((DWORD *) pvOut) = ppdev->dwDriverAccelerationLevel;
  605. bResult = TRUE;
  606. }
  607. else
  608. {
  609. WARNING("EngQueryDeviceAttribute -- bad ulOutSize");
  610. }
  611. break;
  612. default:
  613. WARNING("EngQueryDeviceAttribute -- unknown device attribte");
  614. break;
  615. }
  616. }
  617. else
  618. {
  619. WARNING("EngQueryDeviceAttribute -- pvOut is NULL");
  620. }
  621. return bResult;
  622. }
  623. /******************************Member*Function*****************************\
  624. * PDEVOBJ::PDEVOBJ
  625. *
  626. * Create a PDEVOBJ based on given HDEV.
  627. *
  628. * History:
  629. * 1-Apr-1998 -by- Hideyuki Nagase [hideyukn]
  630. * Wrote it.
  631. *
  632. \**************************************************************************/
  633. // Should be in header to share with icmapi.cxx and ddraw.cxx
  634. #define MAX_COLORTABLE 256
  635. PDEVOBJ::PDEVOBJ
  636. (
  637. HDEV hdevOrg,
  638. FLONG fl
  639. )
  640. {
  641. GDIFunctionID(PDEVOBJ::PDEVOBJ<clone>);
  642. INT i;
  643. TRACE_INIT(("PDEVOBJ::PDEVOBJ_: ENTERING\n"));
  644. ppdev = (PDEV *) NULL;
  645. PDEVOBJ pdoOrg(hdevOrg);
  646. //
  647. // Validate input.
  648. //
  649. // 1) Only GCH_CLONE_DISPLAY supported.
  650. // 2) hdevOrg should be valid.
  651. // 3) hdevOrg should be display device.
  652. //
  653. if ((fl != GCH_CLONE_DISPLAY) || (!pdoOrg.bValid()) || (!pdoOrg.bDisplayPDEV()))
  654. {
  655. WARNING("Failed to validate input parameter\n");
  656. return;
  657. }
  658. DEVLOCKOBJ dlo(pdoOrg);
  659. ppdev = (PDEV *) PALLOCMEM(sizeof(PDEV) - sizeof(DWORD) + gdwDirectDrawContext, 'veDG');
  660. if (ppdev == NULL)
  661. {
  662. WARNING("Failed allocation of PDEV\n");
  663. return;
  664. }
  665. PDEV *ppdevOrg = (PDEV *) pdoOrg.hdev();
  666. ppdev->pldev = ppdevOrg->pldev;
  667. ppdev->ppdevParent = ppdev;
  668. ppdev->ulTag = 'Pdev';
  669. PDEVOBJ pdo((HDEV) ppdev);
  670. TRACE_INIT(("PDEVOBJ::PDEVOBJ_: Mirroring original hdev info to clone\n"));
  671. //
  672. // Copy fields which can be copied from original.
  673. //
  674. ppdev->pfnDrvSetPointerShape = ppdevOrg->pfnDrvSetPointerShape; // Accelerator
  675. ppdev->pfnDrvMovePointer = ppdevOrg->pfnDrvMovePointer; // Accelerator
  676. ppdev->pfnMovePointer = ppdevOrg->pfnMovePointer; // Accelerator
  677. ppdev->pfnSync = ppdevOrg->pfnSync; // Accelerator
  678. ppdev->pfnSyncSurface = ppdevOrg->pfnSyncSurface; // Accelerator
  679. ppdev->pfnSetPalette = ppdevOrg->pfnSetPalette;
  680. ppdev->pfnNotify = ppdevOrg->pfnNotify;
  681. ppdev->dhpdev = ppdevOrg->dhpdev;
  682. ppdev->ppalSurf = ppdevOrg->ppalSurf;
  683. ppdev->devinfo = ppdevOrg->devinfo;
  684. ppdev->GdiInfo = ppdevOrg->GdiInfo;
  685. ppdev->hSpooler = ppdevOrg->hSpooler;
  686. ppdev->pDesktopId = ppdevOrg->pDesktopId;
  687. ppdev->pGraphicsDevice = ppdevOrg->pGraphicsDevice;
  688. ppdev->ptlOrigin = ppdevOrg->ptlOrigin;
  689. if (ppdevOrg->ppdevDevmode)
  690. {
  691. DWORD dwSize = ppdevOrg->ppdevDevmode->dmSize +
  692. ppdevOrg->ppdevDevmode->dmDriverExtra;
  693. ppdev->ppdevDevmode = (PDEVMODEW) PALLOCNOZ(dwSize,GDITAG_DEVMODE);
  694. if (ppdev->ppdevDevmode)
  695. {
  696. RtlMoveMemory(ppdev->ppdevDevmode,
  697. ppdevOrg->ppdevDevmode,
  698. dwSize);
  699. }
  700. else
  701. {
  702. goto ERROR_RETURN;
  703. }
  704. }
  705. ppdev->flAccelerated = ppdevOrg->flAccelerated;
  706. ppdev->ptlPointer = ppdevOrg->ptlPointer;
  707. ppdev->hlfntDefault = ppdevOrg->hlfntDefault;
  708. ppdev->hlfntAnsiVariable = ppdevOrg->hlfntAnsiVariable;
  709. ppdev->hlfntAnsiFixed = ppdevOrg->hlfntAnsiFixed;
  710. ppdev->pSurface = ppdevOrg->pSurface;
  711. for (i = 0; i < HS_DDI_MAX; i++)
  712. {
  713. ppdev->ahsurf[i] = ppdevOrg->ahsurf[i];
  714. }
  715. ppdev->pwszDataFile = ppdevOrg->pwszDataFile;
  716. if (ppdevOrg->pvGammaRampTable)
  717. {
  718. ppdev->pvGammaRampTable = (LPVOID) PALLOCNOZ(
  719. MAX_COLORTABLE * sizeof(WORD) * 3,
  720. 'mciG');
  721. if (ppdev->pvGammaRampTable)
  722. {
  723. RtlCopyMemory(ppdev->pvGammaRampTable,
  724. ppdevOrg->pvGammaRampTable,
  725. MAX_COLORTABLE * sizeof(WORD) * 3);
  726. }
  727. else
  728. {
  729. goto ERROR_RETURN;
  730. }
  731. }
  732. ppdev->sizlMeta = ppdevOrg->sizlMeta;
  733. ppdev->pfnUnfilteredBitBlt = ppdevOrg->pfnUnfilteredBitBlt;
  734. ppdev->dwDriverCapableOverride
  735. = ppdevOrg->dwDriverCapableOverride;
  736. ppdev->dwDriverAccelerationLevel
  737. = ppdevOrg->dwDriverAccelerationLevel;
  738. RtlCopyMemory(ppdev->apfn,ppdevOrg->apfn,sizeof(ppdev->apfn));
  739. //
  740. // If the DDI is hooked, we want to make sure that we don't copy
  741. // the Sp function pointers from ppdevOrg, but get the driver function
  742. // pointers from the SPRITESTATE instead. See vSpHook for details.
  743. //
  744. if (pdoOrg.pSpriteState()->bHooked)
  745. {
  746. SPRITESTATE *pState = pdoOrg.pSpriteState();
  747. ppdev->apfn[INDEX_DrvStrokePath] = (PFN) pState->pfnStrokePath;
  748. ppdev->apfn[INDEX_DrvFillPath] = (PFN) pState->pfnFillPath;
  749. ppdev->apfn[INDEX_DrvBitBlt] = (PFN) pState->pfnBitBlt;
  750. ppdev->apfn[INDEX_DrvCopyBits] = (PFN) pState->pfnCopyBits;
  751. ppdev->apfn[INDEX_DrvStretchBlt] = (PFN) pState->pfnStretchBlt;
  752. ppdev->apfn[INDEX_DrvTextOut] = (PFN) pState->pfnTextOut;
  753. ppdev->apfn[INDEX_DrvLineTo] = (PFN) pState->pfnLineTo;
  754. ppdev->apfn[INDEX_DrvTransparentBlt] = (PFN) pState->pfnTransparentBlt;
  755. ppdev->apfn[INDEX_DrvAlphaBlend] = (PFN) pState->pfnAlphaBlend;
  756. ppdev->apfn[INDEX_DrvPlgBlt] = (PFN) pState->pfnPlgBlt;
  757. ppdev->apfn[INDEX_DrvGradientFill] = (PFN) pState->pfnGradientFill;
  758. ppdev->apfn[INDEX_DrvStretchBltROP] = (PFN) pState->pfnStretchBltROP;
  759. ppdev->apfn[INDEX_DrvSaveScreenBits] = (PFN) pState->pfnSaveScreenBits;
  760. ppdev->apfn[INDEX_DrvDrawStream] = (PFN) pState->pfnDrawStream;
  761. }
  762. //
  763. // Set up the fields can not just copied from original.
  764. //
  765. TRACE_INIT(("PDEVOBJ::PDEVOBJ_: Setup new hdev info for clone\n"));
  766. //
  767. // PDEVOBJ.cPdevRefs and PDEVOBJ.cPdevOpenRefs.
  768. //
  769. ppdev->cPdevRefs = 1; // Number of clients.
  770. ppdev->cPdevOpenRefs = 1; // OpenCount
  771. //
  772. // Setup flags.
  773. //
  774. // We only inherit the flag which still has valid in clone, too.
  775. //
  776. ppdev->fl = ppdevOrg->fl & (PDEV_DISPLAY |
  777. PDEV_GAMMARAMP_TABLE |
  778. PDEV_META_DEVICE |
  779. PDEV_DRIVER_PUNTED_CALL);
  780. //
  781. // PDEVOBJ.hsemDevLock
  782. //
  783. if ((ppdev->hsemDevLock = GreCreateSemaphore()) == NULL)
  784. goto ERROR_RETURN;
  785. //
  786. // we now load font info only when needed. The driver still must have
  787. // setup the default font information.
  788. //
  789. bGotFonts(FALSE);
  790. TRACE_INIT(("PDEVOBJ::PDEVOBJ_: Create pointer semaphore\n"));
  791. //
  792. // PDEVOBJ.hsemPoiner
  793. //
  794. ppdev->hsemPointer = GreCreateSemaphore();
  795. if (!ppdev->hsemPointer)
  796. goto ERROR_RETURN;
  797. //
  798. // Enable DirectDraw (for clone).
  799. //
  800. if (!DxDdEnableDirectDraw(pdo.hdev(),FALSE))
  801. goto ERROR_RETURN;
  802. //
  803. // Adjust original pdev as cloned.
  804. //
  805. TRACE_INIT(("PDEVOBJ::PDEVOBJ_: Processing onto new hdev as clone\n"));
  806. //
  807. // Mark new pdev as clone.
  808. //
  809. pdo.bCloneDriver(TRUE);
  810. //
  811. // NOTE: AFTER HERE, ERROR_RETURN COULD NOT BE ALLOWED
  812. //
  813. #ifdef DDI_WATCHDOG
  814. //
  815. // !!! Hack - since watchdog creation requires access to DEVICE_OBJECT now
  816. // we have to delay watchdog creation till hCreateHDEV where PDEV gets associated
  817. // with DEVICE_OBJECT. It would be nice to have it here though.
  818. //
  819. ppdev->pWatchdogData = NULL;
  820. #endif // DDI_WATCHDOG
  821. // PDEVOBJ.ppdevNext.
  822. //
  823. // Finally, everything done, so put this on global list.
  824. //
  825. TRACE_INIT(("PDEVOBJ::PDEVOBJ_: Insert new hdev to global list\n"));
  826. GreAcquireSemaphoreEx(ghsemDriverMgmt, SEMORDER_DRIVERMGMT, NULL);
  827. ppdev->ppdevNext = gppdevList;
  828. gppdevList = ppdev;
  829. GreReleaseSemaphoreEx(ghsemDriverMgmt);
  830. TRACE_INIT(("PDEVOBJ::PDEVOBJ_: LEAVING with success\n"));
  831. return;
  832. ERROR_RETURN:
  833. if (ppdev->hsemDevLock)
  834. {
  835. GreDeleteSemaphore(ppdev->hsemDevLock);
  836. }
  837. if (ppdev->ppdevDevmode)
  838. {
  839. VFREEMEM(ppdev->ppdevDevmode);
  840. }
  841. if (ppdev->pvGammaRampTable)
  842. {
  843. VFREEMEM(ppdev->pvGammaRampTable);
  844. }
  845. DxDdDisableDirectDraw(pdo.hdev(),FALSE);
  846. VFREEMEM(ppdev);
  847. ppdev = (PDEV *) NULL;
  848. TRACE_INIT(("PDEVOBJ::PDEVOBJ_: LEAVING with error\n"));
  849. return;
  850. }
  851. /******************************Member*Function*****************************\
  852. * PDEVOBJ::PDEVOBJ
  853. *
  854. * Allocates and initializes a PDEV, i.e. takes the reference count from
  855. * zero to one.
  856. *
  857. * The object must be completely constructed, otherwise completely destroyed.
  858. *
  859. \**************************************************************************/
  860. PDEVOBJ::PDEVOBJ
  861. (
  862. PLDEV pldev,
  863. PDEVMODEW pdriv,
  864. PWSZ pwszLogAddr,
  865. PWSZ pwszDataFile,
  866. PWSZ pwszDeviceName,
  867. HANDLE hSpool,
  868. PREMOTETYPEONENODE pRemoteTypeOne,
  869. PGDIINFO pMirroredGdiInfo,
  870. PDEVINFO pMirroredDevInfo,
  871. BOOL bUMPD,
  872. DWORD dwCapableOverride,
  873. ULONG dwAccelerationLevel
  874. )
  875. {
  876. GDIFunctionID(PDEVOBJ::PDEVOBJ);
  877. TRACE_INIT(("PDEVOBJ::PDEVOBJ: ENTERING\n"));
  878. if (bUMPD)
  879. {
  880. ppdev = (PDEV *) EngAllocMem(FL_ZERO_MEMORY,sizeof(PDEV) - sizeof(DWORD) + gdwDirectDrawContext, 'veDG');
  881. }
  882. else
  883. {
  884. ppdev = (PDEV *) PALLOCMEM(sizeof(PDEV) - sizeof(DWORD) + gdwDirectDrawContext, 'veDG');
  885. }
  886. if (ppdev == NULL)
  887. {
  888. WARNING("Failed allocation of PDEV\n");
  889. return;
  890. }
  891. ppdev->ppdevParent = ppdev;
  892. ppdev->pldev = pldev;
  893. ppdev->ulTag = 'Pdev';
  894. ppdev->dwDriverCapableOverride = dwCapableOverride;
  895. ppdev->dwDriverAccelerationLevel = dwAccelerationLevel;
  896. TRACE_INIT(("PDEVOBJ::PDEVOBJ: Calling driver to initialize PDEV\n"));
  897. PDEVOBJ pdo((HDEV) ppdev);
  898. //
  899. // Create semaphores so the device can be locked.
  900. //
  901. if (ppdev->pldev->ldevType != LDEV_FONT)
  902. {
  903. ppdev->hsemDevLock = GreCreateSemaphore();
  904. if (!ppdev->hsemDevLock)
  905. goto ERROR_RETURN;
  906. }
  907. if ( dwCapableOverride & DRIVER_NOT_CAPABLE_GDI )
  908. {
  909. //
  910. // If the driver is not capable of GDI, then it is similar to
  911. // DRIVER_ACCELERATIONS_NONE. Reset the level we stored in PDEV
  912. //
  913. ppdev->dwDriverAccelerationLevel = DRIVER_ACCELERATIONS_NONE;
  914. }
  915. //
  916. // fill in the dispatch table. If we've been told to allow no
  917. // driver accelerations, redirect everything to the panning driver,
  918. // which handles this case.
  919. //
  920. if ((ppdev->pldev->ldevType == LDEV_DEVICE_DISPLAY) &&
  921. (dwDriverAccelerationsLevel() == DRIVER_ACCELERATIONS_NONE))
  922. {
  923. //
  924. // Fill in function table with Panning driver versions.
  925. //
  926. bFillFunctionTable(gadrvfnPanning,
  927. gcdrvfnPanning,
  928. &ppdev->apfn[0]);
  929. }
  930. else
  931. {
  932. RtlMoveMemory(&(ppdev->apfn[0]),
  933. &(ppdev->pldev->apfn[0]),
  934. sizeof(PFN) * INDEX_LAST);
  935. }
  936. //
  937. // if we are doing a ResetDC then we need to transfer over remote type 1
  938. // fonts from previous PDEV
  939. //
  940. ppdev->RemoteTypeOne = pRemoteTypeOne;
  941. //
  942. // HACK - temporary
  943. //
  944. ppdev->pwszDataFile = pwszDataFile;
  945. //
  946. // If this is a Mirroring driver, we want to pass in the global GDIINFO
  947. // and DEVINFO as returned by the primary driver.
  948. //
  949. if (pMirroredGdiInfo)
  950. {
  951. ppdev->GdiInfo = *pMirroredGdiInfo;
  952. ppdev->devinfo = *pMirroredDevInfo;
  953. }
  954. //
  955. // Ask the device driver to create a PDEV.
  956. //
  957. UMDHPDEV *pUMdhpdev;
  958. pdo.bUMPD(bUMPD);
  959. if (bUMPD)
  960. {
  961. //
  962. // NOTE: we store the umpdCookie in dhpdev so that we can pass the
  963. // cookie to the UM UMPD layer during DrvEnablePDEV
  964. //
  965. ppdev->dhpdev = (DHPDEV) pldev->umpdCookie;
  966. }
  967. ppdev->dhpdev = pdo.EnablePDEV (
  968. pdriv, // Driver Data.
  969. pwszLogAddr, // Logical Address.
  970. HS_DDI_MAX, // Count of standard patterns.
  971. ppdev->ahsurf, // Buffer for standard patterns
  972. sizeof(GDIINFO), // Size of GdiInfo
  973. &ppdev->GdiInfo, // Buffer for GdiInfo
  974. sizeof(DEVINFO), // Number of bytes in devinfo.
  975. &ppdev->devinfo, // Device info.
  976. (HDEV)ppdev, // Data File
  977. pwszDeviceName, // Device Name
  978. hSpool); // Base driver handle
  979. if (ppdev->dhpdev)
  980. {
  981. TRACE_INIT(("PDEVOBJ::PDEVOBJ: PDEV initialized by the driver\n"));
  982. if (ppdev->pldev->ldevType != LDEV_FONT)
  983. {
  984. //
  985. // Make sure that units are in MicroMeters for HorzSize, VertSize
  986. //
  987. if ( (LONG)ppdev->GdiInfo.ulHorzSize <= 0 )
  988. {
  989. if ( (LONG)ppdev->GdiInfo.ulHorzSize == 0)
  990. {
  991. // Calculate the ulHorzSize using Default DPI.
  992. // Width in mm = (ulHorzRes / DEFAULT_DPI) * 25.4
  993. ppdev->GdiInfo.ulHorzSize = (254 *
  994. (LONG)ppdev->GdiInfo.ulHorzRes) / (10*DEFAULT_DPI);
  995. }
  996. else
  997. ppdev->GdiInfo.ulHorzSize = (ULONG)(-(LONG)ppdev->GdiInfo.ulHorzSize);
  998. }
  999. else
  1000. {
  1001. ppdev->GdiInfo.ulHorzSize *= 1000;
  1002. }
  1003. if ( (LONG)ppdev->GdiInfo.ulVertSize <= 0 )
  1004. {
  1005. if ( (LONG)ppdev->GdiInfo.ulVertSize == 0)
  1006. {
  1007. // Calculate the ulVertSize using Default DPI.
  1008. // Height in mm = (ulVertRes / DEFAULT_DPI) * 25.4
  1009. ppdev->GdiInfo.ulVertSize = (254 *
  1010. (LONG)ppdev->GdiInfo.ulVertRes) / (10*DEFAULT_DPI);
  1011. }
  1012. else
  1013. {
  1014. ppdev->GdiInfo.ulVertSize = (ULONG)(-(LONG)ppdev->GdiInfo.ulVertSize);
  1015. }
  1016. }
  1017. else
  1018. {
  1019. ppdev->GdiInfo.ulVertSize *= 1000;
  1020. }
  1021. //
  1022. // For compatibility, all displays will have constant style
  1023. // values (plus this helps us because we know the values won't
  1024. // change asynchronously because of dynamic mode changes):
  1025. //
  1026. if (ppdev->GdiInfo.ulTechnology == DT_RASDISPLAY)
  1027. {
  1028. ppdev->GdiInfo.xStyleStep = 1;
  1029. ppdev->GdiInfo.yStyleStep = 1;
  1030. ppdev->GdiInfo.denStyleStep = 3;
  1031. }
  1032. else
  1033. {
  1034. #if DBG
  1035. if (ppdev->GdiInfo.xStyleStep == 0)
  1036. WARNING("Device gave xStyleStep of 0");
  1037. if (ppdev->GdiInfo.yStyleStep == 0)
  1038. WARNING("Device gave yStyleStep of 0");
  1039. if (ppdev->GdiInfo.denStyleStep == 0)
  1040. WARNING("Device gave denStyleStep of 0");
  1041. #endif
  1042. }
  1043. //
  1044. // Compute the appropriate raster flags:
  1045. //
  1046. ppdev->GdiInfo.flRaster = flRaster(ppdev->GdiInfo.ulTechnology,
  1047. ppdev->devinfo.flGraphicsCaps);
  1048. TRACE_INIT(("PDEVOBJ::PDEVOBJ: Creating the default palette\n"));
  1049. //
  1050. // The default palette is stored in devinfo in the pdev.
  1051. // This will be the palette we use for the main surface enabled.
  1052. //
  1053. ASSERTGDI(ppdev->devinfo.hpalDefault != 0,
  1054. "ERROR_RETURN devinfo.hpalDefault invalid");
  1055. {
  1056. EPALOBJ palDefault(ppdev->devinfo.hpalDefault);
  1057. ASSERTGDI(palDefault.bValid(), "ERROR_RETURN hpalDefault invalid");
  1058. //
  1059. // Bug #68071: display drivers often set the ulPrimaryOrder
  1060. // field wrong (because of wrong sample code we gave them),
  1061. // which causes red to be switched with blue in halftone
  1062. // colors. We fix this by ignoring the ulPrimaryOrder that they
  1063. // pass us and instead compute it from the Palette.
  1064. //
  1065. // 19-Mar-1999 Fri 12:10:22 updated -by- Daniel Chou (danielc)
  1066. // Many ohter drivers also set ulPrimaryOrder wrong when the
  1067. // surface format >= 16BPP, here we should check for all
  1068. // devices, not just display, so we removed following line
  1069. // that only check for the display. This make it check on
  1070. // every pdev.
  1071. //
  1072. // if (ppdev->GdiInfo.ulTechnology == DT_RASDISPLAY)
  1073. //
  1074. {
  1075. if (!(palDefault.bIsIndexed()))
  1076. {
  1077. //
  1078. // 6 possibilities here: to be safe we should account for all of them.
  1079. // This code can probably be made simpler if we assume that the
  1080. // values of the PRIMARY_ORDER_xxx constants won't change, but it's
  1081. // not that big a deal.
  1082. //
  1083. if ((palDefault.flRed() > palDefault.flGre()) &&
  1084. (palDefault.flRed() > palDefault.flBlu()))
  1085. {
  1086. if (palDefault.flGre() > palDefault.flBlu())
  1087. {
  1088. ppdev->GdiInfo.ulPrimaryOrder = PRIMARY_ORDER_ABC;
  1089. }
  1090. else
  1091. {
  1092. ppdev->GdiInfo.ulPrimaryOrder = PRIMARY_ORDER_ACB;
  1093. }
  1094. }
  1095. else if ((palDefault.flGre() > palDefault.flRed()) &&
  1096. (palDefault.flGre() > palDefault.flBlu()))
  1097. {
  1098. if (palDefault.flRed() > palDefault.flBlu())
  1099. {
  1100. ppdev->GdiInfo.ulPrimaryOrder = PRIMARY_ORDER_BAC;
  1101. }
  1102. else
  1103. {
  1104. ppdev->GdiInfo.ulPrimaryOrder = PRIMARY_ORDER_BCA;
  1105. }
  1106. }
  1107. else
  1108. {
  1109. // Blue must be greatest (leftmost)
  1110. if (palDefault.flRed() > palDefault.flGre())
  1111. {
  1112. ppdev->GdiInfo.ulPrimaryOrder = PRIMARY_ORDER_CAB;
  1113. }
  1114. else
  1115. {
  1116. ppdev->GdiInfo.ulPrimaryOrder = PRIMARY_ORDER_CBA;
  1117. }
  1118. }
  1119. }
  1120. }
  1121. if (ppdev->GdiInfo.flRaster & RC_PALETTE)
  1122. {
  1123. //
  1124. // Attempt to make it palette managed.
  1125. //
  1126. if(!CreateSurfacePal(palDefault,
  1127. PAL_MANAGED,
  1128. ppdev->GdiInfo.ulNumColors,
  1129. ppdev->GdiInfo.ulNumPalReg))
  1130. {
  1131. goto ERROR_RETURN;
  1132. }
  1133. }
  1134. ppalSurf(palDefault.ppalGet());
  1135. //
  1136. // Leave a reference count of 1 on this palette.
  1137. //
  1138. palDefault.ppalSet(NULL);
  1139. }
  1140. //
  1141. // if the driver didn't fill in the brushes, we'll do it.
  1142. //
  1143. // if it's a display driver, we'll overwrite its brushes with our
  1144. // own, regardless of whether it already filled in the brushes or
  1145. // not. Note that it's okay even if a display driver filled in
  1146. // these values -- the driver already had to keep its own copy of
  1147. // the handles and will clean them up at DrvDisablePDEV time.
  1148. // Supplying our own defaults also simplifies GreDynamicModeChange.
  1149. //
  1150. if ( (ppdev->ahsurf[0] == NULL) ||
  1151. (ppdev->pldev->ldevType == LDEV_DEVICE_DISPLAY) ||
  1152. (ppdev->pldev->ldevType == LDEV_DEVICE_MIRROR) )
  1153. {
  1154. TRACE_INIT(("PDEVOBJ::PDEVOBJ: Creating brushes dor the driver\n"));
  1155. if (ppdev->pldev->ldevType == LDEV_DEVICE_PRINTER)
  1156. {
  1157. if (!bCreateHalftoneBrushes())
  1158. goto ERROR_RETURN;
  1159. }
  1160. else
  1161. {
  1162. // WINBUG #55204 2-1-2000 bhouse Look into whether we leak default brushes
  1163. //
  1164. // Andre Vachon
  1165. // 6-6-95 Kernel mode cleanup
  1166. //
  1167. // The old behaviour is the call the halftoneBrushes function
  1168. // It ends up in a bunch of very complex halftoning code that I have
  1169. // no idea what it does.
  1170. // For now, to clean up drivers in kernel mode, replace this call
  1171. // with a simple function that will create the 6 bitmaps just
  1172. // like display drivers did.
  1173. // Where do these ever get cleaned up?!? I see where the
  1174. // halftone brushes get cleaned up, but not these.
  1175. if (!bCreateDefaultBrushes())
  1176. goto ERROR_RETURN;
  1177. }
  1178. }
  1179. //
  1180. // Set the hSpooler first
  1181. //
  1182. hSpooler(hSpool);
  1183. //
  1184. // Create a semaphore of the mouse pointer
  1185. // (only for the driver will handle cursor)
  1186. //
  1187. if ( (ppdev->pldev->ldevType == LDEV_DEVICE_DISPLAY) ||
  1188. (ppdev->pldev->ldevType == LDEV_DEVICE_META) ||
  1189. (ppdev->pldev->ldevType == LDEV_DEVICE_MIRROR) )
  1190. {
  1191. //
  1192. // Mouse pointer accelerators.
  1193. //
  1194. ppdev->pfnDrvMovePointer =
  1195. (PFN_DrvMovePointer) PPFNDRV(pdo,MovePointer);
  1196. ppdev->pfnDrvSetPointerShape =
  1197. (PFN_DrvSetPointerShape) PPFNDRV(pdo,SetPointerShape);
  1198. //
  1199. // Init fmPointer
  1200. //
  1201. SEMOBJ so(ghsemDriverMgmt);
  1202. TRACE_INIT(("PDEVOBJ::PDEVOBJ: Create pointer semaphore\n"));
  1203. ppdev->hsemPointer = GreCreateSemaphore();
  1204. if (!ppdev->hsemPointer)
  1205. goto ERROR_RETURN;
  1206. //
  1207. // Mark the PDEV as a display.
  1208. //
  1209. ppdev->fl |= PDEV_DISPLAY;
  1210. }
  1211. ppdev->pfnSetPalette = PPFNDRV(pdo, SetPalette);
  1212. ppdev->pfnSync = PPFNDRV(pdo, Synchronize);
  1213. ppdev->pfnSyncSurface = PPFNDRV(pdo, SynchronizeSurface);
  1214. ppdev->pfnNotify = PPFNDRV(pdo, Notify);
  1215. //
  1216. // we now load font info only when needed. The driver still must have
  1217. // setup the default font information.
  1218. //
  1219. bGotFonts(FALSE);
  1220. //
  1221. // If any of the LOGFONTs in DEVINFO do not specify a height,
  1222. // substitute the default.
  1223. //
  1224. LONG lHeightDefault = (DEFAULT_POINT_SIZE * ppdev->GdiInfo.ulLogPixelsY) / POINTS_PER_INCH ;
  1225. ENUMLOGFONTEXDVW elfw;
  1226. if ( ppdev->devinfo.lfDefaultFont.lfHeight == 0 )
  1227. ppdev->devinfo.lfDefaultFont.lfHeight = lHeightDefault;
  1228. if ( ppdev->devinfo.lfAnsiVarFont.lfHeight == 0 )
  1229. ppdev->devinfo.lfAnsiVarFont.lfHeight = lHeightDefault;
  1230. if ( ppdev->devinfo.lfAnsiFixFont.lfHeight == 0 )
  1231. ppdev->devinfo.lfAnsiFixFont.lfHeight = lHeightDefault;
  1232. //
  1233. // Create LFONTs from the LOGFONTs in the DEVINFO.
  1234. // the LOGFONTs should become EXTLOGFONTWs
  1235. //
  1236. vConvertLogFontW(&elfw, &(ppdev->devinfo.lfDefaultFont));
  1237. #ifdef FE_SB
  1238. // We are doing away with the concept of default device fonts for display
  1239. // drivers since it doesnt make sense. Assuming this change gets approved
  1240. // I will remove these before SUR ships.
  1241. if ( ppdev->GdiInfo.ulTechnology == DT_RASDISPLAY )
  1242. {
  1243. ppdev->hlfntDefault = STOCKOBJ_SYSFONT;
  1244. }
  1245. else
  1246. #endif
  1247. {
  1248. if ((ppdev->hlfntDefault
  1249. = (HLFONT) hfontCreate(&elfw,
  1250. LF_TYPE_DEVICE_DEFAULT,
  1251. LF_FLAG_STOCK,
  1252. NULL)) == HLFONT_INVALID)
  1253. {
  1254. ppdev->hlfntDefault = STOCKOBJ_SYSFONT;
  1255. }
  1256. else
  1257. {
  1258. //
  1259. // Set to public.
  1260. //
  1261. if (!GreSetLFONTOwner(ppdev->hlfntDefault, OBJECT_OWNER_PUBLIC))
  1262. {
  1263. //
  1264. // If it failed, get rid of the LFONT and resort to System font.
  1265. //
  1266. bDeleteFont(ppdev->hlfntDefault, TRUE);
  1267. ppdev->hlfntDefault = STOCKOBJ_SYSFONT;
  1268. }
  1269. }
  1270. }
  1271. vConvertLogFontW(&elfw, &(ppdev->devinfo.lfAnsiVarFont));
  1272. if ((ppdev->hlfntAnsiVariable
  1273. = (HLFONT) hfontCreate(&elfw,
  1274. LF_TYPE_ANSI_VARIABLE,
  1275. LF_FLAG_STOCK,
  1276. NULL)) == HLFONT_INVALID)
  1277. {
  1278. ppdev->hlfntAnsiVariable = STOCKOBJ_SYSFONT;
  1279. }
  1280. else
  1281. {
  1282. //
  1283. // Set to public.
  1284. //
  1285. if (!GreSetLFONTOwner(ppdev->hlfntAnsiVariable, OBJECT_OWNER_PUBLIC))
  1286. {
  1287. //
  1288. // If it failed, get rid of the LFONT and resort to System font.
  1289. //
  1290. bDeleteFont(ppdev->hlfntAnsiVariable, TRUE);
  1291. ppdev->hlfntAnsiVariable = STOCKOBJ_SYSFONT;
  1292. }
  1293. }
  1294. vConvertLogFontW(&elfw, &(ppdev->devinfo.lfAnsiFixFont));
  1295. if ((ppdev->hlfntAnsiFixed
  1296. = (HLFONT) hfontCreate(&elfw,
  1297. LF_TYPE_ANSI_FIXED,
  1298. LF_FLAG_STOCK,
  1299. NULL)) == HLFONT_INVALID)
  1300. {
  1301. ppdev->hlfntAnsiFixed = STOCKOBJ_SYSFIXEDFONT;
  1302. }
  1303. else
  1304. {
  1305. //
  1306. // Set to public.
  1307. //
  1308. if (!GreSetLFONTOwner(ppdev->hlfntAnsiFixed, OBJECT_OWNER_PUBLIC))
  1309. {
  1310. //
  1311. // If it failed, get rid of the LFONT and resort to System Fixed font.
  1312. //
  1313. bDeleteFont(ppdev->hlfntAnsiFixed, TRUE);
  1314. ppdev->hlfntAnsiFixed = STOCKOBJ_SYSFIXEDFONT;
  1315. }
  1316. }
  1317. #ifdef DRIVER_DEBUG
  1318. LFONTOBJ lfo1(ppdev->hlfntDefault);
  1319. DbgPrint("GRE!PDEVOBJ(): Device default font\n");
  1320. if (lfo1.bValid())
  1321. {
  1322. lfo1.vDump();
  1323. }
  1324. DbgPrint("GRE!PDEVOBJ(): Ansi variable font\n");
  1325. LFONTOBJ lfo2(ppdev->hlfntAnsiVariable);
  1326. if (lfo2.bValid())
  1327. {
  1328. lfo2.vDump();
  1329. }
  1330. DbgPrint("GRE!PDEVOBJ(): Ansi fixed font\n");
  1331. LFONTOBJ lfo3(ppdev->hlfntAnsiFixed);
  1332. if (lfo3.bValid())
  1333. {
  1334. lfo3.vDump();
  1335. }
  1336. #endif
  1337. //
  1338. // (see bInitDefaultGuiFont() in stockfnt.cxx)
  1339. //
  1340. // If we haven't yet computed the adjusted height of the
  1341. // DEFAULT_GUI_FONT stock object, do so now. We couldn't do
  1342. // this during normal stock font initialization because the
  1343. // display driver had not yet been loaded.
  1344. //
  1345. if ( gbFinishDefGUIFontInit &&
  1346. (ppdev->pldev->ldevType == LDEV_DEVICE_DISPLAY) )
  1347. {
  1348. LFONTOBJ lfo(STOCKOBJ_DEFAULTGUIFONT);
  1349. if (lfo.bValid())
  1350. {
  1351. lfo.plfw()->lfHeight = -(LONG)((lfo.plfw()->lfHeight * ppdev->GdiInfo.ulLogPixelsY + 36) / 72);
  1352. }
  1353. gbFinishDefGUIFontInit = FALSE;
  1354. }
  1355. }
  1356. //
  1357. // Initialize the PDEV fields.
  1358. //
  1359. ppdev->cPdevRefs = 1;
  1360. ppdev->cPdevOpenRefs = 1;
  1361. //
  1362. // Before adding a display PDEV to the PDEV list, make sure it's
  1363. // disabled. We do this to protect against GreFlush walking the
  1364. // PDEV list and calling the driver before we've even finished calling
  1365. // DrvEnableSurface. We mark the PDEV as enabled when all initialization
  1366. // is complete.
  1367. //
  1368. if (pdo.bDisplayPDEV())
  1369. {
  1370. pdo.bDisabled(TRUE);
  1371. // Once the pdev has been disabled we can safely update
  1372. // magic colors in an indexed palette. DrvEnableMDEV will
  1373. // update the palette when the display is reenabled.
  1374. vResetSurfacePalette(hdev());
  1375. }
  1376. //
  1377. // Just stick it at the start of the list.
  1378. // Make sure this list is protected by the driver semaphore
  1379. //
  1380. GreAcquireSemaphoreEx(ghsemDriverMgmt, SEMORDER_DRIVERMGMT, NULL);
  1381. ppdev->ppdevNext = gppdevList;
  1382. gppdevList = ppdev;
  1383. GreReleaseSemaphoreEx(ghsemDriverMgmt);
  1384. TRACE_INIT(("PDEVOBJ::PDEVOBJ: list of display pdevs %08lx\n", gppdevList));
  1385. //
  1386. // NOTE after this point, the object will be "permanent" and will
  1387. // end up being destroyed by the destructor
  1388. //
  1389. #ifdef DDI_WATCHDOG
  1390. //
  1391. // !!! Hack - since watchdog creation requires access to DEVICE_OBJECT now
  1392. // we have to delay watchdog creation till hCreateHDEV where PDEV gets associated
  1393. // with DEVICE_OBJECT. It would be nice to have it here though.
  1394. //
  1395. ppdev->pWatchdogData = NULL;
  1396. #endif // DDI_WATCHDOG
  1397. //
  1398. // Inform the driver that the PDEV is complete.
  1399. //
  1400. pdo.CompletePDEV(ppdev->dhpdev,hdev());
  1401. //
  1402. // We will return with success indicated by a non-NULL ppdev.
  1403. //
  1404. return;
  1405. }
  1406. else
  1407. {
  1408. WARNING("Device failed DrvEnablePDEV\n");
  1409. goto ERROR_RETURN;
  1410. }
  1411. ERROR_RETURN:
  1412. if (ppdev->hsemDevLock)
  1413. {
  1414. GreDeleteSemaphore(ppdev->hsemDevLock);
  1415. }
  1416. if (ppdev->pDevHTInfo != NULL)
  1417. {
  1418. bDisableHalftone();
  1419. }
  1420. #if defined(_WIN64)
  1421. vDeleteWOW64HTPATSIZEUSERAllocations();
  1422. #endif
  1423. if (!bUMPD)
  1424. {
  1425. VFREEMEM(ppdev);
  1426. }
  1427. else
  1428. {
  1429. EngFreeMem(ppdev);
  1430. }
  1431. ppdev = (PDEV *) NULL;
  1432. }
  1433. /******************************Member*Function*****************************\
  1434. * PDEVOBJ::cFonts()
  1435. *
  1436. * History:
  1437. * 3-Feb-1994 -by- Gerrit van Wingerden
  1438. * Wrote it.
  1439. \**************************************************************************/
  1440. ULONG PDEVOBJ::cFonts()
  1441. {
  1442. ULONG_PTR id;
  1443. //
  1444. // see if the device already told us how many fonts it has
  1445. //
  1446. if (ppdev->devinfo.cFonts == (ULONG)-1)
  1447. {
  1448. PDEVOBJ pdo(hdev());
  1449. //
  1450. // if not query the device to see how many there are
  1451. //
  1452. if (PPFNDRV(pdo,QueryFont) != NULL)
  1453. {
  1454. ppdev->devinfo.cFonts = (ULONG)(ULONG_PTR)(*PPFNDRV(pdo,QueryFont))(dhpdev(),0,0,&id);
  1455. }
  1456. else
  1457. {
  1458. ppdev->devinfo.cFonts = 0;
  1459. }
  1460. }
  1461. return(ppdev->devinfo.cFonts);
  1462. }
  1463. /******************************Member*Function*****************************\
  1464. * PDEVOBJ::bGetDeviceFonts()
  1465. *
  1466. * History:
  1467. * 27-Jul-1992 -by- Eric Kutter [erick]
  1468. * Wrote it.
  1469. \**************************************************************************/
  1470. BOOL PDEVOBJ::bGetDeviceFonts()
  1471. {
  1472. ASSERTGDI(!bGotFonts(),"PDEVOBJ::bGetDeviceFonts - already gotten\n");
  1473. //
  1474. // mark that we have gotten the fonts.
  1475. //
  1476. bGotFonts(TRUE);
  1477. //
  1478. // need an ldevobj for calling the device
  1479. //
  1480. PDEVOBJ pdo(hdev());
  1481. //
  1482. // compute the number of device fonts
  1483. //
  1484. cFonts();
  1485. //
  1486. // If there are any device fonts, load the device fonts into the public PFT table.
  1487. //
  1488. if (ppdev->devinfo.cFonts)
  1489. {
  1490. DEVICE_PFTOBJ pfto; // get the device font table
  1491. if (!pfto.bLoadFonts(this))
  1492. {
  1493. WARNING("PDEVOBJ(): couldn't load device fonts\n");
  1494. ppdev->devinfo.cFonts = 0;
  1495. }
  1496. }
  1497. return(TRUE);
  1498. }
  1499. /******************************Public*Routine******************************\
  1500. * FilteredBitBlt()
  1501. *
  1502. * This call allows only simple PATCOPY blts down to the driver; the rest
  1503. * are handled by GDI.
  1504. *
  1505. \**************************************************************************/
  1506. BOOL FilteredBitBlt
  1507. (
  1508. SURFOBJ *psoDst,
  1509. SURFOBJ *psoSrc,
  1510. SURFOBJ *psoMsk,
  1511. CLIPOBJ *pco,
  1512. XLATEOBJ *pxlo,
  1513. RECTL *prclDst,
  1514. POINTL *pptlSrc,
  1515. POINTL *pptlMsk,
  1516. BRUSHOBJ *pbo,
  1517. POINTL *pptlBrush,
  1518. ROP4 rop4
  1519. )
  1520. {
  1521. PFN_DrvBitBlt pfnBitBlt = EngBitBlt;
  1522. // Allow only solid color blts and SRCCOPY blts to be accelerated:
  1523. if ((rop4 == 0xcccc) ||
  1524. ((rop4 == 0xf0f0) && (pbo->iSolidColor != 0xffffffff)))
  1525. {
  1526. PDEVOBJ po(psoDst->hdev);
  1527. pfnBitBlt = po.ppdev->pfnUnfilteredBitBlt;
  1528. }
  1529. return(pfnBitBlt(psoDst, psoSrc, psoMsk, pco, pxlo, prclDst, pptlSrc,
  1530. pptlMsk, pbo, pptlBrush, rop4));
  1531. }
  1532. /******************************Public*Routine******************************\
  1533. * PDEVOBJ::vFilterDriverHooks()
  1534. *
  1535. * Disables driver functionality as appropriate. This routine is used to
  1536. * disable buggy functionality in third-party drivers.
  1537. *
  1538. \**************************************************************************/
  1539. VOID PDEVOBJ::vFilterDriverHooks()
  1540. {
  1541. SYSTEM_GDI_DRIVER_INFORMATION* pGdiDriverInfo;
  1542. LPWSTR pDriverName;
  1543. ULONG ulDriverVersion;
  1544. SURFACE* pSurface;
  1545. DWORD dwLevel;
  1546. DWORD dwOverride;
  1547. pGdiDriverInfo = ppdev->pldev->pGdiDriverInfo;
  1548. pSurface = ppdev->pSurface;
  1549. // Only do this for real drivers.
  1550. if (pGdiDriverInfo == NULL)
  1551. {
  1552. return;
  1553. }
  1554. ulDriverVersion = ppdev->pldev->ulDriverVersion;
  1555. // Make 'pDriverName' point after the last backslash in the fully
  1556. // qualified driver name:
  1557. pDriverName = wcsrchr(pGdiDriverInfo->DriverName.Buffer, L'\\');
  1558. if (pDriverName != NULL)
  1559. pDriverName++;
  1560. else
  1561. pDriverName = pGdiDriverInfo->DriverName.Buffer;
  1562. if (!_wcsicmp(pDriverName, L"stbv128.dll"))
  1563. {
  1564. // The STB nVidia driver started falling around build 1796.
  1565. // It falls over in the driver on calls from DrawCaptionButtons/
  1566. // BitBltSysBmp/NtGdiBitBlt. It appears to have a problem when
  1567. // compatible bitmaps are used while DirectDraw is enabled. As
  1568. // of build 1796, we changed DirectDraw so that it initializes
  1569. // the driver a boot time instead of when the first DirectX
  1570. // application is started. This appears to have exposed a bug
  1571. // in the driver with compatible bitmaps while DirectDraw is
  1572. // enabled.
  1573. // Note: The driver we tested where this problem occured is
  1574. // STBV128.dll, version(ulDriverVersion) 131072
  1575. // Note: we also tried to disable DrvEnableDirectDraw. But it seems
  1576. // this is not the right fix. The crash occured as well.
  1577. ppdev->apfn[INDEX_DrvCreateDeviceBitmap] = NULL;
  1578. }
  1579. else if (!_wcsicmp(pDriverName, L"s3disp.dll"))
  1580. {
  1581. // Bug#178375, NT4 driver s3disp crashes on SetPointShape(). It
  1582. // sometimes scans past the end of the pointer buffer.
  1583. ppdev->apfn[INDEX_DrvSetPointerShape] = NULL;
  1584. }
  1585. else if ((!_wcsicmp(pDriverName, L"rrctrl1.dll")) ||
  1586. (!_wcsicmp(pDriverName, L"rrctrl2.dll")) ||
  1587. (!_wcsicmp(pDriverName, L"rrctrl3.dll")) ||
  1588. (!_wcsicmp(pDriverName, L"rrctrl4.dll")) ||
  1589. (!_wcsicmp(pDriverName, L"rrctrl5.dll")) ||
  1590. (!_wcsicmp(pDriverName, L"rrctrl6.dll")))
  1591. {
  1592. // Bug#333453, Quarterdeck/Symantec Rapid Remote driver tries
  1593. // to hook all functionality exported by real display driver,
  1594. // but doesn't support the new NT5 functions. Limit the driver
  1595. // to >= level 2 accelerations (which also disables DFBs, so
  1596. // we don't need to worry about them hooking unsupported functions
  1597. // there as well).
  1598. if (dwDriverAccelerationsLevel() < 2)
  1599. vSetDriverAccelerationsLevel(2);
  1600. }
  1601. if (bDisplayPDEV())
  1602. {
  1603. dwLevel = dwDriverAccelerationsLevel();
  1604. dwOverride = dwDriverCapableOverride();
  1605. if ( dwOverride & DRIVER_NOT_CAPABLE_GDI )
  1606. {
  1607. // If the driver is not capable of GDI, then it is similar to
  1608. // DRIVER_ACCELERATIONS_NONE. Reset the level we stored in PDEV
  1609. dwLevel = DRIVER_ACCELERATIONS_NONE;
  1610. vSetDriverAccelerationsLevel(dwLevel);
  1611. }
  1612. if (dwLevel < DRIVER_ACCELERATIONS_NONE)
  1613. {
  1614. if (dwLevel >= 1)
  1615. {
  1616. // Disable hardware pointers and device bitmaps:
  1617. ppdev->apfn[INDEX_DrvSetPointerShape] = NULL;
  1618. ppdev->apfn[INDEX_DrvCreateDeviceBitmap] = NULL;
  1619. }
  1620. if (dwLevel >= 2)
  1621. {
  1622. // Disable the more sophisticated GDI drawing routines:
  1623. pSurface->flags(pSurface->flags() & ~(HOOK_STRETCHBLT |
  1624. HOOK_PLGBLT |
  1625. HOOK_FILLPATH |
  1626. HOOK_STROKEANDFILLPATH |
  1627. HOOK_LINETO |
  1628. HOOK_STRETCHBLTROP |
  1629. HOOK_TRANSPARENTBLT |
  1630. HOOK_ALPHABLEND |
  1631. HOOK_GRADIENTFILL));
  1632. }
  1633. if (dwLevel >= 3)
  1634. {
  1635. // Disable all DirectDraw and Direct3D accelerations:
  1636. //
  1637. // Handle by DxDdSetAccelLeve().
  1638. }
  1639. if (dwLevel >= 4)
  1640. {
  1641. // The only GDI accelerations we allow here are the base-line
  1642. // GDI accelerations: DrvTextOut, DrvBitBlt, DrvCopyBits, and
  1643. // DrvStrokePath.
  1644. //
  1645. // NOTE: We also specifically allow DrvMovePointer and
  1646. // GCAPS_PANNING in case the driver is panning the
  1647. // display. (It would be bad if the display doesn't
  1648. // pan when the user enables safe mode!)
  1649. pSurface->flags(pSurface->flags() & (SURF_FLAGS |
  1650. HOOK_COPYBITS |
  1651. HOOK_BITBLT |
  1652. HOOK_TEXTOUT |
  1653. HOOK_SYNCHRONIZE |
  1654. HOOK_STROKEPATH));
  1655. ppdev->devinfo.flGraphicsCaps &= (GCAPS_PALMANAGED |
  1656. GCAPS_MONO_DITHER |
  1657. GCAPS_COLOR_DITHER |
  1658. GCAPS_PANNING |
  1659. GCAPS_LAYERED);
  1660. ppdev->devinfo.flGraphicsCaps2 &= (GCAPS2_SYNCFLUSH |
  1661. GCAPS2_SYNCTIMER);
  1662. ppdev->apfn[INDEX_DrvSaveScreenBits] = NULL;
  1663. ppdev->apfn[INDEX_DrvEscape] = NULL;
  1664. ppdev->apfn[INDEX_DrvDrawEscape] = NULL;
  1665. ppdev->apfn[INDEX_DrvResetPDEV] = NULL;
  1666. ppdev->apfn[INDEX_DrvSetPixelFormat] = NULL;
  1667. ppdev->apfn[INDEX_DrvDescribePixelFormat] = NULL;
  1668. ppdev->apfn[INDEX_DrvSwapBuffers] = NULL;
  1669. // Use filtered Blt function.
  1670. ppdev->pfnUnfilteredBitBlt
  1671. = (PFN_DrvBitBlt) ppdev->apfn[INDEX_DrvBitBlt];
  1672. ppdev->apfn[INDEX_DrvBitBlt] = (PFN) FilteredBitBlt;
  1673. }
  1674. if ( dwOverride & DRIVER_NOT_CAPABLE_OPENGL )
  1675. {
  1676. // Disable OpenGL routines here
  1677. ppdev->apfn[INDEX_DrvSetPixelFormat] = NULL;
  1678. ppdev->apfn[INDEX_DrvDescribePixelFormat] = NULL;
  1679. ppdev->apfn[INDEX_DrvSwapBuffers] = NULL;
  1680. }
  1681. //
  1682. // Disable all escapes.
  1683. //
  1684. if ( dwOverride & DRIVER_NOT_CAPABLE_ESCAPE )
  1685. {
  1686. ppdev->apfn[INDEX_DrvEscape] = NULL;
  1687. ppdev->apfn[INDEX_DrvDrawEscape] = NULL;
  1688. }
  1689. // Call DirectDraw to set accel level.
  1690. DxDdSetAccelLevel(hdev(),dwLevel,dwOverride);
  1691. }
  1692. else
  1693. {
  1694. ASSERTGDI(dwLevel == 5,
  1695. "No-accelerations flag should be modified to reflect change");
  1696. // This case was handled by loading the panning driver.
  1697. }
  1698. }
  1699. }
  1700. /******************************Public*Routine******************************\
  1701. * PDEVOBJ::vProfileDriver()
  1702. *
  1703. * Profiles the driver to determine what accelerations it supports.
  1704. *
  1705. * Note that for the multi-mon PDEV, this returns the acceleration
  1706. * capabilities of the primary monitor.
  1707. *
  1708. \**************************************************************************/
  1709. #define PROFILE_DIMENSION 40
  1710. VOID PDEVOBJ::vProfileDriver()
  1711. {
  1712. DEVBITMAPINFO dbmi;
  1713. EBLENDOBJ eBlendObj;
  1714. CLIPOBJ coClip;
  1715. SURFACE* psurfScreen;
  1716. BRUSHOBJ boTransparent;
  1717. BOOL b;
  1718. HSURF hsurf;
  1719. RECTL rclBlt;
  1720. // We only profile display devices. We could actually do this for
  1721. // printer devices as well, but we would have to re-clear the surface
  1722. // after we did our drawing to it.
  1723. if (!bDisplayPDEV())
  1724. return;
  1725. DEVLOCKOBJ dlo(*this);
  1726. psurfScreen = pSurface();
  1727. XEPALOBJ palScreen(ppalSurf());
  1728. XEPALOBJ palRGB(gppalRGB);
  1729. XEPALOBJ palDefault(ppalDefault);
  1730. // We create the surface fairly big to try and get past drivers that
  1731. // create device surfaces only for 'large' bitmaps. To test the
  1732. // driver, we only have to blt a thin strip, though.
  1733. rclBlt.left = 0;
  1734. rclBlt.top = 0;
  1735. rclBlt.right = 16;
  1736. rclBlt.bottom = 1;
  1737. // Fake up a trivial clip object:
  1738. RtlZeroMemory(&coClip, sizeof(coClip));
  1739. coClip.iDComplexity = DC_TRIVIAL;
  1740. coClip.rclBounds = rclBlt;
  1741. // Ignore any random stuff the driver might have set. We're going
  1742. // to verify for ourselves what they support!
  1743. GdiInfo()->flShadeBlend = 0;
  1744. // Check whatever we can using a 32bpp surface:
  1745. {
  1746. SURFMEM SurfDimo;
  1747. EXLATEOBJ xlo32To32;
  1748. EXLATEOBJ xloScreenTo32;
  1749. EXLATEOBJ xlo32ToScreen;
  1750. // Test for per-pixel alpha acceleration.
  1751. dbmi.iFormat = BMF_32BPP;
  1752. dbmi.hpal = palRGB.hpal();
  1753. dbmi.cxBitmap = PROFILE_DIMENSION;
  1754. dbmi.cyBitmap = PROFILE_DIMENSION;
  1755. dbmi.fl = BMF_TOPDOWN;
  1756. if (SurfDimo.bCreateDIB(&dbmi, NULL))
  1757. {
  1758. if ((xlo32To32.bInitXlateObj(NULL, DC_ICM_OFF, palRGB, palRGB,
  1759. palDefault, palDefault, 0, 0, 0)) &&
  1760. (xloScreenTo32.bInitXlateObj(NULL, DC_ICM_OFF, palScreen, palRGB,
  1761. palDefault, palDefault, 0, 0, 0)) &&
  1762. (xlo32ToScreen.bInitXlateObj(NULL, DC_ICM_OFF, palRGB, palScreen,
  1763. palDefault, palDefault, 0, 0, 0)))
  1764. {
  1765. eBlendObj.BlendFunction.BlendOp = AC_SRC_OVER;
  1766. eBlendObj.BlendFunction.BlendFlags = 0;
  1767. eBlendObj.BlendFunction.AlphaFormat = AC_SRC_ALPHA;
  1768. eBlendObj.BlendFunction.SourceConstantAlpha = 0xff;
  1769. eBlendObj.pxloSrcTo32 = xlo32To32.pxlo();
  1770. eBlendObj.pxloDstTo32 = xloScreenTo32.pxlo();
  1771. eBlendObj.pxlo32ToDst = xlo32ToScreen.pxlo();
  1772. vDriverPuntedCall(FALSE);
  1773. b = PPFNGET(*this, AlphaBlend, psurfScreen->flags())
  1774. (psurfScreen->pSurfobj(),
  1775. SurfDimo.ps->pSurfobj(),
  1776. &coClip,
  1777. xlo32ToScreen.pxlo(),
  1778. &rclBlt,
  1779. &rclBlt,
  1780. &eBlendObj);
  1781. if ((b) && (!bDriverPuntedCall()))
  1782. {
  1783. // WARNING("----- Per-pixel accelerated\n");
  1784. GdiInfo()->flShadeBlend |= SB_PIXEL_ALPHA;
  1785. vAccelerated(ACCELERATED_PIXEL_ALPHA);
  1786. }
  1787. }
  1788. }
  1789. // Note that since we didn't apply 'vKeepIt()', the SURFMEM and
  1790. // EXLATEOBJ destructors will clean up.
  1791. }
  1792. // Check whatever we can using a compatible surface:
  1793. hsurf = hsurfCreateCompatibleSurface(hdev(),
  1794. psurfScreen->iFormat(),
  1795. 0,
  1796. PROFILE_DIMENSION,
  1797. PROFILE_DIMENSION,
  1798. TRUE);
  1799. if (hsurf)
  1800. {
  1801. SURFREF sr(hsurf);
  1802. ASSERTGDI(sr.bValid(), "Driver returned invalid surface");
  1803. EXLATEOBJ xloScreenToScreen;
  1804. EXLATEOBJ xloScreenTo32;
  1805. EXLATEOBJ xlo32ToScreen;
  1806. if ((xloScreenToScreen.bInitXlateObj(NULL, DC_ICM_OFF, palScreen, palScreen,
  1807. palDefault, palDefault, 0, 0, 0)) &&
  1808. (xloScreenTo32.bInitXlateObj(NULL, DC_ICM_OFF, palScreen, palRGB,
  1809. palDefault, palDefault, 0, 0, 0)) &&
  1810. (xlo32ToScreen.bInitXlateObj(NULL, DC_ICM_OFF, palRGB, palScreen,
  1811. palDefault, palDefault, 0, 0, 0)))
  1812. {
  1813. // Test for constant-alpha acceleration.
  1814. eBlendObj.BlendFunction.BlendOp = AC_SRC_OVER;
  1815. eBlendObj.BlendFunction.BlendFlags = 0;
  1816. eBlendObj.BlendFunction.AlphaFormat = 0;
  1817. eBlendObj.BlendFunction.SourceConstantAlpha = 0x85;
  1818. eBlendObj.pxloSrcTo32 = xloScreenTo32.pxlo();
  1819. eBlendObj.pxloDstTo32 = xloScreenTo32.pxlo();
  1820. eBlendObj.pxlo32ToDst = xlo32ToScreen.pxlo();
  1821. vDriverPuntedCall(FALSE);
  1822. b = PPFNGET(*this, AlphaBlend, psurfScreen->flags())
  1823. (psurfScreen->pSurfobj(),
  1824. sr.ps->pSurfobj(),
  1825. &coClip,
  1826. xloScreenToScreen.pxlo(),
  1827. &rclBlt,
  1828. &rclBlt,
  1829. &eBlendObj);
  1830. if ((b) && (!bDriverPuntedCall()))
  1831. {
  1832. // WARNING("----- Constant alpha accelerated\n");
  1833. GdiInfo()->flShadeBlend |= SB_CONST_ALPHA;
  1834. vAccelerated(ACCELERATED_CONSTANT_ALPHA);
  1835. }
  1836. }
  1837. // Test for transparent blt acceleration.
  1838. boTransparent.iSolidColor = 1;
  1839. boTransparent.flColorType = 0;
  1840. vDriverPuntedCall(FALSE);
  1841. b = PPFNGET(*this, TransparentBlt, psurfScreen->flags())
  1842. (psurfScreen->pSurfobj(),
  1843. sr.ps->pSurfobj(),
  1844. NULL,
  1845. NULL,
  1846. &rclBlt,
  1847. &rclBlt,
  1848. 1,
  1849. NULL);
  1850. if ((b) && (!bDriverPuntedCall()))
  1851. {
  1852. // WARNING("----- Transparent blt accelerated\n");
  1853. vAccelerated(ACCELERATED_TRANSPARENT_BLT);
  1854. }
  1855. }
  1856. // Cleanup.
  1857. bDeleteSurface(hsurf);
  1858. }
  1859. /******************************Public*Routine******************************\
  1860. * PDEVOBJ::vDisableSurface()
  1861. *
  1862. * Disables the surface for the pdev.
  1863. *
  1864. * Parameters:
  1865. *
  1866. * cutype The CLEANUPTYPE parameter (default value CLEANUP_NONE)
  1867. * is used specify special processing during process cleanup
  1868. * and session cleanup.
  1869. *
  1870. * It may be one of the following values:
  1871. *
  1872. * Value: Description
  1873. *
  1874. * CLEANUP_NONE Default. No special processing.
  1875. *
  1876. * CLEANUP_PROCESS The process cleanup code is used to do
  1877. * special handling of UMPD; during process
  1878. * cleanup it is not necessary or desirable
  1879. * to callback to user-mode to delete
  1880. * user-mode resources.
  1881. *
  1882. * CLEANUP_SESSION The session cleanup (i.e., hydra shutdown)
  1883. * code does special handling of HMGR
  1884. * objects deleted previously by session
  1885. * cleanup code, but for which stale pointer
  1886. * may exist in the PDEV.
  1887. *
  1888. \**************************************************************************/
  1889. VOID PDEVOBJ::vDisableSurface(CLEANUPTYPE cutype)
  1890. {
  1891. TRACE_INIT(("PDEVOBJ::vDisableSurface: ENTERING\n"));
  1892. //
  1893. // Locate the LDEV.
  1894. //
  1895. PDEVOBJ pdo(hdev());
  1896. //
  1897. // Disable the surface. Note we don't have to
  1898. // fix up the palette because it doesn't get
  1899. // reference counted when put in the palette.
  1900. //
  1901. //
  1902. // On clone PDEV, those stuff never be enabled.
  1903. //
  1904. if (!bCloneDriver())
  1905. {
  1906. vDisableSynchronize(hdev());
  1907. }
  1908. vSpDisableSprites(hdev(), cutype);
  1909. //
  1910. // Notify DirectDraw to be disabled.
  1911. //
  1912. DxDdDisableDirectDraw(hdev(),!bCloneDriver());
  1913. if (ppdev->pSurface != NULL)
  1914. {
  1915. SURFREF su(ppdev->pSurface);
  1916. ppdev->pSurface = NULL;
  1917. //
  1918. // Cannot call user-mode driver to delete surface if the user-mode
  1919. // process is gone (i.e., during process or session cleanup).
  1920. //
  1921. if (!pdo.bUMPD() || (cutype == CLEANUP_NONE))
  1922. {
  1923. su.vUnreference();
  1924. (*PPFNDRV(pdo,DisableSurface))(ppdev->dhpdev);
  1925. }
  1926. else
  1927. {
  1928. //
  1929. // If we are here, then this is process or session cleanup
  1930. // and the PDEV is a user-mode driver. Even though the user-mode
  1931. // portions of the surface are cleaned up as part of the user-mode
  1932. // cleanup, we still need to delete the kernel-mode portion of the
  1933. // surface.
  1934. //
  1935. su.bDeleteSurface(cutype);
  1936. }
  1937. }
  1938. TRACE_INIT(("PDEVOBJ::vDisableSurface: LEAVING\n"));
  1939. }
  1940. /******************************Member*Function*****************************\
  1941. * PDEVOBJ::vReferencePdev()
  1942. *
  1943. * Adds a reference to the PDEV.
  1944. *
  1945. \**************************************************************************/
  1946. VOID PDEVOBJ::vReferencePdev()
  1947. {
  1948. GDIFunctionID(PDEVOBJ::vReferencePdev);
  1949. SEMOBJ so(ghsemDriverMgmt);
  1950. ppdev->cPdevRefs++;
  1951. }
  1952. extern "C" void vUnmapRemoteFonts(FONTFILEVIEW *);
  1953. /***************************************************************************\
  1954. *
  1955. * VOID vMarkSurfacesWithHDEV.
  1956. *
  1957. * Sets hdev of all surfaces in Handle table which reference the PDEV passed
  1958. * in to 0.
  1959. *
  1960. \***************************************************************************/
  1961. VOID vMarkSurfacesWithHDEV(PDEV *ppdev)
  1962. {
  1963. SURFACE *pSurface = NULL;
  1964. HOBJ hobj = 0;
  1965. MLOCKFAST mlo; // Take HandleManager lock so HmgSafeNextObjt can be called
  1966. while (pSurface = (SURFACE*)HmgSafeNextObjt(hobj,SURF_TYPE))
  1967. {
  1968. hobj = (HOBJ) pSurface->hGet();
  1969. if (pSurface->hdev() == (HDEV)ppdev)
  1970. {
  1971. KdPrint(("WARNING: Surface (%p) is owned by HDEV (%p). This HDEV is going to be freed\n", pSurface, ppdev));
  1972. pSurface->hdev((HDEV)0);
  1973. }
  1974. }
  1975. }
  1976. /******************************Member*Function*****************************\
  1977. * PDEVOBJ::vUnreferencePdev()
  1978. *
  1979. * Removes a reference to the PDEV. Deletes the PDEV if all references are
  1980. * gone.
  1981. *
  1982. * Parameters:
  1983. *
  1984. * cutype The CLEANUPTYPE parameter (default value CLEANUP_NONE)
  1985. * is used specify special processing during process cleanup
  1986. * and session cleanup.
  1987. *
  1988. * It may be one of the following values:
  1989. *
  1990. * Value: Description
  1991. *
  1992. * CLEANUP_NONE Default. No special processing.
  1993. *
  1994. * CLEANUP_PROCESS The process cleanup code is used to do
  1995. * special handling of UMPD; during process
  1996. * cleanup it is not necessary or desirable
  1997. * to callback to user-mode to delete
  1998. * user-mode resources.
  1999. *
  2000. * CLEANUP_SESSION The session cleanup (i.e., hydra
  2001. * shutdown) code does special handling of
  2002. * HMGR objects deleted previously by session
  2003. * cleanup code, but for which stale pointer
  2004. * may exist in the PDEV (for example, palettes).
  2005. *
  2006. * Note: special session cleanup handling is usually only needed for HMGR
  2007. * objects for which the PDEV has cached a pointer. Objects referenced
  2008. * via a handle are safe if they are locked via the HMGR table (if the
  2009. * object has already been deleted, then the handle is invalid and the
  2010. * lock attempt will fail).
  2011. *
  2012. \**************************************************************************/
  2013. VOID PDEVOBJ::vUnreferencePdev(CLEANUPTYPE cutype)
  2014. {
  2015. GDIFunctionID(PDEVOBJ::vUnreferencePdev);
  2016. HANDLE hSpooler = NULL;
  2017. ULONG cPdevRefs;
  2018. BOOL bUMPD = ppdev->fl & PDEV_UMPD;
  2019. //
  2020. // Decrement reference count and remove from list if last reference.
  2021. // This must be done under the protection of the driver mgmt semaphore.
  2022. //
  2023. GreAcquireSemaphoreEx(ghsemDriverMgmt, SEMORDER_DRIVERMGMT, NULL);
  2024. cPdevRefs = --(ppdev->cPdevRefs);
  2025. if (cPdevRefs == 0)
  2026. {
  2027. TRACE_INIT(("PDEVOBJ::vCommonDelete: destroying a PDEV\n"));
  2028. //
  2029. // Delete it from the list.
  2030. //
  2031. if (gppdevList == ppdev)
  2032. {
  2033. gppdevList = ppdev->ppdevNext;
  2034. }
  2035. else
  2036. {
  2037. PDEV *pp;
  2038. for (pp = gppdevList; pp != NULL; pp = pp->ppdevNext)
  2039. {
  2040. if (pp->ppdevNext == ppdev)
  2041. {
  2042. pp->ppdevNext = ppdev->ppdevNext;
  2043. break;
  2044. }
  2045. }
  2046. }
  2047. #if DBG
  2048. //
  2049. // If this is DDML driver, make sure one other PDEV referecnes
  2050. // this PDEV as parent.
  2051. //
  2052. if (bMetaDriver())
  2053. {
  2054. PDEV *pp;
  2055. for (pp = gppdevList; pp != NULL; pp = pp->ppdevNext)
  2056. {
  2057. if (pp->ppdevParent == ppdev)
  2058. {
  2059. WARNING("Deleting parent PDEV which still used\n");
  2060. }
  2061. }
  2062. }
  2063. #endif
  2064. }
  2065. GreReleaseSemaphoreEx(ghsemDriverMgmt);
  2066. //
  2067. // If last reference, delete the PDEV and its resources. We do this
  2068. // outside of the driver mgmt semaphore because it could cause a
  2069. // deadlock if we need to call back to user-mode (i.e., UMPD).
  2070. //
  2071. if (cPdevRefs == 0)
  2072. {
  2073. //
  2074. // Since we are going to delete this PDEV, there shouldn't be any
  2075. // active RFONTs lying around for this PDEV.
  2076. //
  2077. ASSERTGDI(ppdev->prfntActive == NULL,
  2078. "active rfonts on pdev being deleted!\n");
  2079. //
  2080. // Ordinarily, we would grab the ghsemRFONTList semaphore because
  2081. // we are going to access the RFONT list. However, since we're in
  2082. // the process of tearing down the PDEV, we don't really need to.
  2083. //
  2084. //
  2085. // Delete all the rfonts on the PDEV.
  2086. //
  2087. PRFONT prfnt;
  2088. while ( (prfnt = ppdev->prfntInactive) != (PRFONT) NULL )
  2089. {
  2090. RFONTTMPOBJ rflo(prfnt);
  2091. PFFOBJ pffo(rflo.pPFF());
  2092. ASSERTGDI (
  2093. pffo.bValid(),
  2094. "bad HPFF"
  2095. );
  2096. rflo.bDeleteRFONT(this, &pffo); // bDelete keeps the list head ptrs updated
  2097. }
  2098. //
  2099. // If device fonts exist, remove them
  2100. //
  2101. if ((ppdev->devinfo.cFonts != 0) && bGotFonts())
  2102. {
  2103. PFF *pPFF = 0;
  2104. PFF **ppPFF;
  2105. GreAcquireSemaphoreEx(ghsemPublicPFT, SEMORDER_PUBLICPFT, NULL);
  2106. DEVICE_PFTOBJ pfto;
  2107. pPFF = pfto.pPFFGet(hdev(), &ppPFF);
  2108. if (!pfto.bUnloadWorkhorse(pPFF, ppPFF, ghsemPublicPFT, 0))
  2109. {
  2110. WARNING("couldn't unload device fonts\n");
  2111. }
  2112. }
  2113. //
  2114. // If a type one font list exists dereference it
  2115. //
  2116. if(ppdev->TypeOneInfo)
  2117. {
  2118. PTYPEONEINFO FreeTypeOneInfo;
  2119. FreeTypeOneInfo = NULL;
  2120. GreAcquireFastMutex(ghfmMemory);
  2121. ppdev->TypeOneInfo->cRef -= 1;
  2122. if(!ppdev->TypeOneInfo->cRef)
  2123. {
  2124. //
  2125. // Don't free pool while holding a mutex.
  2126. //
  2127. FreeTypeOneInfo = ppdev->TypeOneInfo;
  2128. }
  2129. GreReleaseFastMutex(ghfmMemory);
  2130. if (FreeTypeOneInfo)
  2131. {
  2132. VFREEMEM(FreeTypeOneInfo);
  2133. }
  2134. }
  2135. //
  2136. // If any remote type one fonts exist free those
  2137. //
  2138. PREMOTETYPEONENODE RemoteTypeOne = ppdev->RemoteTypeOne;
  2139. while(RemoteTypeOne)
  2140. {
  2141. PVOID Tmp = (PVOID) RemoteTypeOne;
  2142. //
  2143. // ulRegionSize and hSpoolerSecure will be stored in the PFM fileview
  2144. //
  2145. RemoteTypeOne->fvPFM.cRefCountFD = 1;
  2146. vUnmapRemoteFonts(&RemoteTypeOne->fvPFM);
  2147. RemoteTypeOne = RemoteTypeOne->pNext;
  2148. VFREEMEM(Tmp);
  2149. WARNING1("Freeing Type1\n");
  2150. }
  2151. //
  2152. // Delete GammaRamp table, if allocated.
  2153. //
  2154. if (ppdev->fl & PDEV_GAMMARAMP_TABLE)
  2155. {
  2156. VFREEMEM(ppdev->pvGammaRampTable);
  2157. }
  2158. if (ppdev->ppdevDevmode)
  2159. {
  2160. VFREEMEM(ppdev->ppdevDevmode);
  2161. }
  2162. if (!bCloneDriver())
  2163. {
  2164. //
  2165. // Destroy the LFONTs.
  2166. //
  2167. if (ppdev->hlfntDefault != STOCKOBJ_SYSFONT)
  2168. bDeleteFont(ppdev->hlfntDefault, TRUE);
  2169. if (ppdev->hlfntAnsiVariable != STOCKOBJ_SYSFONT)
  2170. bDeleteFont(ppdev->hlfntAnsiVariable, TRUE);
  2171. if (ppdev->hlfntAnsiFixed != STOCKOBJ_SYSFIXEDFONT)
  2172. bDeleteFont(ppdev->hlfntAnsiFixed, TRUE);
  2173. //
  2174. // Delete the patterns if they are created by the graphics engine on the
  2175. // behalf of the driver.
  2176. // This is what happends for all display drivers.
  2177. //
  2178. if (ppdev->fl & PDEV_DISPLAY)
  2179. {
  2180. for (int iPat = 0; iPat < HS_DDI_MAX; iPat++)
  2181. {
  2182. bDeleteSurface(ppdev->ahsurf[iPat]);
  2183. }
  2184. }
  2185. }
  2186. //
  2187. // Disable the surface for the pdev.
  2188. //
  2189. vDisableSurface(cutype);
  2190. //
  2191. // Destroy the device halftone info.
  2192. //
  2193. if (ppdev->pDevHTInfo != NULL)
  2194. {
  2195. bDisableHalftone();
  2196. }
  2197. #if defined(_WIN64)
  2198. vDeleteWOW64HTPATSIZEUSERAllocations();
  2199. #endif
  2200. //
  2201. // Nuke the realized gray pattern brush (used to draw the
  2202. // drag rectangles). Normally, the EBRUSHOBJ destructor
  2203. // will decrement the realized brush ref counts. However,
  2204. // the EBRUSHOBJ cached in the PDEV is allocated as part
  2205. // of the PDEV so never invokes a destructor. Therefore,
  2206. // we need to force the realized brushes out explicitly.
  2207. //
  2208. pbo()->vNuke();
  2209. if (!bCloneDriver())
  2210. {
  2211. //
  2212. // Unreference the palette we used for this PDEV.
  2213. //
  2214. // If session cleanup (i.e., Hydra) the palettes are already
  2215. // deleted; therefore, should skip.
  2216. //
  2217. if (cutype != CLEANUP_SESSION)
  2218. {
  2219. if (ppdev->ppalSurf)
  2220. {
  2221. DEC_SHARE_REF_CNT(ppdev->ppalSurf);
  2222. }
  2223. }
  2224. //
  2225. // Disable the driver's PDEV.
  2226. //
  2227. // We do this odd check to ensure that the driver's DrvDisablePDEV
  2228. // address isn't the same as its DrvEnablePDEV address because an
  2229. // early beta NetMeeting driver had a bug where its table entries
  2230. // for INDEX_DrvEnablePDEV and INDEX_DrvDisablePDEV were the same
  2231. // (this was in SP3 before we enabled dynamic mode changes for
  2232. // DDML drivers). We made a change recently (this is still before
  2233. // SP3 has shipped, which enabled the DDML) so that we refuse to
  2234. // load DDML drivers that don't have GCAPS_LAYERRED set -- but we
  2235. // have to load the driver first before we can check GCAPS_LAYERED.
  2236. // So if it doesn't have GCAPS_LAYERED set, we have to unload the
  2237. // driver -- but this old NetMeeting driver had a bad DisablePDEV
  2238. // routine!
  2239. //
  2240. // At any rate, to work around the problem where someone has the
  2241. // beta version of the NetMeeting driver installed (which shipped
  2242. // with the IE4 beta and has the DisablePDEV bug) and then upgrades
  2243. // to retail SP3, we simply don't call the driver's bad DisablePDEV
  2244. // routine. The driver will likely leak memory, but this happens
  2245. // only once per boot and is better than a blue screen.
  2246. //
  2247. if (PPFNDRV((*this),DisablePDEV) != (PFN_DrvDisablePDEV)
  2248. PPFNDRV((*this),EnablePDEV))
  2249. {
  2250. //
  2251. // If the user mode process is gone (i.e, during session
  2252. // or process cleanup), don't callout to user mode.
  2253. //
  2254. if (!bUMPD || (cutype == CLEANUP_NONE))
  2255. (*PPFNDRV((*this),DisablePDEV))(ppdev->dhpdev);
  2256. }
  2257. //
  2258. // Remove the LDEV reference.
  2259. //
  2260. if (!bUMPD)
  2261. ldevUnloadImage(ppdev->pldev);
  2262. else
  2263. UMPD_ldevUnloadImage(ppdev->pldev);
  2264. // If this PDEV referenced an enabled physical device
  2265. // then release its usage for this session.
  2266. if (!bDisabled() && ppdev->pGraphicsDevice != NULL)
  2267. {
  2268. bSetDeviceSessionUsage(ppdev->pGraphicsDevice, FALSE);
  2269. }
  2270. }
  2271. TRACE_INIT(("PDEVOBJ::vCommonDelete: Closing Device handle.\n"));
  2272. if (ppdev->fl & PDEV_PRINTER)
  2273. {
  2274. //
  2275. // note the spool handle so we can close connection outside
  2276. // of the spooler management semaphore
  2277. //
  2278. hSpooler = ppdev->hSpooler;
  2279. }
  2280. #ifdef DDI_WATCHDOG
  2281. //
  2282. // Stop and free all watchdogs.
  2283. //
  2284. GreDeleteWatchdogs(ppdev->pWatchdogData, WD_NUMBER);
  2285. ppdev->pWatchdogData = NULL;
  2286. #endif // DDI_WATCHDOG
  2287. //
  2288. // Free the locks as one of the last steps, in case any of the
  2289. // above decides to try and acquire the locks.
  2290. //
  2291. //
  2292. // If hsemDevLock points "shared devlock", don't delete it.
  2293. //
  2294. if (!(ppdev->fl & PDEV_SHARED_DEVLOCK))
  2295. {
  2296. if (ppdev->hsemDevLock)
  2297. {
  2298. GreDeleteSemaphore(ppdev->hsemDevLock);
  2299. }
  2300. }
  2301. if (ppdev->fl & PDEV_DISPLAY)
  2302. {
  2303. GreDeleteSemaphore(ppdev->hsemPointer);
  2304. }
  2305. // See if there are any surfaces in the handle table still referencing
  2306. // this PDEV. If so mark them such that the bDeleteSurface call will
  2307. // not touch anything which refers the PDEV.
  2308. vMarkSurfacesWithHDEV(ppdev);
  2309. //
  2310. // Free the PDEV.
  2311. //
  2312. if (!bUMPD)
  2313. {
  2314. VFREEMEM(ppdev);
  2315. }
  2316. else
  2317. {
  2318. EngFreeMem(ppdev);
  2319. }
  2320. ppdev = (PDEV *) NULL;
  2321. }
  2322. //
  2323. // this needs to be done outside of the driver management semaphore
  2324. //
  2325. if (!bUMPD && hSpooler)
  2326. {
  2327. ClosePrinter(hSpooler);
  2328. }
  2329. }
  2330. /******************************Member*Function*****************************\
  2331. * PDEVOBJ::vSync()
  2332. *
  2333. * If the surface hooks synchronization then call the hook. Note, if
  2334. * provided we will call DrvSynchronizeSurface otherwise we will call
  2335. * DrvSynchronize.
  2336. *
  2337. \**************************************************************************/
  2338. VOID PDEVOBJ::vSync(
  2339. SURFOBJ* pso,
  2340. RECTL* prcl,
  2341. FLONG fl)
  2342. {
  2343. PSURFACE pSurf = SURFOBJ_TO_SURFACE(pso);
  2344. if(pSurf->flags() & HOOK_SYNCHRONIZE)
  2345. {
  2346. if (!bDisabled())
  2347. {
  2348. FREASSERTGDI(ppdev->pfnSyncSurface || ppdev->pfnSync,
  2349. "Surface has HOOK_SYNCHRONIZE flags, but both ppdev->pfnSyncSurface and ppdev->pfnSync are NULL\n");
  2350. if(ppdev->pfnSyncSurface != NULL)
  2351. (ppdev->pfnSyncSurface)(pso, prcl, fl);
  2352. else
  2353. (ppdev->pfnSync)(pso->dhpdev, prcl);
  2354. }
  2355. }
  2356. }
  2357. /******************************Member*Function*****************************\
  2358. * PDEVOBJ::vNotify()
  2359. *
  2360. * If the driver supplies DrvNotify, then call it.
  2361. *
  2362. \**************************************************************************/
  2363. VOID PDEVOBJ::vNotify(
  2364. ULONG iType,
  2365. PVOID pvData)
  2366. {
  2367. if(ppdev->pfnNotify != NULL)
  2368. {
  2369. (ppdev->pfnNotify)(ppdev->pSurface->pSurfobj(), iType, pvData);
  2370. }
  2371. }
  2372. /******************************Member*Function*****************************\
  2373. * PDEVOBJ::bDisabled()
  2374. *
  2375. * Marks a PDEV as enabled or disabled, and modifies all updates the
  2376. * cached state in all affected DCs.
  2377. *
  2378. * NOTE: This assumes the DEVLOCK is held.
  2379. *
  2380. \**************************************************************************/
  2381. BOOL PDEVOBJ::bDisabled
  2382. (
  2383. BOOL bDisable
  2384. )
  2385. {
  2386. HDEV hdev;
  2387. HOBJ hobj;
  2388. DC *pdc;
  2389. ASSERTGDI(bDisplayPDEV(), "Expected only display devices");
  2390. SETFLAG(bDisable, ppdev->fl, PDEV_DISABLED);
  2391. hdev = (HDEV) ppdev;
  2392. //
  2393. // We have to hold the handle manager lock while we traverse all
  2394. // the handle manager objects.
  2395. //
  2396. MLOCKFAST mo;
  2397. hobj = 0;
  2398. while (pdc = (DC*) HmgSafeNextObjt(hobj, DC_TYPE))
  2399. {
  2400. hobj = (HOBJ) pdc->hGet();
  2401. if ((pdc->dctp() == DCTYPE_DIRECT) &&
  2402. (pdc->hdev() == hdev))
  2403. {
  2404. pdc->bInFullScreen(bDisable);
  2405. }
  2406. }
  2407. return(ppdev->fl & PDEV_DISABLED);
  2408. }
  2409. #if DBG
  2410. /******************************Member*Function*****************************\
  2411. * PDEVOBJ::AssertDevLock()
  2412. *
  2413. * This routine verifies that the DevLock is held.
  2414. *
  2415. \**************************************************************************/
  2416. VOID PDEVOBJ::vAssertDevLock()
  2417. {
  2418. #if !defined(_GDIPLUS_)
  2419. ASSERTGDI(!bDisplayPDEV() ||
  2420. GreIsSemaphoreOwnedByCurrentThread(hsemDevLock()),
  2421. "PDEVOBJ: Devlock not held");
  2422. #endif
  2423. }
  2424. /******************************Member*Function*****************************\
  2425. * PDEVOBJ::AssertNoDevLock()
  2426. *
  2427. * This routine verifies that the DevLock is not held.
  2428. *
  2429. \**************************************************************************/
  2430. VOID PDEVOBJ::vAssertNoDevLock()
  2431. {
  2432. #if !defined(_GDIPLUS_)
  2433. ASSERTGDI(!bDisplayPDEV() ||
  2434. !GreIsSemaphoreOwnedByCurrentThread(hsemDevLock()),
  2435. "PDEVOBJ: Devlock held");
  2436. #endif
  2437. }
  2438. /******************************Member*Function*****************************\
  2439. * PDEVOBJ::AssertDynaLock()
  2440. *
  2441. * This routine verifies that appropriate locks are held before accessing
  2442. * DC fields that may otherwise be changed asynchronously by the dynamic
  2443. * mode-change code.
  2444. *
  2445. \**************************************************************************/
  2446. VOID PDEVOBJ::vAssertDynaLock()
  2447. {
  2448. //
  2449. // One of the following conditions is enough to allow the thread
  2450. // to safely access fields that may be modified by the dyanmic
  2451. // mode changing:
  2452. //
  2453. // 1. It's a non-display device -- this will not change modes;
  2454. // 2. That the USER semaphore is held;
  2455. // 3. That the DEVLOCK is held for this object;
  2456. // 4. That the DEVLOCK is held for this object's parent;
  2457. // 5. That the Palette semaphore is held;
  2458. // 6. That the Handle Manager semaphore is held;
  2459. // 7. That the Pointer semaphore is held;
  2460. // 8. That the driver management semaphore is held;
  2461. // 9. That the parent's pointer Semaphore is held.
  2462. // 10. The pdev is being torn down (i.e., cPdevRefs == 0).
  2463. //
  2464. #if !defined(_GDIPLUS_)
  2465. ASSERTGDI(!bDisplayPDEV() ||
  2466. (ppdev->cPdevRefs == 0) ||
  2467. UserIsUserCritSecIn() ||
  2468. GreIsSemaphoreOwnedByCurrentThread(hsemDevLock()) ||
  2469. GreIsSemaphoreOwnedByCurrentThread(
  2470. ppdev->ppdevParent->hsemDevLock) ||
  2471. GreIsSemaphoreSharedByCurrentThread(ghsemShareDevLock) ||
  2472. GreIsSemaphoreOwnedByCurrentThread(ghsemPalette) ||
  2473. GreIsSemaphoreOwnedByCurrentThread(ghsemHmgr) ||
  2474. GreIsSemaphoreOwnedByCurrentThread(hsemPointer()) ||
  2475. GreIsSemaphoreOwnedByCurrentThread(ghsemDriverMgmt) ||
  2476. ((ppdev->ppdevParent != NULL) &&
  2477. GreIsSemaphoreOwnedByCurrentThread(ppdev->ppdevParent->hsemPointer)),
  2478. "PDEVOBJ: A dynamic mode change lock must be held to access this field");
  2479. #endif
  2480. }
  2481. /******************************Member*Function*****************************\
  2482. * PDEVOBJ::ppfn()
  2483. *
  2484. * This routine verifies that appropriate locks are held before accessing
  2485. * the dispatch table for a PDEV for function pointers that could otherwise
  2486. * be changed asynchronously by a dynamic mode change.
  2487. *
  2488. \**************************************************************************/
  2489. PFN PDEVOBJ::ppfn(ULONG i)
  2490. {
  2491. //
  2492. // Font producers and some types of font consumers are not allowed to
  2493. // do dynamic mode changes. As such, accessing the dispatch table
  2494. // entries specific to those types of drivers does not have to occur
  2495. // under a lock.
  2496. //
  2497. // Note that if this list is expanded, it should also be changed in
  2498. // 'bMatchEnoughForDynamicModeChange':
  2499. //
  2500. if ((i != INDEX_DrvQueryFontCaps) &&
  2501. (i != INDEX_DrvLoadFontFile) &&
  2502. (i != INDEX_DrvQueryFontFile) &&
  2503. (i != INDEX_DrvGetGlyphMode))
  2504. {
  2505. vAssertDynaLock();
  2506. }
  2507. return(ppdev->apfn[i]);
  2508. }
  2509. #endif