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.

1705 lines
39 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. enable.c
  5. Abstract:
  6. Implementation of device and surface related DDI entry points:
  7. DrvEnableDriver
  8. DrvDisableDriver
  9. DrvEnablePDEV
  10. DrvResetPDEV
  11. DrvCompletePDEV
  12. DrvDisablePDEV
  13. DrvEnableSurface
  14. DrvDisableSurface
  15. DrvBitBlt
  16. DrvStretchBlt
  17. DrvDitherColor
  18. DrvEscape
  19. Environment:
  20. Fax driver, kernel mode
  21. Revision History:
  22. 01/09/96 -davidx-
  23. Created it.
  24. mm/dd/yy -author-
  25. description
  26. --*/
  27. #include "faxdrv.h"
  28. #include "forms.h"
  29. #define CLOSE_HANDLE(h) if (!CloseHandle(h)) Error(("CloseHandle failed: %d.\n", GetLastError()))
  30. //
  31. // Our DRVFN table which tells the engine where to find the routines we support.
  32. //
  33. static DRVFN FaxDriverFuncs[] =
  34. {
  35. { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV },
  36. { INDEX_DrvResetPDEV, (PFN) DrvResetPDEV },
  37. { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV },
  38. { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV },
  39. { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface },
  40. { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface },
  41. { INDEX_DrvStartDoc, (PFN) DrvStartDoc },
  42. { INDEX_DrvEndDoc, (PFN) DrvEndDoc },
  43. { INDEX_DrvStartPage, (PFN) DrvStartPage },
  44. { INDEX_DrvSendPage, (PFN) DrvSendPage },
  45. { INDEX_DrvBitBlt, (PFN) DrvBitBlt },
  46. { INDEX_DrvStretchBlt, (PFN) DrvStretchBlt },
  47. { INDEX_DrvCopyBits, (PFN) DrvCopyBits },
  48. { INDEX_DrvDitherColor, (PFN) DrvDitherColor },
  49. { INDEX_DrvEscape, (PFN) DrvEscape },
  50. };
  51. //
  52. // Forward declaration of local functions
  53. //
  54. VOID SelectPrinterForm(PDEVDATA);
  55. BOOL FillDevInfo(PDEVDATA, ULONG, PVOID);
  56. BOOL FillGdiInfo(PDEVDATA, ULONG, PVOID);
  57. VOID FreeDevData(PDEVDATA);
  58. HINSTANCE ghInstance;
  59. BOOL
  60. DllEntryPoint(
  61. HANDLE hModule,
  62. ULONG ulReason,
  63. PCONTEXT pContext
  64. )
  65. /*++
  66. Routine Description:
  67. DLL initialization procedure.
  68. Arguments:
  69. hModule - DLL instance handle
  70. ulReason - Reason for the call
  71. pContext - Pointer to context (not used by us)
  72. Return Value:
  73. TRUE if DLL is initialized successfully, FALSE otherwise.
  74. --*/
  75. {
  76. switch (ulReason)
  77. {
  78. case DLL_PROCESS_ATTACH:
  79. ghInstance = hModule;
  80. break;
  81. case DLL_PROCESS_DETACH:
  82. break;
  83. }
  84. return TRUE;
  85. }
  86. BOOL
  87. DrvQueryDriverInfo(
  88. DWORD dwMode,
  89. PVOID pBuffer,
  90. DWORD cbBuf,
  91. PDWORD pcbNeeded
  92. )
  93. /*++
  94. Routine Description:
  95. Query driver information
  96. Arguments:
  97. dwMode - Specify the information being queried
  98. pBuffer - Points to output buffer
  99. cbBuf - Size of output buffer in bytes
  100. pcbNeeded - Return the expected size of output buffer
  101. Return Value:
  102. TRUE if successful, FALSE if there is an error
  103. --*/
  104. {
  105. switch (dwMode)
  106. {
  107. case DRVQUERY_USERMODE:
  108. Assert(pcbNeeded != NULL);
  109. *pcbNeeded = sizeof(DWORD);
  110. if (pBuffer == NULL || cbBuf < sizeof(DWORD))
  111. {
  112. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  113. return FALSE;
  114. }
  115. *((PDWORD) pBuffer) = TRUE;
  116. return TRUE;
  117. default:
  118. Error(("Unknown dwMode in DrvQueryDriverInfo: %d\n", dwMode));
  119. SetLastError(ERROR_INVALID_PARAMETER);
  120. return FALSE;
  121. }
  122. }
  123. BOOL
  124. DrvEnableDriver(
  125. ULONG iEngineVersion,
  126. ULONG cb,
  127. PDRVENABLEDATA pDrvEnableData
  128. )
  129. /*++
  130. Routine Description:
  131. Implementation of DDI entry point DrvEnableDriver.
  132. Please refer to DDK documentation for more details.
  133. Arguments:
  134. iEngineVersion - Specifies the DDI version number that GDI is written for
  135. cb - Size of the buffer pointed to by pDrvEnableData
  136. pDrvEnableData - Points to an DRVENABLEDATA structure
  137. Return Value:
  138. TRUE if successful, FALSE if there is an error
  139. --*/
  140. {
  141. Verbose(("Entering DrvEnableDriver...\n"));
  142. //
  143. // Make sure we have a valid engine version and
  144. // we're given enough room for the DRVENABLEDATA.
  145. //
  146. if (iEngineVersion < DDI_DRIVER_VERSION_NT4 || cb < sizeof(DRVENABLEDATA)) {
  147. Error(("DrvEnableDriver failed\n"));
  148. SetLastError(ERROR_BAD_DRIVER_LEVEL);
  149. return FALSE;
  150. }
  151. //
  152. // Fill in the DRVENABLEDATA structure for the engine.
  153. //
  154. pDrvEnableData->iDriverVersion = DDI_DRIVER_VERSION_NT4;
  155. pDrvEnableData->c = sizeof(FaxDriverFuncs) / sizeof(DRVFN);
  156. pDrvEnableData->pdrvfn = FaxDriverFuncs;
  157. return TRUE;
  158. }
  159. DHPDEV
  160. DrvEnablePDEV(
  161. PDEVMODE pdm,
  162. PWSTR pLogAddress,
  163. ULONG cPatterns,
  164. HSURF *phsurfPatterns,
  165. ULONG cjGdiInfo,
  166. ULONG *pGdiInfo,
  167. ULONG cjDevInfo,
  168. DEVINFO *pDevInfo,
  169. HDEV hdev,
  170. PWSTR pDeviceName,
  171. HANDLE hPrinter
  172. )
  173. /*++
  174. Routine Description:
  175. Implementation of DDI entry point DrvEnablePDEV.
  176. Please refer to DDK documentation for more details.
  177. Arguments:
  178. pdm - Points to a DEVMODE structure that contains driver data
  179. pLogAddress - Points to the logical address string
  180. cPatterns - Specifies the number of standard patterns
  181. phsurfPatterns - Buffer to hold surface handles to standard patterns
  182. cjGdiInfo - Size of GDIINFO buffer
  183. pGdiInfo - Points to a GDIINFO structure
  184. cjDevInfo - Size of DEVINFO buffer
  185. pDevInfo - Points to a DEVINFO structure
  186. hdev - GDI device handle
  187. pDeviceName - Points to device name string
  188. hPrinter - Spooler printer handle
  189. Return Value:
  190. Driver device handle, NULL if there is an error
  191. --*/
  192. {
  193. PDEVDATA pdev;
  194. #ifndef USERMODE_DRIVER
  195. ULONG ul;
  196. #endif
  197. Verbose(("Entering DrvEnablePDEV...\n"));
  198. //
  199. // Allocate memory for our DEVDATA structure and initialize it
  200. //
  201. if (! (pdev = MemAllocZ(sizeof(DEVDATA)))) {
  202. Error(("Memory allocation failed\n"));
  203. return NULL;
  204. }
  205. pdev->hPrinter = hPrinter;
  206. pdev->bPrintPreview = FALSE;
  207. pdev->hPreviewMapping = NULL;
  208. #ifdef USERMODE_DRIVER
  209. pdev->hPreviewFile = INVALID_HANDLE_VALUE;
  210. #endif
  211. pdev->pTiffPageHeader = NULL;
  212. pdev->pbTiffPageFP = NULL;
  213. pdev->startDevData = pdev;
  214. pdev->endDevData = pdev;
  215. //
  216. // Save and validate DEVMODE information
  217. // start with the driver default
  218. // then merge with the system default
  219. // finally merge with the input devmode
  220. //
  221. if (CurrentVersionDevmode(pdm)) {
  222. memcpy(&pdev->dm, pdm, sizeof(DRVDEVMODE));
  223. //
  224. // NOTE: We now use dmPrintQuality and dmYResolution fields
  225. // to store the resolution measured in dots-per-inch. Add
  226. // the following check as a safety precaution in case older
  227. // DEVMODE is passed to us.
  228. //
  229. if (pdev->dm.dmPublic.dmPrintQuality <= 0 ||
  230. pdev->dm.dmPublic.dmYResolution <= 0)
  231. {
  232. pdev->dm.dmPublic.dmPrintQuality = FAXRES_HORIZONTAL;
  233. pdev->dm.dmPublic.dmYResolution = FAXRES_VERTICAL;
  234. }
  235. //
  236. // Check if we were given a mapping file
  237. //
  238. if (pdev->dm.dmPrivate.szMappingFile[0] != TEXT('\0'))
  239. {
  240. //
  241. // Load the preview file image:
  242. //
  243. // In user mode this is done by - CreateFile(), CreateFileMapping() and MapViewOfFile().
  244. // In kernel mode this is done by - EngLoadModuleForWrite() and EngMapModule().
  245. //
  246. #ifdef USERMODE_DRIVER
  247. //
  248. // First, open the file
  249. //
  250. if ( INVALID_HANDLE_VALUE == (pdev->hPreviewFile = SafeCreateFile(
  251. pdev->dm.dmPrivate.szMappingFile,
  252. GENERIC_READ | GENERIC_WRITE,
  253. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  254. NULL,
  255. OPEN_EXISTING,
  256. FILE_ATTRIBUTE_TEMPORARY,
  257. NULL)) )
  258. {
  259. Error(("Failed opening mapping file.\n"));
  260. }
  261. else
  262. {
  263. //
  264. // Then create a mapping object
  265. //
  266. pdev->hPreviewMapping = CreateFileMapping(
  267. pdev->hPreviewFile, // handle to file
  268. NULL, // security
  269. PAGE_READWRITE, // protection
  270. 0, // high-order DWORD of size
  271. MAX_TIFF_PAGE_SIZE, // low-order DWORD of size
  272. NULL // object name
  273. );
  274. #else
  275. //
  276. // First, load the file image
  277. //
  278. pdev->hPreviewMapping = EngLoadModuleForWrite(pdev->dm.dmPrivate.szMappingFile, 0);
  279. #endif
  280. if (pdev->hPreviewMapping)
  281. {
  282. //
  283. // Now, open a view to the image in our address space
  284. //
  285. #ifdef USERMODE_DRIVER
  286. pdev->pTiffPageHeader = (PMAP_TIFF_PAGE_HEADER) MapViewOfFile(
  287. pdev->hPreviewMapping, // handle to file-mapping object
  288. FILE_MAP_WRITE, // access mode
  289. 0, // high-order DWORD of offset
  290. 0, // low-order DWORD of offset
  291. 0 // number of bytes to map
  292. );
  293. if ( (NULL != pdev->pTiffPageHeader) &&
  294. (sizeof(MAP_TIFF_PAGE_HEADER) == pdev->pTiffPageHeader->cb) )
  295. #else
  296. pdev->pTiffPageHeader =
  297. (PMAP_TIFF_PAGE_HEADER) EngMapModule(pdev->hPreviewMapping, &ul);
  298. if ( (NULL != pdev->pTiffPageHeader) &&
  299. (MAX_TIFF_PAGE_SIZE == ul) &&
  300. (sizeof(MAP_TIFF_PAGE_HEADER) == pdev->pTiffPageHeader->cb) )
  301. #endif
  302. {
  303. //
  304. // Sucess
  305. //
  306. pdev->bPrintPreview = pdev->pTiffPageHeader->bPreview;
  307. pdev->pbTiffPageFP = (LPBYTE) (pdev->pTiffPageHeader + 1);
  308. }
  309. else
  310. {
  311. Error(("Failed opening view.\n"));
  312. #ifdef USERMODE_DRIVER
  313. if (pdev->pTiffPageHeader)
  314. {
  315. UnmapViewOfFile(pdev->pTiffPageHeader);
  316. }
  317. CLOSE_HANDLE(pdev->hPreviewMapping);
  318. CLOSE_HANDLE(pdev->hPreviewFile);
  319. pdev->hPreviewFile = NULL;
  320. #else
  321. EngFreeModule(pdev->hPreviewMapping);
  322. #endif
  323. pdev->hPreviewMapping = NULL;
  324. pdev->pTiffPageHeader = NULL;
  325. }
  326. }
  327. else
  328. {
  329. Error(("Failed mapping file: %s.\n", pdev->dm.dmPrivate.szMappingFile));
  330. #ifdef USERMODE_DRIVER
  331. // Close the file handle
  332. CLOSE_HANDLE(pdev->hPreviewFile);
  333. pdev->hPreviewFile = NULL;
  334. #endif
  335. }
  336. #ifdef USERMODE_DRIVER
  337. }
  338. #endif
  339. }
  340. else
  341. {
  342. Warning(("No mapping file specified.\n"));
  343. }
  344. } else {
  345. Error(("Bad DEVMODE passed to DrvEnablePDEV\n"));
  346. DriverDefaultDevmode(&pdev->dm, NULL, hPrinter);
  347. }
  348. //
  349. // Calculate the paper size information
  350. //
  351. SelectPrinterForm(pdev);
  352. //
  353. // Fill out GDIINFO and DEVINFO structure
  354. //
  355. if (! FillGdiInfo(pdev, cjGdiInfo, pGdiInfo) ||
  356. ! FillDevInfo(pdev, cjDevInfo, pDevInfo))
  357. {
  358. FreeDevData(pdev);
  359. return NULL;
  360. }
  361. //
  362. // Zero out the array of HSURF's so that the engine will
  363. // automatically simulate the standard patterns for us
  364. //
  365. memset(phsurfPatterns, 0, sizeof(HSURF) * cPatterns);
  366. //
  367. // Return a pointer to our DEVDATA structure
  368. //
  369. return (DHPDEV) pdev;
  370. }
  371. BOOL
  372. DrvResetPDEV(
  373. DHPDEV dhpdevOld,
  374. DHPDEV dhpdevNew
  375. )
  376. /*++
  377. Routine Description:
  378. Implementation of DDI entry point DrvResetPDEV.
  379. Please refer to DDK documentation for more details.
  380. Arguments:
  381. phpdevOld - Driver handle to the old device
  382. phpdevNew - Driver handle to the new device
  383. Return Value:
  384. TRUE if successful, FALSE if there is an error
  385. --*/
  386. {
  387. PDEVDATA pdevOld, pdevNew;
  388. Verbose(("Entering DrvResetPDEV...\n"));
  389. //
  390. // Validate both old and new device
  391. //
  392. pdevOld = (PDEVDATA) dhpdevOld;
  393. pdevNew = (PDEVDATA) dhpdevNew;
  394. if (! ValidDevData(pdevOld) || ! ValidDevData(pdevNew)) {
  395. Error(("ValidDevData failed\n"));
  396. SetLastError(ERROR_INVALID_PARAMETER);
  397. return FALSE;
  398. }
  399. Verbose(("Entering DrvResetPDEV...\n"));
  400. //
  401. // Transfer information from old device to new device
  402. //
  403. if (pdevOld->pageCount != 0) {
  404. pdevNew->pageCount = pdevOld->pageCount;
  405. pdevNew->flags |= PDEV_RESETPDEV;
  406. pdevNew->fileOffset = pdevOld->fileOffset;
  407. if (pdevOld->pFaxIFD) {
  408. pdevNew->pFaxIFD = pdevOld->pFaxIFD;
  409. pdevOld->pFaxIFD = NULL;
  410. }
  411. }
  412. //
  413. // Carry over relevant flag bits
  414. //
  415. pdevNew->flags |= pdevOld->flags & PDEV_CANCELLED;
  416. return TRUE;
  417. }
  418. VOID
  419. DrvCompletePDEV(
  420. DHPDEV dhpdev,
  421. HDEV hdev
  422. )
  423. /*++
  424. Routine Description:
  425. Implementation of DDI entry point DrvCompletePDEV.
  426. Please refer to DDK documentation for more details.
  427. Arguments:
  428. dhpdev - Driver device handle
  429. hdev - GDI device handle
  430. Return Value:
  431. NONE
  432. --*/
  433. {
  434. PDEVDATA pdev = (PDEVDATA) dhpdev;
  435. Verbose(("Entering DrvCompletePDEV...\n"));
  436. if (! ValidDevData(pdev)) {
  437. Assert(FALSE);
  438. return;
  439. }
  440. //
  441. // Remember the engine's handle to the physical device
  442. //
  443. pdev->hdev = hdev;
  444. }
  445. HSURF
  446. DrvEnableSurface(
  447. DHPDEV dhpdev
  448. )
  449. /*++
  450. Routine Description:
  451. Implementation of DDI entry point DrvEnableSurface.
  452. Please refer to DDK documentation for more details.
  453. Arguments:
  454. dhpdev - Driver device handle
  455. Return Value:
  456. Handle to newly created surface, NULL if there is an error
  457. --*/
  458. {
  459. PDEVDATA pdev = (PDEVDATA) dhpdev;
  460. FLONG flHooks;
  461. Verbose(("Entering DrvEnableSurface...\n"));
  462. //
  463. // Validate the pointer to our DEVDATA structure
  464. //
  465. if (! ValidDevData(pdev)) {
  466. Error(("ValidDevData failed\n"));
  467. SetLastError(ERROR_INVALID_PARAMETER);
  468. return NULL;
  469. }
  470. //
  471. // Adjust the bitmap size so that we always end up with 1728 pixels per scanline
  472. //
  473. Assert(MAX_WIDTH_PIXELS % DWORDBITS == 0);
  474. if (IsLandscapeMode(pdev)) {
  475. Assert(pdev->imageSize.cy <= MAX_WIDTH_PIXELS);
  476. pdev->imageSize.cy = MAX_WIDTH_PIXELS;
  477. pdev->imageSize.cx = ((pdev->imageSize.cx + (BYTEBITS - 1)) / BYTEBITS) * BYTEBITS;
  478. } else {
  479. Assert(pdev->imageSize.cx <= MAX_WIDTH_PIXELS);
  480. pdev->imageSize.cx = MAX_WIDTH_PIXELS;
  481. }
  482. pdev->lineOffset = PadBitsToBytes(pdev->imageSize.cx, sizeof(DWORD));
  483. //
  484. // Call the engine to create a standard bitmap surface for us
  485. //
  486. pdev->hbitmap = (HSURF) EngCreateBitmap(pdev->imageSize,
  487. pdev->lineOffset,
  488. BMF_1BPP,
  489. BMF_TOPDOWN | BMF_NOZEROINIT | BMF_USERMEM,
  490. NULL);
  491. if (pdev->hbitmap == NULL) {
  492. Error(("EngCreateBitmap failed\n"));
  493. return NULL;
  494. }
  495. //
  496. // Associate the surface with the device and inform the
  497. // engine which functions we have hooked out
  498. //
  499. if (pdev->dm.dmPrivate.flags & FAXDM_NO_HALFTONE)
  500. flHooks = 0;
  501. else
  502. flHooks = (HOOK_STRETCHBLT | HOOK_BITBLT | HOOK_COPYBITS);
  503. EngAssociateSurface(pdev->hbitmap, pdev->hdev, flHooks);
  504. //
  505. // Return the surface handle to the engine
  506. //
  507. return pdev->hbitmap;
  508. }
  509. VOID
  510. DrvDisableSurface(
  511. DHPDEV dhpdev
  512. )
  513. /*++
  514. Routine Description:
  515. Implementation of DDI entry point DrvDisableSurface.
  516. Please refer to DDK documentation for more details.
  517. Arguments:
  518. dhpdev - Driver device handle
  519. Return Value:
  520. NONE
  521. --*/
  522. {
  523. PDEVDATA pdev = (PDEVDATA) dhpdev;
  524. Verbose(("Entering DrvDisableSurface...\n"));
  525. if (! ValidDevData(pdev)) {
  526. Assert(FALSE);
  527. return;
  528. }
  529. //
  530. // Call the engine to delete the surface handle
  531. //
  532. if (pdev->hbitmap != NULL) {
  533. EngDeleteSurface(pdev->hbitmap);
  534. pdev->hbitmap = NULL;
  535. }
  536. }
  537. VOID
  538. DrvDisablePDEV(
  539. DHPDEV dhpdev
  540. )
  541. /*++
  542. Routine Description:
  543. Implementation of DDI entry point DrvDisablePDEV.
  544. Please refer to DDK documentation for more details.
  545. Arguments:
  546. dhpdev - Driver device handle
  547. Return Value:
  548. NONE
  549. --*/
  550. {
  551. PDEVDATA pdev = (PDEVDATA) dhpdev;
  552. Verbose(("Entering DrvDisablePDEV...\n"));
  553. if (! ValidDevData(pdev)) {
  554. Assert(FALSE);
  555. return;
  556. }
  557. //
  558. // Free up memory allocated for the current PDEV
  559. //
  560. FreeDevData(pdev);
  561. }
  562. VOID
  563. DrvDisableDriver(
  564. VOID
  565. )
  566. /*++
  567. Routine Description:
  568. Implementation of DDI entry point DrvDisableDriver.
  569. Please refer to DDK documentation for more details.
  570. Arguments:
  571. NONE
  572. Return Value:
  573. NONE
  574. --*/
  575. {
  576. Verbose(("Entering DrvDisableDriver...\n"));
  577. }
  578. BOOL
  579. IsCompatibleSurface(
  580. SURFOBJ *psoDst,
  581. SURFOBJ *psoSrc,
  582. XLATEOBJ *pxlo
  583. )
  584. /*++
  585. Routine Description:
  586. Check if the source surface is compatible with the destination surface
  587. i.e. we can bitblt without halftonig
  588. Arguments:
  589. psoDst - Specifies the destination surface
  590. psoSrc - Specifies the source surface
  591. pxlo - How to transform colors between the source surface and the destination surface
  592. Return Value:
  593. TRUE if the source surface is compatible with the destination surface
  594. FALSE otherwise
  595. --*/
  596. {
  597. BOOL result;
  598. //
  599. // We know our destination surface is always 1bpp
  600. //
  601. Assert(psoDst->iBitmapFormat == BMF_1BPP);
  602. //
  603. // Check whether the transformation is trivial
  604. //
  605. if (!pxlo || (pxlo->flXlate & XO_TRIVIAL)) {
  606. result = (psoSrc->iBitmapFormat == psoDst->iBitmapFormat);
  607. } else if ((pxlo->flXlate & XO_TABLE) && pxlo->cEntries <= 2) {
  608. ULONG srcPalette[2];
  609. srcPalette[0] = srcPalette[1] = RGB_BLACK;
  610. XLATEOBJ_cGetPalette(pxlo, XO_SRCPALETTE, pxlo->cEntries, srcPalette);
  611. result = (srcPalette[0] == RGB_BLACK || srcPalette[0] == RGB_WHITE) &&
  612. (srcPalette[1] == RGB_BLACK || srcPalette[1] == RGB_WHITE);
  613. } else
  614. result = FALSE;
  615. return result;
  616. }
  617. BOOL
  618. DrvCopyBits(
  619. SURFOBJ *psoTrg,
  620. SURFOBJ *psoSrc,
  621. CLIPOBJ *pco,
  622. XLATEOBJ *pxlo,
  623. RECTL *prclDst,
  624. POINTL *pptlSrc
  625. )
  626. /*++
  627. Routine Description:
  628. Implementation of DDI entry point DrvCopyBits.
  629. We need to hook out this function. Otherwise bitmaps won't be halftoned.
  630. Arguments:
  631. Please refer to DDK documentation for more details.
  632. Return Value:
  633. TRUE if successful, FALSE otherwise
  634. --*/
  635. {
  636. Verbose(("Entering DrvCopyBits ...\n"));
  637. //
  638. // Check if halftoning is necessary
  639. // If not, let the engine handle it
  640. //
  641. if ((psoSrc->iType != STYPE_BITMAP) ||
  642. (psoTrg->iType != STYPE_BITMAP) ||
  643. IsCompatibleSurface(psoTrg, psoSrc, pxlo))
  644. {
  645. return EngCopyBits(psoTrg, psoSrc, pco, pxlo, prclDst, pptlSrc);
  646. }
  647. else
  648. {
  649. POINTL ptlBrushOrg;
  650. RECTL rclDst, rclSrc;
  651. ptlBrushOrg.x = ptlBrushOrg.y = 0;
  652. rclDst = *prclDst;
  653. rclSrc.left = pptlSrc->x;
  654. rclSrc.top = pptlSrc->y;
  655. rclSrc.right = rclSrc.left + (rclDst.right - rclDst.left);
  656. rclSrc.bottom = rclSrc.top + (rclDst.bottom - rclDst.top);
  657. if ((rclSrc.right > psoSrc->sizlBitmap.cx) ||
  658. (rclSrc.bottom > psoSrc->sizlBitmap.cy))
  659. {
  660. rclSrc.right = psoSrc->sizlBitmap.cx;
  661. rclSrc.bottom = psoSrc->sizlBitmap.cy;
  662. rclDst.right = rclDst.left + (rclSrc.right - rclSrc.left);
  663. rclDst.bottom = rclDst.top + (rclSrc.bottom - rclSrc.top);
  664. }
  665. return EngStretchBlt(psoTrg,
  666. psoSrc,
  667. NULL,
  668. pco,
  669. pxlo,
  670. &DefHTClrAdj,
  671. &ptlBrushOrg,
  672. &rclDst,
  673. &rclSrc,
  674. NULL,
  675. HALFTONE);
  676. }
  677. }
  678. BOOL
  679. DrvBitBlt(
  680. SURFOBJ *psoTrg,
  681. SURFOBJ *psoSrc,
  682. SURFOBJ *psoMask,
  683. CLIPOBJ *pco,
  684. XLATEOBJ *pxlo,
  685. RECTL *prclTrg,
  686. POINTL *pptlSrc,
  687. POINTL *pptlMask,
  688. BRUSHOBJ *pbo,
  689. POINTL *pptlBrush,
  690. ROP4 rop4
  691. )
  692. /*++
  693. Routine Description:
  694. Implementation of DDI entry point DrvBitBlt.
  695. We need to hook out this function. Otherwise bitmaps won't be halftoned.
  696. Arguments:
  697. Please refer to DDK documentation for more details.
  698. Return Value:
  699. TRUE if successful, FALSE otherwise
  700. --*/
  701. {
  702. COLORADJUSTMENT *pca;
  703. PDEVDATA pdev;
  704. DWORD rop3Foreground, rop3Background;
  705. SURFOBJ *psoNewSrc;
  706. HBITMAP hbmpNewSrc;
  707. POINTL brushOrg;
  708. BOOL result;
  709. Verbose(("Entering DrvBitBlt...\n"));
  710. //
  711. // Validate input parameters
  712. //
  713. Assert(psoTrg != NULL);
  714. pdev = (PDEVDATA) psoTrg->dhpdev;
  715. if (! ValidDevData(pdev)) {
  716. Error(("ValidDevData failed\n"));
  717. SetLastError(ERROR_INVALID_PARAMETER);
  718. return FALSE;
  719. }
  720. //
  721. // Use the system default color adjustment information
  722. //
  723. pca = &DefHTClrAdj;
  724. //
  725. // Figure out the foreground and background ROP3
  726. //
  727. psoNewSrc = NULL;
  728. hbmpNewSrc = NULL;
  729. rop3Foreground = GetForegroundRop3(rop4);
  730. rop3Background = GetBackgroundRop3(rop4);
  731. if ((Rop3NeedPattern(rop3Foreground) || Rop3NeedPattern(rop3Background)) && pptlBrush) {
  732. brushOrg = *pptlBrush;
  733. } else {
  734. brushOrg.x = brushOrg.y = 0;
  735. }
  736. //
  737. // If a source bitmap is involved in the raster operation and
  738. // the source is not compatible with the destination surface,
  739. // then we'll halftone the source bitmap into a new bitmap and
  740. // bitblt the new bitmap onto the destination surface.
  741. //
  742. if ((Rop3NeedSource(rop3Foreground) || Rop3NeedSource(rop3Background)) &&
  743. !IsCompatibleSurface(psoTrg, psoSrc, pxlo))
  744. {
  745. RECTL rclNewSrc, rclOldSrc;
  746. SIZEL bmpSize;
  747. LONG lDelta;
  748. rclNewSrc.left = rclNewSrc.top = 0;
  749. rclNewSrc.right = prclTrg->right - prclTrg->left;
  750. rclNewSrc.bottom = prclTrg->bottom - prclTrg->top;
  751. rclOldSrc.left = pptlSrc->x;
  752. rclOldSrc.top = pptlSrc->y;
  753. rclOldSrc.right = rclOldSrc.left + rclNewSrc.right;
  754. rclOldSrc.bottom = rclOldSrc.top + rclNewSrc.bottom;
  755. //
  756. // Express path for the most common case: SRCCOPY
  757. //
  758. if (rop4 == 0xcccc) {
  759. return EngStretchBlt(psoTrg,
  760. psoSrc,
  761. psoMask,
  762. pco,
  763. pxlo,
  764. pca,
  765. &brushOrg,
  766. prclTrg,
  767. &rclOldSrc,
  768. pptlMask,
  769. HALFTONE);
  770. }
  771. //
  772. // Modify the brush origin, because when we blt to the clipped bitmap
  773. // the origin is at bitmap's (0, 0) minus the original location
  774. //
  775. brushOrg.x -= prclTrg->left;
  776. brushOrg.y -= prclTrg->top;
  777. //
  778. // Create a temporary bitmap surface
  779. // Halftone the source bitmap into the temporary bitmap
  780. //
  781. Assert(psoTrg->iBitmapFormat == BMF_1BPP);
  782. bmpSize.cx = rclNewSrc.right;
  783. bmpSize.cy = rclNewSrc.bottom;
  784. lDelta = PadBitsToBytes(bmpSize.cx, sizeof(DWORD));
  785. if (! (hbmpNewSrc = EngCreateBitmap(bmpSize,
  786. lDelta,
  787. BMF_1BPP,
  788. BMF_TOPDOWN | BMF_NOZEROINIT,
  789. NULL)) ||
  790. ! EngAssociateSurface((HSURF) hbmpNewSrc, pdev->hdev, 0) ||
  791. ! (psoNewSrc = EngLockSurface((HSURF) hbmpNewSrc)) ||
  792. ! EngStretchBlt(psoNewSrc,
  793. psoSrc,
  794. NULL,
  795. NULL,
  796. pxlo,
  797. pca,
  798. &brushOrg,
  799. &rclNewSrc,
  800. &rclOldSrc,
  801. NULL,
  802. HALFTONE))
  803. {
  804. if (psoNewSrc)
  805. EngUnlockSurface(psoNewSrc);
  806. if (hbmpNewSrc)
  807. EngDeleteSurface((HSURF) hbmpNewSrc);
  808. return FALSE;
  809. }
  810. //
  811. // Proceed to bitblt from the temporary bitmap to the destination
  812. //
  813. psoSrc = psoNewSrc;
  814. pptlSrc = (PPOINTL) &rclNewSrc.left;
  815. pxlo = NULL;
  816. brushOrg.x = brushOrg.y = 0;
  817. }
  818. //
  819. // Let engine do the work
  820. //
  821. result = EngBitBlt(psoTrg,
  822. psoSrc,
  823. psoMask,
  824. pco,
  825. pxlo,
  826. prclTrg,
  827. pptlSrc,
  828. pptlMask,
  829. pbo,
  830. &brushOrg,
  831. rop4);
  832. //
  833. // Clean up properly before returning
  834. //
  835. if (psoNewSrc)
  836. EngUnlockSurface(psoNewSrc);
  837. if (hbmpNewSrc)
  838. EngDeleteSurface((HSURF) hbmpNewSrc);
  839. return result;
  840. }
  841. BOOL
  842. DrvStretchBlt(
  843. SURFOBJ *psoDest,
  844. SURFOBJ *psoSrc,
  845. SURFOBJ *psoMask,
  846. CLIPOBJ *pco,
  847. XLATEOBJ *pxlo,
  848. COLORADJUSTMENT *pca,
  849. POINTL *pptlBrushOrg,
  850. RECTL *prclDest,
  851. RECTL *prclSrc,
  852. POINTL *pptlMask,
  853. ULONG iMode
  854. )
  855. /*++
  856. Routine Description:
  857. Implementation of DDI entry point DrvDisableDriver.
  858. We need to hook out this function. Otherwise bitmaps won't be halftoned.
  859. Arguments:
  860. Please refer to DDK documentation for more details.
  861. Return Value:
  862. TRUE if successful, FALSE if there is an error
  863. --*/
  864. {
  865. Verbose(("Entering DrvStretchBlt...\n"));
  866. //
  867. // If no color adjustment information is provided, use the system default
  868. //
  869. if (pca == NULL)
  870. pca = &DefHTClrAdj;
  871. //
  872. // Let engine do the work; make sure halftone is enabled
  873. //
  874. return EngStretchBlt(psoDest,
  875. psoSrc,
  876. psoMask,
  877. pco,
  878. pxlo,
  879. pca,
  880. pptlBrushOrg,
  881. prclDest,
  882. prclSrc,
  883. pptlMask,
  884. HALFTONE);
  885. }
  886. ULONG
  887. DrvDitherColor(
  888. DHPDEV dhpdev,
  889. ULONG iMode,
  890. ULONG rgb,
  891. ULONG *pul
  892. )
  893. /*++
  894. Routine Description:
  895. Implementation of DDI entry point DrvDisableDriver.
  896. Please refer to DDK documentation for more details.
  897. Arguments:
  898. dhpdev - Driver device handle
  899. iMode - Determines the palette to dither against
  900. rgb - Specifies the RGB color that is to be dithered
  901. pul - Points to a memory location in which the dithering information is to be recorded
  902. Return Value:
  903. DCR_HALFTONE to indicate that the engine should create a halftone
  904. approximation for the driver.
  905. --*/
  906. {
  907. return DCR_HALFTONE;
  908. }
  909. BOOL
  910. FillDevInfo(
  911. PDEVDATA pdev,
  912. ULONG cb,
  913. PVOID pdevinfo
  914. )
  915. /*++
  916. Routine Description:
  917. Fill in the DEVINFO structure pointed to by pdevinfo.
  918. Arguments:
  919. pdev - Pointer to our DEVDATA structure
  920. cb - Size of structure pointed to by pdevinfo
  921. pdevinfo - Pointer to DEVINFO structure
  922. [Notes:]
  923. Since we have to worry about not writing out more than cb bytes to
  924. pdevinfo, we will first fill in a local buffer, then copy cb bytes
  925. to pdevinfo.
  926. Return Value:
  927. TRUE if successful. FALSE otherwise.
  928. --*/
  929. {
  930. static ULONG paletteColors[2] = {
  931. RGB_BLACK,
  932. RGB_WHITE,
  933. };
  934. DEVINFO devinfo;
  935. memset(&devinfo, 0, sizeof(devinfo));
  936. //
  937. // Fill in the graphics capabilities flags: we let the engine
  938. // do almost everything. Also, we have to tell the engine not
  939. // to do metafile spooling because we hook out DrvDocumentEvent.
  940. //
  941. devinfo.flGraphicsCaps = GCAPS_HALFTONE |
  942. GCAPS_MONO_DITHER |
  943. GCAPS_COLOR_DITHER |
  944. GCAPS_DONTJOURNAL;
  945. //
  946. // No device fonts
  947. //
  948. devinfo.cFonts = 0;
  949. //
  950. // Black and white palette: entry 0 is black and entry 1 is white
  951. //
  952. if (! (pdev->hpal = EngCreatePalette(PAL_INDEXED, 2, paletteColors, 0, 0, 0))) {
  953. Error(("EngCreatePalette failed\n"));
  954. return FALSE;
  955. }
  956. devinfo.hpalDefault = pdev->hpal;
  957. devinfo.iDitherFormat = BMF_1BPP;
  958. devinfo.cxDither = devinfo.cyDither = 4;
  959. //
  960. // Copy cb bytes from devinfo structure into the caller-provided buffer
  961. //
  962. if (cb > sizeof(devinfo))
  963. {
  964. memset(pdevinfo, 0, cb);
  965. memcpy(pdevinfo, &devinfo, sizeof(devinfo));
  966. }
  967. else
  968. memcpy(pdevinfo, &devinfo, cb);
  969. return TRUE;
  970. }
  971. BOOL
  972. FillGdiInfo(
  973. PDEVDATA pdev,
  974. ULONG cb,
  975. PVOID pgdiinfo
  976. )
  977. /*++
  978. Routine Description:
  979. Fill in the device capabilities information for the engine.
  980. Arguments:
  981. pdev - Pointer to DEVDATA structure
  982. cb - Size of buffer pointed to by pgdiinfo
  983. pgdiinfo - Pointer to a GDIINFO buffer
  984. Return Value:
  985. NONE
  986. --*/
  987. {
  988. GDIINFO gdiinfo;
  989. LONG maxRes;
  990. memset(&gdiinfo, 0, sizeof(gdiinfo));
  991. //
  992. // This field doesn't seem to have any effect for printer drivers.
  993. // Put our driver version number in there anyway.
  994. //
  995. gdiinfo.ulVersion = DRIVER_VERSION;
  996. //
  997. // We're raster printers
  998. //
  999. gdiinfo.ulTechnology = DT_RASPRINTER;
  1000. //
  1001. // Width and height of the imageable area measured in microns.
  1002. // Remember to turn on the sign bit.
  1003. //
  1004. gdiinfo.ulHorzSize = - (pdev->imageArea.right - pdev->imageArea.left);
  1005. gdiinfo.ulVertSize = - (pdev->imageArea.bottom - pdev->imageArea.top);
  1006. //
  1007. // Convert paper size and imageable area from microns to pixels
  1008. //
  1009. pdev->paperSize.cx = MicronToPixel(pdev->paperSize.cx, pdev->xres);
  1010. pdev->paperSize.cy = MicronToPixel(pdev->paperSize.cy, pdev->yres);
  1011. pdev->imageArea.left = MicronToPixel(pdev->imageArea.left, pdev->xres);
  1012. pdev->imageArea.right = MicronToPixel(pdev->imageArea.right, pdev->xres);
  1013. pdev->imageArea.top = MicronToPixel(pdev->imageArea.top, pdev->yres);
  1014. pdev->imageArea.bottom = MicronToPixel(pdev->imageArea.bottom, pdev->yres);
  1015. pdev->imageSize.cx = pdev->imageArea.right - pdev->imageArea.left;
  1016. pdev->imageSize.cy = pdev->imageArea.bottom - pdev->imageArea.top;
  1017. //
  1018. // Width and height of the imageable area measured in device pixels
  1019. //
  1020. gdiinfo.ulHorzRes = pdev->imageSize.cx;
  1021. gdiinfo.ulVertRes = pdev->imageSize.cy;
  1022. //
  1023. // Color depth information
  1024. //
  1025. gdiinfo.cBitsPixel = 1;
  1026. gdiinfo.cPlanes = 1;
  1027. gdiinfo.ulNumColors = 2;
  1028. //
  1029. // Resolution information
  1030. //
  1031. gdiinfo.ulLogPixelsX = pdev->xres;
  1032. gdiinfo.ulLogPixelsY = pdev->yres;
  1033. //
  1034. // Win31 compatible text capability flags. Are they still used by anyone?
  1035. //
  1036. gdiinfo.flTextCaps = 0;
  1037. //
  1038. // Device pixel aspect ratio
  1039. //
  1040. gdiinfo.ulAspectX = pdev->yres;
  1041. gdiinfo.ulAspectY = pdev->xres;
  1042. gdiinfo.ulAspectXY = CalcHypot(pdev->xres, pdev->yres);
  1043. //
  1044. // Dotted line appears to be approximately 25dpi
  1045. // We assume either xres is a multiple of yres or yres is a multiple of xres
  1046. //
  1047. maxRes = max(pdev->xres, pdev->yres);
  1048. Assert((maxRes % pdev->xres) == 0 && (maxRes % pdev->yres == 0));
  1049. gdiinfo.xStyleStep = maxRes / pdev->xres;
  1050. gdiinfo.yStyleStep = maxRes / pdev->yres;
  1051. gdiinfo.denStyleStep = maxRes / 25;
  1052. //
  1053. // Size and margins of physical surface measured in device pixels
  1054. //
  1055. gdiinfo.szlPhysSize.cx = pdev->paperSize.cx;
  1056. gdiinfo.szlPhysSize.cy = pdev->paperSize.cy;
  1057. gdiinfo.ptlPhysOffset.x = pdev->imageArea.left;
  1058. gdiinfo.ptlPhysOffset.y = pdev->imageArea.top;
  1059. //
  1060. // Use default halftone information
  1061. //
  1062. gdiinfo.ciDevice = DefDevHTInfo.ColorInfo;
  1063. gdiinfo.ulDevicePelsDPI = max(pdev->xres, pdev->yres);
  1064. gdiinfo.ulPrimaryOrder = PRIMARY_ORDER_CBA;
  1065. gdiinfo.ulHTOutputFormat = HT_FORMAT_1BPP;
  1066. gdiinfo.flHTFlags = HT_FLAG_HAS_BLACK_DYE;
  1067. gdiinfo.ulHTPatternSize = HT_PATSIZE_4x4_M;
  1068. //
  1069. // Copy cb byte from gdiinfo structure into the caller-provided buffer
  1070. //
  1071. if (cb > sizeof(gdiinfo))
  1072. {
  1073. memset(pgdiinfo, 0, cb);
  1074. memcpy(pgdiinfo, &gdiinfo, sizeof(gdiinfo));
  1075. }
  1076. else
  1077. memcpy(pgdiinfo, &gdiinfo, cb);
  1078. return TRUE;
  1079. }
  1080. VOID
  1081. FreeDevData(
  1082. PDEVDATA pdev
  1083. )
  1084. /*++
  1085. Routine Description:
  1086. Free up all memory associated with the specified PDEV
  1087. Arguments:
  1088. pdev Pointer to our DEVDATA structure
  1089. Return Value:
  1090. NONE
  1091. --*/
  1092. {
  1093. if (pdev->hpal)
  1094. EngDeletePalette(pdev->hpal);
  1095. //
  1096. // Close our preview file mapping if opened
  1097. //
  1098. #ifdef USERMODE_DRIVER
  1099. if (pdev->pTiffPageHeader)
  1100. {
  1101. UnmapViewOfFile(pdev->pTiffPageHeader);
  1102. pdev->pTiffPageHeader = NULL;
  1103. }
  1104. if (pdev->hPreviewMapping)
  1105. {
  1106. CLOSE_HANDLE(pdev->hPreviewMapping);
  1107. pdev->hPreviewMapping = NULL;
  1108. }
  1109. if (INVALID_HANDLE_VALUE != pdev->hPreviewFile)
  1110. {
  1111. CLOSE_HANDLE(pdev->hPreviewFile);
  1112. pdev->hPreviewFile = INVALID_HANDLE_VALUE;
  1113. }
  1114. #else
  1115. if (pdev->hPreviewMapping)
  1116. {
  1117. EngFreeModule(pdev->hPreviewMapping);
  1118. }
  1119. #endif // USERMODE_DRIVER
  1120. MemFree(pdev->pFaxIFD);
  1121. MemFree(pdev);
  1122. }
  1123. VOID
  1124. SelectPrinterForm(
  1125. PDEVDATA pdev
  1126. )
  1127. /*++
  1128. Routine Description:
  1129. Store printer paper size information in our DEVDATA structure
  1130. Arguments:
  1131. pdev - Pointer to our DEVDATA structure
  1132. Return Value:
  1133. NONE
  1134. --*/
  1135. {
  1136. FORM_INFO_1 formInfo;
  1137. //
  1138. // Validate devmode form specification; use default form if it's invalid.
  1139. //
  1140. if (! ValidDevmodeForm(pdev->hPrinter, &pdev->dm.dmPublic, &formInfo)) {
  1141. memset(&formInfo, 0, sizeof(formInfo));
  1142. //
  1143. // Default to A4 paper
  1144. //
  1145. formInfo.Size.cx = formInfo.ImageableArea.right = A4_WIDTH;
  1146. formInfo.Size.cy = formInfo.ImageableArea.bottom = A4_HEIGHT;
  1147. }
  1148. Assert(formInfo.Size.cx > 0 && formInfo.Size.cy > 0);
  1149. Assert(formInfo.ImageableArea.left >= 0 &&
  1150. formInfo.ImageableArea.top >= 0 &&
  1151. formInfo.ImageableArea.left < formInfo.ImageableArea.right &&
  1152. formInfo.ImageableArea.top < formInfo.ImageableArea.bottom &&
  1153. formInfo.ImageableArea.right <= formInfo.Size.cx &&
  1154. formInfo.ImageableArea.bottom <= formInfo.Size.cy);
  1155. //
  1156. // Take landscape into consideration
  1157. //
  1158. if (IsLandscapeMode(pdev)) {
  1159. LONG width, height;
  1160. //
  1161. // Swap the width and height
  1162. //
  1163. pdev->paperSize.cy = width = formInfo.Size.cx;
  1164. pdev->paperSize.cx = height = formInfo.Size.cy;
  1165. //
  1166. // Rotate the coordinate system 90 degrees counterclockwise
  1167. //
  1168. pdev->imageArea.left = height - formInfo.ImageableArea.bottom;
  1169. pdev->imageArea.top = formInfo.ImageableArea.left;
  1170. pdev->imageArea.right = height - formInfo.ImageableArea.top;
  1171. pdev->imageArea.bottom = formInfo.ImageableArea.right;
  1172. //
  1173. // Swap x and y resolution
  1174. //
  1175. pdev->xres = pdev->dm.dmPublic.dmYResolution;
  1176. pdev->yres = pdev->dm.dmPublic.dmPrintQuality;
  1177. } else {
  1178. pdev->paperSize = formInfo.Size;
  1179. pdev->imageArea = formInfo.ImageableArea;
  1180. pdev->xres = pdev->dm.dmPublic.dmPrintQuality;
  1181. pdev->yres = pdev->dm.dmPublic.dmYResolution;
  1182. }
  1183. }
  1184. LONG
  1185. CalcHypot(
  1186. LONG x,
  1187. LONG y
  1188. )
  1189. /*++
  1190. Routine Description:
  1191. Returns the length of the hypotenouse of a right triangle
  1192. Arguments:
  1193. x, y - Edges of the right triangle
  1194. Return Value:
  1195. Hypotenouse of the right triangle
  1196. --*/
  1197. {
  1198. LONG hypo, delta, target;
  1199. //
  1200. // Take care of negative inputs
  1201. //
  1202. if (x < 0)
  1203. x = -x;
  1204. if (y < 0)
  1205. y = -y;
  1206. //
  1207. // use sq(x) + sq(y) = sq(hypo);
  1208. // start with MAX(x, y),
  1209. // use sq(x + 1) = sq(x) + 2x + 1 to incrementally get to the target hypotenouse.
  1210. //
  1211. hypo = max(x, y);
  1212. target = min(x, y);
  1213. target *= target;
  1214. for(delta = 0; delta < target; hypo++)
  1215. delta += (hypo << 1) + 1;
  1216. return hypo;
  1217. }