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.

2293 lines
64 KiB

  1. /*++
  2. Copyright (c) 1996-1999 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. Environment:
  16. Windows NT Unidrv driver
  17. Revision History:
  18. 10/14/96 -amandan-
  19. Created
  20. 03/31/97 -zhanw-
  21. Added OEM customization support. Hooked out all DDI drawing functions.
  22. --*/
  23. #include "unidrv.h"
  24. #pragma hdrstop("unidrv.h")
  25. //Comment out this line to disable FTRACE and FVALUE.
  26. //#define FILETRACE
  27. #include "unidebug.h"
  28. #ifdef WINNT_40
  29. DECLARE_CRITICAL_SECTION;
  30. //
  31. // The global link list of ref counts for currently loaded OEM render plugin DLLs
  32. //
  33. extern POEM_PLUGIN_REFCOUNT gpOEMPluginRefCount;
  34. #endif // WINNT_40
  35. //
  36. // Our DRVFN table which tells the engine where to find the routines we support.
  37. //
  38. static DRVFN UniDriverFuncs[] = {
  39. //
  40. // enable.c
  41. //
  42. { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV },
  43. { INDEX_DrvResetPDEV, (PFN) DrvResetPDEV },
  44. { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV },
  45. { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV },
  46. { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface },
  47. { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface },
  48. #ifndef WINNT_40
  49. { INDEX_DrvDisableDriver, (PFN)DrvDisableDriver },
  50. #endif
  51. //
  52. // print.c
  53. //
  54. { INDEX_DrvStartDoc, (PFN)DrvStartDoc },
  55. { INDEX_DrvStartPage, (PFN)DrvStartPage },
  56. { INDEX_DrvSendPage, (PFN)DrvSendPage },
  57. { INDEX_DrvEndDoc, (PFN)DrvEndDoc },
  58. { INDEX_DrvStartBanding, (PFN)DrvStartBanding },
  59. { INDEX_DrvNextBand, (PFN)DrvNextBand },
  60. //
  61. // graphics.c
  62. //
  63. { INDEX_DrvPaint, (PFN)DrvPaint }, // new hook
  64. { INDEX_DrvBitBlt, (PFN)DrvBitBlt },
  65. { INDEX_DrvStretchBlt, (PFN)DrvStretchBlt },
  66. #ifndef WINNT_40
  67. { INDEX_DrvStretchBltROP, (PFN)DrvStretchBltROP }, // new in NT5
  68. { INDEX_DrvPlgBlt, (PFN)DrvPlgBlt }, // new in NT5
  69. #endif
  70. { INDEX_DrvCopyBits, (PFN)DrvCopyBits },
  71. { INDEX_DrvDitherColor, (PFN)DrvDitherColor },
  72. { INDEX_DrvRealizeBrush, (PFN)DrvRealizeBrush }, // in case OEM wants
  73. { INDEX_DrvLineTo, (PFN)DrvLineTo }, // new hook
  74. { INDEX_DrvStrokePath, (PFN)DrvStrokePath }, // new hook
  75. { INDEX_DrvFillPath, (PFN)DrvFillPath }, // new hook
  76. { INDEX_DrvStrokeAndFillPath, (PFN)DrvStrokeAndFillPath }, // new hook
  77. #ifndef WINNT_40
  78. { INDEX_DrvGradientFill, (PFN)DrvGradientFill }, // new in NT5
  79. { INDEX_DrvAlphaBlend, (PFN)DrvAlphaBlend }, // new in NT5
  80. { INDEX_DrvTransparentBlt, (PFN)DrvTransparentBlt }, // new in NT5
  81. #endif
  82. //
  83. // textout.c
  84. //
  85. { INDEX_DrvTextOut, (PFN)DrvTextOut },
  86. //
  87. // escape.c
  88. //
  89. { INDEX_DrvEscape, (PFN) DrvEscape },
  90. //
  91. // font.c
  92. //
  93. { INDEX_DrvQueryFont, (PFN) DrvQueryFont },
  94. { INDEX_DrvQueryFontTree, (PFN) DrvQueryFontTree },
  95. { INDEX_DrvQueryFontData, (PFN) DrvQueryFontData },
  96. { INDEX_DrvGetGlyphMode, (PFN) DrvGetGlyphMode },
  97. { INDEX_DrvFontManagement, (PFN) DrvFontManagement },
  98. { INDEX_DrvQueryAdvanceWidths, (PFN) DrvQueryAdvanceWidths },
  99. };
  100. //
  101. // Unidrv hooks out every drawing DDI to analyze page content for optimization
  102. //
  103. #ifndef WINNT_40
  104. #define HOOK_UNIDRV_FLAGS (HOOK_BITBLT | \
  105. HOOK_STRETCHBLT | \
  106. HOOK_PLGBLT | \
  107. HOOK_TEXTOUT | \
  108. HOOK_PAINT | \
  109. HOOK_STROKEPATH | \
  110. HOOK_FILLPATH | \
  111. HOOK_STROKEANDFILLPATH | \
  112. HOOK_LINETO | \
  113. HOOK_COPYBITS | \
  114. HOOK_STRETCHBLTROP | \
  115. HOOK_TRANSPARENTBLT | \
  116. HOOK_ALPHABLEND | \
  117. HOOK_GRADIENTFILL)
  118. #else
  119. #define HOOK_UNIDRV_FLAGS (HOOK_BITBLT | \
  120. HOOK_STRETCHBLT | \
  121. HOOK_TEXTOUT | \
  122. HOOK_PAINT | \
  123. HOOK_STROKEPATH | \
  124. HOOK_FILLPATH | \
  125. HOOK_STROKEANDFILLPATH | \
  126. HOOK_LINETO | \
  127. HOOK_COPYBITS)
  128. #endif
  129. //
  130. // Unidrv driver memory pool tag, required by common library headers
  131. //
  132. DWORD gdwDrvMemPoolTag = '5nuD';
  133. #if ENABLE_STOCKGLYPHSET
  134. //
  135. // Stock glyphset data
  136. //
  137. FD_GLYPHSET *pStockGlyphSet[MAX_STOCK_GLYPHSET];
  138. HSEMAPHORE hGlyphSetSem = NULL;
  139. VOID FreeGlyphSet(VOID);
  140. #endif //ENABLE_STOCKGLYPHSET
  141. #ifdef WINNT_40 //NT 4.0
  142. HSEMAPHORE hSemBrushColor = NULL;
  143. #endif //WINNT_40
  144. //
  145. // Forward declarations
  146. //
  147. PPDEV PAllocPDEVData(HANDLE);
  148. VOID VFreePDEVData( PDEV *);
  149. VOID VDisableSurface(PDEV *);
  150. BPaperSizeSourceSame(PDEV * , PDEV *);
  151. HSURF HCreateDeviceSurface(PDEV *, INT);
  152. HBITMAP HCreateBitmapSurface(PDEV *, INT);
  153. HINSTANCE ghInstance;
  154. BOOL WINAPI
  155. DllMain(
  156. HANDLE hModule,
  157. ULONG ulReason,
  158. PCONTEXT pContext
  159. )
  160. /*++
  161. Routine Description:
  162. DLL initialization procedure.
  163. Arguments:
  164. hModule - DLL instance handle
  165. ulReason - Reason for the call
  166. pContext - Pointer to context (not used by us)
  167. Return Value:
  168. TRUE if DLL is initialized successfully, FALSE otherwise.
  169. --*/
  170. {
  171. switch (ulReason)
  172. {
  173. case DLL_PROCESS_ATTACH:
  174. ghInstance = hModule;
  175. break;
  176. case DLL_PROCESS_DETACH:
  177. break;
  178. }
  179. return TRUE;
  180. }
  181. BOOL
  182. DrvQueryDriverInfo(
  183. DWORD dwMode,
  184. PVOID pBuffer,
  185. DWORD cbBuf,
  186. PDWORD pcbNeeded
  187. )
  188. /*++
  189. Routine Description:
  190. Query driver information
  191. Arguments:
  192. dwMode - Specify the information being queried
  193. pBuffer - Points to output buffer
  194. cbBuf - Size of output buffer in bytes
  195. pcbNeeded - Return the expected size of output buffer
  196. Return Value:
  197. TRUE if successful, FALSE if there is an error
  198. --*/
  199. {
  200. switch (dwMode)
  201. {
  202. #ifndef WINNT_40
  203. case DRVQUERY_USERMODE:
  204. ASSERT(pcbNeeded != NULL);
  205. *pcbNeeded = sizeof(DWORD);
  206. if (pBuffer == NULL || cbBuf < sizeof(DWORD))
  207. {
  208. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  209. return FALSE;
  210. }
  211. *((PDWORD) pBuffer) = TRUE;
  212. return TRUE;
  213. #endif
  214. default:
  215. ERR(("Unknown dwMode in DrvQueryDriverInfo: %d\n", dwMode));
  216. SetLastError(ERROR_INVALID_PARAMETER);
  217. return FALSE;
  218. }
  219. }
  220. BOOL
  221. DrvEnableDriver(
  222. ULONG iEngineVersion,
  223. ULONG cb,
  224. PDRVENABLEDATA pDrvEnableData
  225. )
  226. /*++
  227. Routine Description:
  228. Implementation of DDI entry point DrvEnableDriver.
  229. Please refer to DDK documentation for more details.
  230. Arguments:
  231. iEngineVersion - Specifies the DDI version number that GDI is written for
  232. cb - Size of the buffer pointed to by pDrvEnableData
  233. pDrvEnableData - Points to an DRVENABLEDATA structure
  234. Return Value:
  235. TRUE if successful, FALSE if there is an error
  236. --*/
  237. {
  238. VERBOSE(("Entering DrvEnableDriver...\n"));
  239. //
  240. // Make sure we have a valid engine version and
  241. // we're given enough room for the DRVENABLEDATA.
  242. //
  243. if (iEngineVersion < DDI_DRIVER_VERSION_NT4 || cb < sizeof(DRVENABLEDATA))
  244. {
  245. ERR(("DrvEnableDriver failed\n"));
  246. SetLastError(ERROR_BAD_DRIVER_LEVEL);
  247. return FALSE;
  248. }
  249. //
  250. // Fill in the DRVENABLEDATA structure for the engine.
  251. //
  252. pDrvEnableData->iDriverVersion = DDI_DRIVER_VERSION_NT4;
  253. pDrvEnableData->c = sizeof(UniDriverFuncs) / sizeof(DRVFN);
  254. pDrvEnableData->pdrvfn = UniDriverFuncs;
  255. #ifdef WINNT_40 // NT 4.0
  256. INIT_CRITICAL_SECTION();
  257. if (!IS_VALID_DRIVER_SEMAPHORE())
  258. {
  259. ERR(("Failed to initialize semaphore.\n"));
  260. SetLastError(ERROR_NO_SYSTEM_RESOURCES);
  261. return FALSE;
  262. }
  263. ENTER_CRITICAL_SECTION();
  264. gpOEMPluginRefCount = NULL;
  265. LEAVE_CRITICAL_SECTION();
  266. if (!(hSemBrushColor = EngCreateSemaphore()))
  267. {
  268. return(FALSE);
  269. }
  270. #endif //WINNT_40
  271. #if ENABLE_STOCKGLYPHSET
  272. //
  273. // Initialize stock glyphset data
  274. //
  275. if (!(hGlyphSetSem = EngCreateSemaphore()))
  276. {
  277. ERR(("DrvEnableDriver: EngCreateSemaphore failed.\n"));
  278. SetLastError(ERROR_BAD_DRIVER_LEVEL);
  279. return FALSE;
  280. }
  281. EngAcquireSemaphore(hGlyphSetSem);
  282. ZeroMemory(pStockGlyphSet, MAX_STOCK_GLYPHSET * sizeof(FD_GLYPHSET*));
  283. EngReleaseSemaphore(hGlyphSetSem);
  284. #endif //ENABLE_STOCKGLYPHSET
  285. return TRUE;
  286. }
  287. DHPDEV
  288. DrvEnablePDEV(
  289. PDEVMODE pdm,
  290. PWSTR pLogAddress,
  291. ULONG cPatterns,
  292. HSURF *phsurfPatterns,
  293. ULONG cjGdiInfo,
  294. ULONG *pGdiInfo,
  295. ULONG cjDevInfo,
  296. DEVINFO *pDevInfo,
  297. HDEV hdev,
  298. PWSTR pDeviceName,
  299. HANDLE hPrinter
  300. )
  301. /*++
  302. Routine Description:
  303. Implementation of DDI entry point DrvEnablePDEV.
  304. Please refer to DDK documentation for more details.
  305. Arguments:
  306. pdm - Points to a DEVMODEW structure that contains driver data
  307. pLogAddress - Points to the logical address string
  308. cPatterns - Specifies the number of standard patterns
  309. phsurfPatterns - Buffer to hold surface handles to standard patterns
  310. cjGdiInfo - Size of GDIINFO buffer
  311. pGdiInfo - Points to a GDIINFO structure
  312. cjDevInfo - Size of DEVINFO buffer
  313. pDevInfo - Points to a DEVINFO structure
  314. hdev - GDI device handle
  315. pDeviceName - Points to device name string
  316. hPrinter - Spooler printer handle
  317. Return Value:
  318. Driver device handle, NULL if there is an error
  319. --*/
  320. {
  321. PDEV *pPDev;
  322. RECTL rcFormImageArea;
  323. DRVENABLEDATA ded; // for OEM customization support
  324. PDEVOEM pdevOem;
  325. PFN_OEMEnablePDEV pfnOEMEnablePDEV;
  326. VERBOSE(("Entering DrvEnablePDEV...\n"));
  327. ZeroMemory(phsurfPatterns, sizeof(HSURF) * cPatterns);
  328. //
  329. // Allocate PDEV,
  330. // Initializes binary data,
  331. // Get default binary data snapshot,
  332. //
  333. if (! (pPDev = PAllocPDEVData(hPrinter)) ||
  334. ! (pPDev->pDriverInfo3 = MyGetPrinterDriver(hPrinter, hdev, 3)) ||
  335. ! (pPDev->pRawData = LoadRawBinaryData(pPDev->pDriverInfo3->pDataFile)) ||
  336. ! (pPDev->pDriverInfo = PGetDefaultDriverInfo(hPrinter, pPDev->pRawData) ) ||
  337. ! (pPDev->pInfoHeader = pPDev->pDriverInfo->pInfoHeader) ||
  338. ! (pPDev->pUIInfo = OFFSET_TO_POINTER(pPDev->pInfoHeader, pPDev->pInfoHeader->loUIInfoOffset)) )
  339. {
  340. ERR(("DrvEnablePDEV failed: %d\n", GetLastError()));
  341. VFreePDEVData(pPDev);
  342. return NULL;
  343. }
  344. //
  345. // Must load OEM dll's before setting devmode
  346. //
  347. if( ! BLoadAndInitOemPlugins(pPDev) ||
  348. ! BInitWinResData(&pPDev->WinResData, pPDev->pDriverInfo3->pDriverPath, pPDev->pUIInfo) ||
  349. ! (pPDev->pOptionsArray = MemAllocZ(MAX_PRINTER_OPTIONS * sizeof(OPTSELECT))))
  350. {
  351. ERR(("DrvEnablePDEV failed: %d\n", GetLastError()));
  352. VFreePDEVData(pPDev);
  353. return NULL;
  354. }
  355. //
  356. // Since output is expected to follow this call, allocate storage
  357. // for the output buffer. This used to be statically allocated
  358. // within UNIDRV's PDEV, but now we can save that space for INFO
  359. // type DCs.
  360. //
  361. // Not! according to Bug 150881 StartDoc and EndDoc
  362. // are optional calls, but pbOBuf is required.
  363. //
  364. if( !(pPDev->pbOBuf = MemAllocZ( CCHSPOOL )) )
  365. {
  366. ERR(("DrvEnablePDEV failed: %d\n", GetLastError()));
  367. VFreePDEVData(pPDev);
  368. return NULL;
  369. }
  370. //
  371. // Use the default binary data to validate input devmode
  372. // and merges with the system, devmode.
  373. // Get printer properties.
  374. // and loads minidriver resource data
  375. //
  376. if (! BGetPrinterProperties(pPDev->devobj.hPrinter, pPDev->pRawData, &pPDev->PrinterData) ||
  377. ! BMergeAndValidateDevmode(pPDev, pdm, &rcFormImageArea))
  378. {
  379. ERR(("DrvEnablePDEV failed: %d\n", GetLastError()));
  380. VFreePDEVData(pPDev);
  381. return NULL;
  382. }
  383. //
  384. // get updated binary snapshot with the validated/merged devmode
  385. //
  386. if (! (pPDev->pDriverInfo = PGetUpdateDriverInfo (
  387. pPDev,
  388. hPrinter,
  389. pPDev->pInfoHeader,
  390. pPDev->pOptionsArray,
  391. pPDev->pRawData,
  392. MAX_PRINTER_OPTIONS,
  393. pPDev->pdm,
  394. &pPDev->PrinterData)))
  395. {
  396. ERR(("PGetUpdateDriverInfo failed: %d\n", GetLastError()));
  397. pPDev->pInfoHeader = NULL ; // deleted by PGetUpdateDriverInfo
  398. // better fix is to pass a pointer to pPDev->pInfoHeader so PGetUpdateDriverInfo
  399. // can update the pointer immediately.
  400. VFreePDEVData(pPDev);
  401. return NULL;
  402. }
  403. if(! (pPDev->pInfoHeader = pPDev->pDriverInfo->pInfoHeader) ||
  404. ! (pPDev->pUIInfo = OFFSET_TO_POINTER(pPDev->pInfoHeader, pPDev->pInfoHeader->loUIInfoOffset)) )
  405. {
  406. ERR(("DrvEnablePDEV failed: %d\n", GetLastError()));
  407. VFreePDEVData(pPDev);
  408. return NULL;
  409. }
  410. //
  411. // pPDev->pUIInfo is reset so update the winresdata pUIInfo also.
  412. //
  413. pPDev->WinResData.pUIInfo = pPDev->pUIInfo;
  414. //
  415. // Initialize the rest of PDEV and GDIINFO, DEVINFO and
  416. // call the Font, Raster modules to
  417. // initialize their parts of the PDEVICE, GDIINFO and DEVINFO
  418. // Palette initialization is done by control module.
  419. //
  420. //
  421. // This is necessary to initialize for FMInit.
  422. //
  423. pPDev->devobj.hEngine = hdev;
  424. pPDev->fHooks = HOOK_UNIDRV_FLAGS;
  425. if (! BInitPDEV(pPDev, &rcFormImageArea ) ||
  426. ! BInitGdiInfo(pPDev, pGdiInfo, cjGdiInfo) ||
  427. ! BInitDevInfo(pPDev, pDevInfo, cjDevInfo) ||
  428. ! VMInit(pPDev, pDevInfo, (PGDIINFO)pGdiInfo) ||
  429. ! RMInit(pPDev, pDevInfo, (PGDIINFO)pGdiInfo) ||
  430. ! BInitPalDevInfo(pPDev, pDevInfo, (PGDIINFO)pGdiInfo) ||
  431. ! FMInit(pPDev, pDevInfo, (PGDIINFO)pGdiInfo))
  432. {
  433. ERR(("DrvEnablePDEV failed: %d\n", GetLastError()));
  434. VFreePDEVData(pPDev);
  435. return NULL;
  436. }
  437. FTRACE(Tracing Palette);
  438. FVALUE((pDevInfo->flGraphicsCaps & GCAPS_ARBRUSHTEXT), 0x%x);
  439. ded.iDriverVersion = PRINTER_OEMINTF_VERSION;
  440. ded.c = sizeof(UniDriverFuncs) / sizeof(DRVFN);
  441. ded.pdrvfn = (DRVFN*) UniDriverFuncs;
  442. //
  443. // Call EnablePDEV for the vector plugins.
  444. // Put the return value in (((PDEVOBJ)pPDev)->pdevOEM)
  445. //
  446. HANDLE_VECTORPROCS_RET(pPDev, VMEnablePDEV, (pPDev)->pVectorPDEV,
  447. ((PDEVOBJ) pPDev,
  448. pDeviceName,
  449. cPatterns,
  450. phsurfPatterns,
  451. cjGdiInfo,
  452. (GDIINFO *)pGdiInfo,
  453. cjDevInfo,
  454. (DEVINFO *)pDevInfo,
  455. &ded) ) ;
  456. //
  457. // If there is present a vector module and it exports EnablePDEV
  458. // but its EnablePDEV has failed, then we cannot continue.
  459. //
  460. if ( pPDev->pVectorProcs &&
  461. ( (PVMPROCS)(pPDev->pVectorProcs) )->VMEnablePDEV &&
  462. !(pPDev->pVectorPDEV)
  463. )
  464. {
  465. ERR(("Vector Module's EnablePDEV failed \n"));
  466. VFreePDEVData(pPDev);
  467. return NULL;
  468. }
  469. //
  470. // Call OEMEnablePDEV entrypoint for each OEM dll
  471. //
  472. START_OEMENTRYPOINT_LOOP(pPDev)
  473. if (pOemEntry->pIntfOem != NULL)
  474. {
  475. if (HComOEMEnablePDEV(pOemEntry,
  476. (PDEVOBJ)pPDev,
  477. pDeviceName,
  478. cPatterns,
  479. phsurfPatterns,
  480. cjGdiInfo,
  481. (GDIINFO *) pGdiInfo,
  482. cjDevInfo,
  483. (DEVINFO *) pDevInfo,
  484. &ded,
  485. &pOemEntry->pParam) == E_NOTIMPL)
  486. continue;
  487. }
  488. else
  489. {
  490. if ((pfnOEMEnablePDEV = GET_OEM_ENTRYPOINT(pOemEntry, OEMEnablePDEV)))
  491. {
  492. pOemEntry->pParam = pfnOEMEnablePDEV(
  493. (PDEVOBJ) pPDev,
  494. pDeviceName,
  495. cPatterns,
  496. phsurfPatterns,
  497. cjGdiInfo,
  498. (GDIINFO *) pGdiInfo,
  499. cjDevInfo,
  500. (DEVINFO *) pDevInfo,
  501. &ded);
  502. }
  503. else
  504. continue;
  505. }
  506. if (pOemEntry->pParam == NULL)
  507. {
  508. ERR(("OEMEnablePDEV failed for '%ws': %d\n",
  509. pOemEntry->ptstrDriverFile,
  510. GetLastError()));
  511. VFreePDEVData(pPDev);
  512. return NULL;
  513. }
  514. //
  515. // Add support for OEM's 8bpp multi-level color
  516. //
  517. if (((GDIINFO *)pGdiInfo)->ulHTOutputFormat == HT_FORMAT_8BPP &&
  518. ((GDIINFO *)pGdiInfo)->flHTFlags & HT_FLAG_8BPP_CMY332_MASK &&
  519. ((GDIINFO *)pGdiInfo)->flHTFlags & HT_FLAG_USE_8BPP_BITMASK)
  520. {
  521. VInitPal8BPPMaskMode(pPDev,(GDIINFO *)pGdiInfo);
  522. }
  523. pOemEntry->dwFlags |= OEMENABLEPDEV_CALLED;
  524. #if 0
  525. //
  526. // in the extremely simple case, OEM dll may not need to create
  527. // a PDEV at all.
  528. //
  529. else // OEMEnablePDEV is not exported. Error!
  530. {
  531. ERR(("OEMEnablePDEV is not exported for '%ws'\n",
  532. pOemEntry->ptstrDriverFile));
  533. VFreePDEVData(pPDev);
  534. return NULL;
  535. }
  536. //
  537. // for every OEM DLL, OEMDisablePDEV is also a required export.
  538. //
  539. if (!GET_OEM_ENTRYPOINT(pOemEntry, OEMDisablePDEV))
  540. {
  541. ERR(("OEMDisablePDEV is not exported for '%ws'\n",
  542. pOemEntry->ptstrDriverFile));
  543. VFreePDEVData(pPDev);
  544. return NULL;
  545. }
  546. #endif
  547. END_OEMENTRYPOINT_LOOP
  548. //
  549. // Unload and free binary data allocated by the parser.
  550. // Will need to reload at DrvEnableSurface
  551. //
  552. VUnloadFreeBinaryData(pPDev);
  553. return (DHPDEV) pPDev;
  554. }
  555. BOOL
  556. DrvResetPDEV(
  557. DHPDEV dhpdevOld,
  558. DHPDEV dhpdevNew
  559. )
  560. /*++
  561. Routine Description:
  562. Implementation of DDI entry point DrvResetPDEV.
  563. Please refer to DDK documentation for more details.
  564. Arguments:
  565. phpdevOld - Driver handle to the old device
  566. phpdevNew - Driver handle to the new device
  567. Return Value:
  568. TRUE if successful, FALSE if there is an error
  569. --*/
  570. {
  571. PPDEV pPDevOld, pPDevNew;
  572. PFN_OEMResetPDEV pfnOEMResetPDEV;
  573. POEM_PLUGIN_ENTRY pOemEntryOld;
  574. BOOL bResult = TRUE;
  575. VERBOSE(("Entering DrvResetPDEV...\n"));
  576. pPDevOld = (PDEV *) dhpdevOld;
  577. pPDevNew = (PDEV *) dhpdevNew;
  578. ASSERT_VALID_PDEV(pPDevOld);
  579. ASSERT_VALID_PDEV(pPDevNew);
  580. //
  581. // Carry relevant information from old pdev to new pdev
  582. // BUG_BUG, what other information should we carry over here ?
  583. //
  584. //
  585. // Set the PF_SEND_ONLY_NOEJECT_CMDS flag if the only
  586. // thing that changed between the old and new devmode
  587. // require only commands that do not cause a page ejection.
  588. //
  589. //
  590. // Don't need to resend the page initialization iff
  591. // The Document has started printing AND
  592. // The device support DUPLEX AND
  593. // The Duplex option selected is DM_DUPLEX AND
  594. // The previous duplex option matches the current duplex option AND
  595. // The Paper Size, Paper Source , and Orientation is the same
  596. // Due to unloading of rawbinary data and snapshot, pPDevNew->pDuplex
  597. // and other related fields are null at this time. must use devmode.
  598. //
  599. if( (pPDevOld->fMode & PF_DOCSTARTED) &&
  600. (pPDevNew->pdm->dmFields & DM_DUPLEX) &&
  601. (pPDevOld->pdm->dmFields & DM_DUPLEX) &&
  602. (pPDevNew->pdm->dmDuplex != DMDUP_SIMPLEX) &&
  603. (pPDevNew->pdm->dmDuplex == pPDevOld->pdm->dmDuplex) )
  604. {
  605. BOOL bUseNoEjectSubset = TRUE ;
  606. COMMAND *pSeqCmd;
  607. DWORD dwCmdIndex ;
  608. if (!BPaperSizeSourceSame(pPDevNew,pPDevOld))
  609. bUseNoEjectSubset = FALSE ;
  610. //
  611. // if orientation command is not NO_PageEject
  612. //
  613. if( bUseNoEjectSubset &&
  614. (pPDevNew->pdm->dmFields & DM_ORIENTATION) &&
  615. (pPDevOld->pdm->dmFields & DM_ORIENTATION) &&
  616. (pPDevNew->pdm->dmOrientation != pPDevOld->pdm->dmOrientation) &&
  617. pPDevOld->pOrientation &&
  618. ((dwCmdIndex = pPDevOld->pOrientation->GenericOption.dwCmdIndex) != UNUSED_ITEM) &&
  619. (pSeqCmd = INDEXTOCOMMANDPTR(pPDevOld->pDriverInfo, dwCmdIndex)) &&
  620. !(pSeqCmd->bNoPageEject))
  621. bUseNoEjectSubset = FALSE ;
  622. //
  623. // if colormode command is not NO_PageEject
  624. //
  625. if( bUseNoEjectSubset &&
  626. (pPDevNew->pdm->dmFields & DM_COLOR) &&
  627. (pPDevOld->pdm->dmFields & DM_COLOR) &&
  628. (pPDevNew->pdm->dmColor != pPDevOld->pdm->dmColor) &&
  629. pPDevOld->pColorMode &&
  630. ((dwCmdIndex = pPDevOld->pColorMode->GenericOption.dwCmdIndex) != UNUSED_ITEM) &&
  631. (pSeqCmd = INDEXTOCOMMANDPTR(pPDevOld->pDriverInfo, dwCmdIndex)) &&
  632. !(pSeqCmd->bNoPageEject))
  633. bUseNoEjectSubset = FALSE ;
  634. //check all other doc properties if you want:
  635. if(bUseNoEjectSubset)
  636. pPDevNew->fMode |= PF_SEND_ONLY_NOEJECT_CMDS;
  637. }
  638. //
  639. // if Job commands already sent, don't send them again.
  640. //
  641. if( pPDevOld->fMode & PF_JOB_SENT)
  642. pPDevNew->fMode |= PF_JOB_SENT;
  643. //
  644. // if Doc commands already sent, don't send them again.
  645. //
  646. if( pPDevOld->fMode & PF_DOC_SENT)
  647. pPDevNew->fMode |= PF_DOC_SENT;
  648. pPDevNew->dwPageNumber = pPDevOld->dwPageNumber ;
  649. // preserve pageNumber across ResetDC.
  650. //
  651. // Call Raster and Font module to carry over their stuff from old
  652. // pPDev to new pPDev
  653. //
  654. if (!(((PRMPROCS)(pPDevNew->pRasterProcs))->RMResetPDEV(pPDevOld, pPDevNew)) ||
  655. !(((PFMPROCS)(pPDevNew->pFontProcs))->FMResetPDEV(pPDevOld, pPDevNew)))
  656. {
  657. bResult = FALSE;
  658. }
  659. //
  660. // Also call the vector module.
  661. //
  662. if ( pPDevOld->pVectorProcs )
  663. {
  664. pPDevOld->devobj.pdevOEM = pPDevOld->pVectorPDEV;
  665. HANDLE_VECTORPROCS_RET( pPDevNew, VMResetPDEV, bResult,
  666. ((PDEVOBJ) pPDevOld,
  667. (PDEVOBJ) pPDevNew ) ) ;
  668. }
  669. //
  670. // Call OEMResetPDEV entrypoint
  671. //
  672. ASSERT(pPDevNew->pOemPlugins);
  673. ASSERT(pPDevOld->pOemPlugins);
  674. START_OEMENTRYPOINT_LOOP(pPDevNew)
  675. pOemEntryOld = PFindOemPluginWithSignature(pPDevOld->pOemPlugins,
  676. pOemEntry->dwSignature);
  677. if (pOemEntryOld != NULL)
  678. {
  679. pPDevOld->devobj.pdevOEM = pOemEntryOld->pParam;
  680. pPDevOld->devobj.pOEMDM = pOemEntryOld->pOEMDM;
  681. if (pOemEntry->pIntfOem != NULL)
  682. {
  683. HRESULT hr;
  684. hr = HComOEMResetPDEV(pOemEntry,
  685. (PDEVOBJ)pPDevOld,
  686. (PDEVOBJ)pPDevNew);
  687. if (hr == E_NOTIMPL)
  688. continue;
  689. if (FAILED(hr))
  690. {
  691. ERR(("OEMResetPDEV failed for '%ws': %d\n",
  692. pOemEntry->ptstrDriverFile,
  693. GetLastError()));
  694. bResult = FALSE;
  695. }
  696. }
  697. else
  698. {
  699. if (!(pfnOEMResetPDEV = GET_OEM_ENTRYPOINT(pOemEntry, OEMResetPDEV)))
  700. continue;
  701. if (! pfnOEMResetPDEV((PDEVOBJ) pPDevOld, (PDEVOBJ) pPDevNew))
  702. {
  703. ERR(("OEMResetPDEV failed for '%ws': %d\n",
  704. pOemEntry->ptstrDriverFile,
  705. GetLastError()));
  706. bResult = FALSE;
  707. }
  708. }
  709. }
  710. END_OEMENTRYPOINT_LOOP
  711. return bResult;
  712. }
  713. HSURF
  714. DrvEnableSurface(
  715. DHPDEV dhpdev
  716. )
  717. /*++
  718. Routine Description:
  719. Implementation of DDI entry point DrvEnableSurface.
  720. Please refer to DDK documentation for more details.
  721. Arguments:
  722. dhpdev - Driver device handle
  723. Return Value:
  724. Handle to newly created surface, NULL if there is an error
  725. --*/
  726. {
  727. HSURF hSurface; // Handle to the surface
  728. HBITMAP hBitmap; // The bitmap handle
  729. // SIZEL szSurface; // Device surface size
  730. INT iFormat; // Bitmap format
  731. ULONG cbScan; // Scan line byte length (DWORD aligned)
  732. int iBPP; // Bits per pel, as # of bits
  733. int iPins; // Basic rounding factor for banding size
  734. PDEV *pPDev = (PDEV*)dhpdev;
  735. DWORD dwNumBands; // Number of bands to use
  736. PFN_OEMDriverDMS pfnOEMDriverDMS;
  737. DWORD dwHooks = 0, dwHooksSize = 0; // used to query what kind of surface should be created
  738. POEM_PLUGINS pOemPlugins; // OEM Plugin Module
  739. PTSTR ptstrDllName;
  740. DEVOBJ DevObj;
  741. BOOL bReturn = FALSE;
  742. VERBOSE(("Entering DrvEnableSurface...\n"));
  743. //
  744. // Reloads the binary data and reinit the offsets and pointers
  745. // to binary data
  746. //
  747. if (!BReloadBinaryData(pPDev))
  748. return NULL;
  749. //
  750. // BUG_BUG, Need to put test code here to force banding for testing purposes
  751. //
  752. // szSurface.cx = pPDev->sf.szImageAreaG.cx;
  753. // szSurface.cy = pPDev->sf.szImageAreaG.cy;
  754. iBPP = pPDev->sBitsPixel;
  755. switch (pPDev->sBitsPixel)
  756. {
  757. case 1:
  758. iFormat = BMF_1BPP;
  759. break;
  760. case 4:
  761. iFormat = BMF_4BPP;
  762. break;
  763. case 8:
  764. iFormat = BMF_8BPP;
  765. break;
  766. case 24:
  767. iFormat = BMF_24BPP;
  768. break;
  769. default:
  770. ERR(("Unknown sBitsPixels in DrvEnableSurface"));
  771. break;
  772. }
  773. //
  774. // Time to allocate surface bitmap
  775. DevObj = pPDev->devobj;
  776. //
  777. //
  778. // First call Vector pseudo-plugin
  779. //
  780. HANDLE_VECTORPROCS_RET( pPDev, VMDriverDMS, bReturn,
  781. ((PDEVOBJ) pPDev,
  782. &dwHooks,
  783. sizeof(DWORD),
  784. &dwHooksSize) ) ;
  785. {
  786. if ( bReturn && dwHooks)
  787. pPDev->fMode |= PF_DEVICE_MANAGED;
  788. else
  789. pPDev->fMode &= ~PF_DEVICE_MANAGED;
  790. }
  791. // Call OEMGetInfo to find out if the Oem wants to create
  792. // a bitmap surface or a device surface
  793. pOemPlugins = pPDev->pOemPlugins;
  794. if (pOemPlugins->dwCount > 0)
  795. {
  796. //
  797. // Before the HANDLE_VECTORPROCS_RET was placed above, it made sense to initialize
  798. // dwHooks. But now we dont want to reinitialize it.
  799. //
  800. // dwHooks = 0;
  801. dwHooksSize = 0;
  802. START_OEMENTRYPOINT_LOOP(pPDev)
  803. VERBOSE(("Getting the OEMDriverDMS address\n"));
  804. if (pOemEntry->pIntfOem != NULL)
  805. {
  806. HRESULT hr;
  807. hr = HComDriverDMS(pOemEntry,
  808. (PDEVOBJ)pPDev,
  809. &dwHooks,
  810. sizeof(DWORD),
  811. &dwHooksSize);
  812. //
  813. // We need to explicitly check for E_NOTIMPL. SUCCEEDED macro
  814. // will fail for this error.
  815. //
  816. if (hr == E_NOTIMPL)
  817. continue;
  818. if(!SUCCEEDED(hr))
  819. {
  820. WARNING(("OEMDriverDMS returned FALSE '%ws': ErrorCode = %d\n",
  821. pOemEntry->ptstrDriverFile,
  822. GetLastError()));
  823. dwHooks = 0;
  824. }
  825. if (dwHooks)
  826. pPDev->fMode |= PF_DEVICE_MANAGED;
  827. else
  828. pPDev->fMode &= ~PF_DEVICE_MANAGED;
  829. }
  830. else
  831. {
  832. if ((pfnOEMDriverDMS = GET_OEM_ENTRYPOINT(pOemEntry, OEMDriverDMS)))
  833. {
  834. bReturn = pfnOEMDriverDMS((PDEVOBJ)pPDev,
  835. &dwHooks,
  836. sizeof(DWORD),
  837. &dwHooksSize);
  838. if (bReturn == FALSE)
  839. {
  840. WARNING(("OEMDriverDMS returned FALSE '%ws': ErrorCode = %d\n",
  841. pOemEntry->ptstrDriverFile,
  842. GetLastError()));
  843. dwHooks = 0;
  844. }
  845. if (dwHooks)
  846. pPDev->fMode |= PF_DEVICE_MANAGED;
  847. else
  848. pPDev->fMode &= ~PF_DEVICE_MANAGED;
  849. }
  850. }
  851. END_OEMENTRYPOINT_LOOP
  852. }
  853. //
  854. // If the OEM Plugin Module wants a device managed surface
  855. // (from OEMGetInfo) - then create it.
  856. // Otherwise a bitmap surface is created. Note: Banding must be
  857. // turned off for a device surface.
  858. //
  859. if (DRIVER_DEVICEMANAGED (pPDev)) // device surface
  860. {
  861. VERBOSE(("DrvEnableSurface: creating a DEVICE surface.\n"));
  862. //
  863. // Hack for monochrome HPGL2 pseudo-plugin driver.
  864. // The gpd indicates the driver is monochrome, but the plugin wants the
  865. // driver surface to be 24bpp color. Even though the rendering is done in monochrome,
  866. // but the plugin wants GDI to send it all color information. So it wants destination
  867. // surface to be declared color surface. Putting color information in gpd, though simple,
  868. // breaks backward compatibility (e.g. if new gpd is used with old unidrv). Therefore
  869. // this hack. If the personality in gpd is hpgl2 and the VectorProc structure is
  870. // initialized (which means that Graphics Mode has been chosen as HP-GL/2 from the UI),
  871. // then we assume we are printing to monochrome HPGL printer.
  872. // Therefore for plugin's happiness we create the device managed surface
  873. // as 24bpp.
  874. // Question: This creates a wierd situation, where the surface is color, but
  875. // unidrv thinks it is monochrome and creates palette accordingly.
  876. // Answer: Since all the rendering is done by the plugin and unidrv is not used,
  877. // I think we should be ok.
  878. //
  879. if ((pPDev->ePersonality == kHPGL2 ||
  880. pPDev->ePersonality == kPCLXL ) &&
  881. pPDev->pVectorProcs != NULL &&
  882. iFormat == BMF_1BPP)
  883. {
  884. hSurface = HCreateDeviceSurface (pPDev, BMF_24BPP);
  885. }
  886. else
  887. {
  888. hSurface = HCreateDeviceSurface (pPDev, iFormat);
  889. }
  890. // if we can't create the surface fail the call.
  891. if (!hSurface)
  892. {
  893. ERR(("Unidrv!DrvEnableSurface:HCreateBitmapSurface Failed"));
  894. VDisableSurface( pPDev );
  895. return NULL;
  896. }
  897. pPDev->hSurface = hSurface;
  898. pPDev->hbm = NULL;
  899. pPDev->pbScanBuf = NULL; // Don't need this buffer
  900. }
  901. else // bitmap surface
  902. {
  903. //
  904. // Create a surface. Try for a bitmap for the entire surface.
  905. // If this fails, then switch to journalling and a somewhat smaller
  906. // surface. If journalling, we still create the bitmap here. While
  907. // it is nicer to do this at DrvSendPage() time, we do it here to
  908. // ensure that it is possible. By maintaining the bitmap for the
  909. // life of the DC, we can be reasonably certain of being able to
  910. // complete printing regardless of how tight memory becomes later.
  911. //
  912. VERBOSE(("DrvEnableSurface: creating a BITMAP surface.\n"));
  913. hBitmap = HCreateBitmapSurface (pPDev, iFormat);
  914. // if we can't create the bitmap fail the call.
  915. if (!hBitmap)
  916. {
  917. ERR(("Unidrv!DrvEnableSurface:HCreateBitmapSurface Failed"));
  918. VDisableSurface( pPDev );
  919. return NULL;
  920. }
  921. //
  922. // We will always use szBand to describe the bitmap surface, a band
  923. // could be the whole page or a part of a page.
  924. //
  925. //
  926. // Allocate array to represent the page in scanlines,
  927. // for z-ordering fix
  928. //
  929. if( (pPDev->pbScanBuf = MemAllocZ(pPDev->szBand.cy)) == NULL)
  930. {
  931. VDisableSurface( pPDev );
  932. return NULL;
  933. }
  934. //
  935. // Allocate array to represents the page in scanlines, for erasing surface
  936. //
  937. if( (pPDev->pbRasterScanBuf = MemAllocZ((pPDev->szBand.cy / LINESPERBLOCK)+1)) == NULL)
  938. {
  939. VDisableSurface( pPDev );
  940. return NULL;
  941. }
  942. #ifndef DISABLE_NEWRULES
  943. //
  944. // Allocate array to store black rectangle optimization
  945. // Device must support rectangle commands and unidrv must dump the raster
  946. //
  947. if ((pPDev->fMode & PF_RECT_FILL) &&
  948. !(pPDev->pdmPrivate->dwFlags & DXF_TEXTASGRAPHICS) &&
  949. !(pPDev->fMode2 & PF2_MIRRORING_ENABLED) &&
  950. ((COMMANDPTR(pPDev->pDriverInfo,CMD_RECTBLACKFILL)) ||
  951. (COMMANDPTR(pPDev->pDriverInfo,CMD_RECTGRAYFILL)) ||
  952. !(COMMANDPTR(pPDev->pDriverInfo,CMD_RECTWHITEFILL))) &&
  953. (pPDev->pColorModeEx == NULL || pPDev->pColorModeEx->dwPrinterBPP))
  954. {
  955. if( (pPDev->pbRulesArray = MemAlloc(sizeof(RECTL) * MAX_NUM_RULES)) == NULL)
  956. {
  957. VDisableSurface( pPDev );
  958. return NULL;
  959. }
  960. }
  961. else
  962. pPDev->pbRulesArray = NULL;
  963. #endif
  964. pPDev->dwDelta = pPDev->szBand.cx / MAX_COLUMM;
  965. pPDev->hbm = hBitmap;
  966. pPDev->hSurface = NULL;
  967. }
  968. //
  969. // Call Raster and Font module EnableSurface for surface intialization
  970. //
  971. if ( !(((PRMPROCS)(pPDev->pRasterProcs))->RMEnableSurface(pPDev)) ||
  972. !(((PFMPROCS)(pPDev->pFontProcs))->FMEnableSurface(pPDev)) )
  973. {
  974. VDisableSurface( pPDev );
  975. return NULL;
  976. }
  977. //
  978. // Now need to associate this surface with the pdev passed in at
  979. // DrvCompletePDev time.
  980. // Note: BUG_BUG, The RMInit() and FMInit() calls should have
  981. // initialized the pPDev->fHooks already. All we need to do here is use it
  982. //
  983. ASSERT(pPDev->fHooks != 0);
  984. if (DRIVER_DEVICEMANAGED (pPDev)) // device surface
  985. {
  986. pPDev->fHooks = dwHooks;
  987. EngAssociateSurface (hSurface, pPDev->devobj.hEngine, pPDev->fHooks);
  988. return hSurface;
  989. }
  990. else
  991. {
  992. #ifdef DISABLEDEVSURFACE
  993. EngAssociateSurface( (HSURF)hBitmap, pPDev->devobj.hEngine, pPDev->fHooks );
  994. pPDev->pso = EngLockSurface( (HSURF)hBitmap);
  995. if (pPDev->pso == NULL)
  996. {
  997. ERR(("Unidrv!DrvEnableSurface:EngLockSurface Failed"));
  998. VDisableSurface( pPDev );
  999. return NULL;
  1000. }
  1001. return (HSURF)hBitmap;
  1002. #else
  1003. // HSURF hSurface;
  1004. // SIZEL szSurface;
  1005. EngAssociateSurface( (HSURF)hBitmap, pPDev->devobj.hEngine, 0 );
  1006. pPDev->pso = EngLockSurface( (HSURF)hBitmap);
  1007. if (pPDev->pso == NULL)
  1008. {
  1009. ERR(("Unidrv!DrvEnableSurface:EngLockSurface Failed"));
  1010. VDisableSurface( pPDev );
  1011. return NULL;
  1012. }
  1013. //
  1014. // Create a device surface to make sure GDI always calls the driver first
  1015. // for any drawing
  1016. //
  1017. hSurface = EngCreateDeviceSurface((DHSURF)pPDev, pPDev->szBand, iFormat);
  1018. if (!hSurface)
  1019. {
  1020. ERR(("Unidrv!DrvEnableSurface:EngCreateDeviceSurface Failed"));
  1021. VDisableSurface( pPDev );
  1022. return NULL;
  1023. }
  1024. // If banding is enabled mark the device surface as a banding surface
  1025. //
  1026. if (pPDev->bBanding)
  1027. EngMarkBandingSurface(hSurface);
  1028. pPDev->hSurface = hSurface;
  1029. EngAssociateSurface( (HSURF)hSurface, pPDev->devobj.hEngine, pPDev->fHooks );
  1030. return (HSURF)hSurface;
  1031. #endif
  1032. }
  1033. }
  1034. VOID
  1035. DrvDisableSurface(
  1036. DHPDEV dhpdev
  1037. )
  1038. /*++
  1039. Routine Description:
  1040. Implementation of DDI entry point DrvDisableSurface.
  1041. Please refer to DDK documentation for more details.
  1042. Arguments:
  1043. dhpdev - Driver device handle
  1044. Return Value:
  1045. NONE
  1046. --*/
  1047. {
  1048. VERBOSE(("Entering DrvDisableSurface...\n"));
  1049. VDisableSurface( (PDEV *)dhpdev );
  1050. }
  1051. VOID
  1052. DrvDisablePDEV(
  1053. DHPDEV dhpdev
  1054. )
  1055. /*++
  1056. Routine Description:
  1057. Implementation of DDI entry point DrvDisablePDEV.
  1058. Please refer to DDK documentation for more details.
  1059. Free up all memory allocated for PDEV
  1060. Arguments:
  1061. dhpdev - Driver device handle
  1062. Return Value:
  1063. NONE
  1064. --*/
  1065. {
  1066. PDEV *pPDev = (PDEV *) dhpdev;
  1067. VERBOSE(("Entering DrvDisablePDEV...\n"));
  1068. if (!VALID_PDEV(pPDev))
  1069. {
  1070. SetLastError(ERROR_INVALID_PARAMETER);
  1071. return;
  1072. }
  1073. // ASSERT_VALID_PDEV(pPDev);
  1074. //
  1075. // Free up resources associated with the PDEV
  1076. //
  1077. FlushSpoolBuf( pPDev ); // may need to do this per bug 250963
  1078. VFreePDEVData(pPDev);
  1079. }
  1080. VOID
  1081. DrvDisableDriver(
  1082. VOID
  1083. )
  1084. /*++
  1085. Routine Description:
  1086. Implementation of DDI entry point DrvDisableDriver.
  1087. Please refer to DDK documentation for more details.
  1088. Arguments:
  1089. NONE
  1090. Return Value:
  1091. NONE
  1092. --*/
  1093. {
  1094. //
  1095. // Free everything that is allocated at DrvEnableDriver
  1096. //
  1097. VERBOSE(("Entering DrvDisableDriver...\n"));
  1098. #if ENABLE_STOCKGLYPHSET
  1099. EngAcquireSemaphore(hGlyphSetSem);
  1100. FreeGlyphSet();
  1101. EngReleaseSemaphore(hGlyphSetSem);
  1102. EngDeleteSemaphore(hGlyphSetSem) ;
  1103. #endif
  1104. #ifdef WINNT_40
  1105. ENTER_CRITICAL_SECTION();
  1106. VFreePluginRefCountList(&gpOEMPluginRefCount);
  1107. LEAVE_CRITICAL_SECTION();
  1108. DELETE_CRITICAL_SECTION();
  1109. #endif // WINNT_40
  1110. return;
  1111. }
  1112. VOID
  1113. DrvCompletePDEV(
  1114. DHPDEV dhpdev,
  1115. HDEV hdev
  1116. )
  1117. /*++
  1118. Routine Description:
  1119. Implementation of DDI entry point DrvCompletePDEV.
  1120. Please refer to DDK documentation for more details.
  1121. This function is called when the engine completed the installation of
  1122. the physical device, some Engine functions requires the engine hdev as
  1123. a parameter, so we save it in our PDEVICE for later use.
  1124. Arguments:
  1125. dhpdev - Driver device handle
  1126. hdev - GDI device handle
  1127. Return Value:
  1128. NONE
  1129. --*/
  1130. {
  1131. PDEV *pPDev = (PDEV *) dhpdev;
  1132. VERBOSE(("Entering DrvCompletePDEV...\n"));
  1133. if (!VALID_PDEV(pPDev))
  1134. {
  1135. SetLastError(ERROR_INVALID_PARAMETER);
  1136. return;
  1137. }
  1138. // ASSERT_VALID_PDEV(pPDev);
  1139. pPDev->devobj.hEngine = hdev;
  1140. }
  1141. PPDEV
  1142. PAllocPDEVData(
  1143. HANDLE hPrinter
  1144. )
  1145. /*++
  1146. Routine Description:
  1147. Allocate a new PDEV structure
  1148. Arguments:
  1149. hPrinter - handle to the current printer
  1150. Return Value:
  1151. Pointer to newly allocated PDEV structure,
  1152. NULL if there is an error
  1153. --*/
  1154. {
  1155. PDEV *pPDev;
  1156. //
  1157. // Allocate a zero-init PDEV structure and
  1158. // mark the signature fields
  1159. //
  1160. ASSERT(hPrinter != NULL);
  1161. if ((pPDev = MemAllocZ(sizeof(PDEV))) != NULL)
  1162. {
  1163. pPDev->pvStartSig = pPDev->pvEndSig = (PVOID) pPDev;
  1164. pPDev->devobj.dwSize = sizeof(DEVOBJ);
  1165. pPDev->devobj.hPrinter = hPrinter;
  1166. //
  1167. // set up pPDev->devobj.pPublicDM after pPDev->pdm has been set up
  1168. // (init.c)
  1169. //
  1170. pPDev->ulID = PDEV_ID;
  1171. }
  1172. else
  1173. ERR(("PAllocPDEVData: Memory allocation failed: %d\n", GetLastError()));
  1174. return pPDev;
  1175. }
  1176. VOID
  1177. VFreePDEVData(
  1178. PDEV * pPDev
  1179. )
  1180. /*++
  1181. Routine Description:
  1182. Dispose of a PDEV structure
  1183. Arguments:
  1184. pPDev - Pointer to a previously allocated PDEV structure
  1185. Return Value:
  1186. NONE
  1187. --*/
  1188. {
  1189. if (pPDev == NULL)
  1190. return;
  1191. VUnloadOemPlugins(pPDev);
  1192. //
  1193. // Call parser to free memory allocated for binary data
  1194. //
  1195. VUnloadFreeBinaryData(pPDev);
  1196. //
  1197. // Free other memory allocated for PDEV
  1198. //
  1199. if(pPDev->pSplForms)
  1200. {
  1201. MemFree(pPDev->pSplForms);
  1202. pPDev->pSplForms = NULL ;
  1203. }
  1204. //
  1205. // Free the output buffer
  1206. //
  1207. if(pPDev->pbOBuf )
  1208. {
  1209. MemFree(pPDev->pbOBuf);
  1210. pPDev->pbOBuf = NULL;
  1211. }
  1212. if (pPDev->pOptionsArray)
  1213. MemFree(pPDev->pOptionsArray);
  1214. //Unload Unidrv Module Handle, loaded for Unidrv resources
  1215. if (pPDev->hUniResDLL)
  1216. EngFreeModule(pPDev->hUniResDLL);
  1217. //
  1218. // Call Raster and Font module to clean up at DrvDisablePDEV
  1219. //
  1220. if (pPDev->pRasterProcs)
  1221. {
  1222. ((PRMPROCS)(pPDev->pRasterProcs))->RMDisablePDEV(pPDev);
  1223. }
  1224. if (pPDev->pFontProcs)
  1225. {
  1226. ((PFMPROCS)(pPDev->pFontProcs))->FMDisablePDEV(pPDev);
  1227. }
  1228. HANDLE_VECTORPROCS( pPDev, VMDisablePDEV, ((PDEVOBJ) pPDev)) ;
  1229. HANDLE_VECTORPROCS( pPDev, VMDisableDriver, ()) ;
  1230. //
  1231. // Free the Palette data
  1232. //
  1233. if (pPDev->pPalData)
  1234. {
  1235. //
  1236. // Free the Palette
  1237. //
  1238. if ( ((PAL_DATA *)pPDev->pPalData)->hPalette )
  1239. EngDeletePalette( ((PAL_DATA *)pPDev->pPalData)->hPalette );
  1240. if (((PAL_DATA*)(pPDev->pPalData))->pulDevPalCol)
  1241. MemFree(((PAL_DATA*)(pPDev->pPalData))->pulDevPalCol);
  1242. MemFree(pPDev->pPalData);
  1243. pPDev->pPalData = NULL;
  1244. }
  1245. //
  1246. // Free Resource Data
  1247. //
  1248. VWinResClose(&pPDev->WinResData);
  1249. // VWinResClose(&pPDev->localWinResData);
  1250. //
  1251. // Free devmode data
  1252. //
  1253. MemFree(pPDev->pdm);
  1254. MemFree(pPDev->pDriverInfo3);
  1255. if (pPDev->pbScanBuf) // may be NULL for a device surface
  1256. {
  1257. MemFree(pPDev->pbScanBuf);
  1258. }
  1259. if (pPDev->pbRasterScanBuf)
  1260. {
  1261. MemFree(pPDev->pbRasterScanBuf);
  1262. }
  1263. #ifndef DISABLE_NEWRULES
  1264. if (pPDev->pbRulesArray)
  1265. {
  1266. MemFree(pPDev->pbRulesArray);
  1267. }
  1268. #endif
  1269. //
  1270. // Free cached patterns
  1271. //
  1272. MemFree(pPDev->GState.pCachedPatterns);
  1273. //
  1274. // Free the PDEV structure itself
  1275. //
  1276. MemFree(pPDev);
  1277. }
  1278. HSURF
  1279. HCreateDeviceSurface(
  1280. PDEV * pPDev,
  1281. INT iFormat
  1282. )
  1283. /*++
  1284. Routine Description:
  1285. Creates a device surface and returns a handle that the driver
  1286. will manage.
  1287. Arguments:
  1288. pPDev - Pointer to PDEV structure
  1289. iFormat - pixel depth of the device
  1290. Return Value:
  1291. Handle to the surface if successful, NULL otherwise
  1292. --*/
  1293. {
  1294. HSURF hSurface;
  1295. SIZEL szSurface;
  1296. ASSERT_VALID_PDEV(pPDev);
  1297. szSurface.cx = pPDev->sf.szImageAreaG.cx;
  1298. szSurface.cy = pPDev->sf.szImageAreaG.cy;
  1299. hSurface = EngCreateDeviceSurface((DHSURF)pPDev, szSurface, iFormat);
  1300. if (hSurface == NULL)
  1301. {
  1302. ERR(("EngCreateDeviceSurface failed\n"));
  1303. SetLastError(ERROR_BAD_DRIVER_LEVEL);
  1304. return NULL;
  1305. }
  1306. pPDev->rcClipRgn.top = 0;
  1307. pPDev->rcClipRgn.left = 0;
  1308. pPDev->rcClipRgn.right = pPDev->sf.szImageAreaG.cx;
  1309. pPDev->rcClipRgn.bottom = pPDev->sf.szImageAreaG.cy;
  1310. pPDev->bBanding = FALSE;
  1311. pPDev->szBand.cx = szSurface.cx;
  1312. pPDev->szBand.cy = szSurface.cy;
  1313. return hSurface;
  1314. }
  1315. HBITMAP
  1316. HCreateBitmapSurface(
  1317. PDEV * pPDev,
  1318. INT iFormat
  1319. )
  1320. /*++
  1321. Routine Description:
  1322. Creates a bitmap surface and returns a handle that the driver
  1323. will manage.
  1324. Arguments:
  1325. pPDev - Pointer to PDEV structure
  1326. iFormat - pixel depth of the device
  1327. Return Value:
  1328. Handle to the bitmap if successful, NULL otherwise
  1329. --*/
  1330. {
  1331. SIZEL szSurface;
  1332. HBITMAP hBitmap;
  1333. ULONG cbScan; // Scan line byte length (DWORD aligned)
  1334. DWORD dwNumBands; // Number of bands to use
  1335. int iBPP; // Bits per pel, as # of bits
  1336. int iPins; // Basic rounding factor for banding size
  1337. PFN_OEMMemoryUsage pfnOEMMemoryUsage;
  1338. DWORD dwMaxBandSize; // Maximum size of band to use
  1339. szSurface.cx = pPDev->sf.szImageAreaG.cx;
  1340. szSurface.cy = pPDev->sf.szImageAreaG.cy;
  1341. iBPP = pPDev->sBitsPixel;
  1342. //
  1343. // define the maximum size bitmap band we will allow
  1344. //
  1345. dwMaxBandSize = MAX_SIZE_OF_BITMAP;
  1346. //
  1347. // adjust the maximum size of the bitmap buffer based on
  1348. // the amount of memory used by the OEM driver.
  1349. //
  1350. if (pPDev->pOemHookInfo && (pfnOEMMemoryUsage = (PFN_OEMMemoryUsage)pPDev->pOemHookInfo[EP_OEMMemoryUsage].pfnHook))
  1351. {
  1352. OEMMEMORYUSAGE MemoryUsage;
  1353. MemoryUsage.dwPercentMemoryUsage = 0;
  1354. MemoryUsage.dwFixedMemoryUsage = 0;
  1355. MemoryUsage.dwMaxBandSize = dwMaxBandSize;
  1356. FIX_DEVOBJ(pPDev,EP_OEMMemoryUsage);
  1357. if(pPDev->pOemEntry)
  1358. {
  1359. if(((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem ) // OEM plug in uses COM and function is implemented.
  1360. {
  1361. HRESULT hr ;
  1362. hr = HComMemoryUsage((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
  1363. (PDEVOBJ)pPDev,&MemoryUsage);
  1364. if(SUCCEEDED(hr))
  1365. ; // cool !
  1366. }
  1367. else
  1368. {
  1369. pfnOEMMemoryUsage((PDEVOBJ)pPDev,&MemoryUsage);
  1370. }
  1371. }
  1372. dwMaxBandSize = ((dwMaxBandSize - MemoryUsage.dwFixedMemoryUsage) * 100) /
  1373. (100 + MemoryUsage.dwPercentMemoryUsage);
  1374. }
  1375. if (dwMaxBandSize < (MIN_SIZE_OF_BITMAP*2L))
  1376. dwMaxBandSize = MIN_SIZE_OF_BITMAP*2L;
  1377. //
  1378. // Create a surface. Try for a bitmap for the entire surface.
  1379. // If this fails, then switch to journalling and a somewhat smaller
  1380. // surface. If journalling, we still create the bitmap here. While
  1381. // it is nicer to do this at DrvSendPage() time, we do it here to
  1382. // ensure that it is possible. By maintaining the bitmap for the
  1383. // life of the DC, we can be reasonably certain of being able to
  1384. // complete printing regardless of how tight memory becomes later.
  1385. //
  1386. cbScan = ((szSurface.cx * iBPP + DWBITS - 1) & ~(DWBITS - 1)) / BBITS;
  1387. //
  1388. // Determine the number of bands to use based on the max size of
  1389. // a band.
  1390. //
  1391. dwNumBands = ((cbScan * szSurface.cy) / dwMaxBandSize)+1;
  1392. //
  1393. // Test registry for forced number of bands for testing
  1394. //
  1395. #if DBG
  1396. {
  1397. DWORD dwType;
  1398. DWORD ul;
  1399. int RegistryBands;
  1400. if( !GetPrinterData( pPDev->devobj.hPrinter, L"Banding", &dwType,
  1401. (BYTE *)&RegistryBands, sizeof( RegistryBands ), &ul ) &&
  1402. ul == sizeof( RegistryBands ) )
  1403. {
  1404. /* Some sanity checking: if iShrinkFactor == 0, disable banding */
  1405. if (RegistryBands > 0)
  1406. dwNumBands = RegistryBands;
  1407. }
  1408. }
  1409. #endif
  1410. #ifdef BANDTEST
  1411. //
  1412. // Test code for forcing number of bands via GPD
  1413. //
  1414. if (pPDev->pGlobals->dwMaxNumPalettes > 0)
  1415. dwNumBands = pPDev->pGlobals->dwMaxNumPalettes;
  1416. #endif
  1417. //
  1418. // Time to allocate surface bitmap
  1419. //
  1420. if (dwNumBands > 1 || pPDev->fMode & PF_FORCE_BANDING ||
  1421. pPDev->pUIInfo->dwFlags & FLAG_REVERSE_BAND_ORDER ||
  1422. !(hBitmap = EngCreateBitmap( szSurface, (LONG) cbScan, iFormat, BMF_TOPDOWN|
  1423. BMF_NOZEROINIT|BMF_USERMEM, NULL )) )
  1424. {
  1425. //
  1426. // The bitmap creation failed, so we will try for smaller ones
  1427. // until we find one that is OK OR we cannot create one with
  1428. // enough scan lines to be useful.
  1429. //
  1430. //
  1431. // Calculate the rounding factor for band shrink operations.
  1432. // Basically this is to allow more effective use of the printer,
  1433. // by making the bands a multiple of the number of pins per
  1434. // pass. In interlaced mode, this is the number of scan lines
  1435. // in the interlaced band, not the number of pins in the print head.
  1436. // For single pin printers, make this a multiple of 8. This
  1437. // speeds up processing a little.
  1438. //
  1439. // If this is 1bpp we need to make the band size a multiple of the halftone
  1440. // pattern to avoid a certain GDI bug where it doesn't correctly align
  1441. // a pattern brush at the beginning of each band.
  1442. //
  1443. if (iBPP == 1 && pPDev->pResolutionEx->dwPinsPerLogPass == 1)
  1444. {
  1445. INT iPatID;
  1446. if (pPDev->pHalftone)
  1447. iPatID = pPDev->pHalftone->dwHTID;
  1448. else
  1449. iPatID= HT_PATSIZE_AUTO;
  1450. if (iPatID == HT_PATSIZE_AUTO)
  1451. {
  1452. INT dpi = pPDev->ptGrxRes.x;
  1453. if (dpi > pPDev->ptGrxRes.y)
  1454. dpi = pPDev->ptGrxRes.y;
  1455. if (dpi >= 2400) // 16x16 pattern
  1456. iPins = 16;
  1457. else if (dpi >= 1800) // 14x14 pattern
  1458. iPins = 56;
  1459. else if (dpi >= 1200) // 12x12 pattern
  1460. iPins = 24;
  1461. else if (dpi >= 800) // 10x10 pattern
  1462. iPins = 40;
  1463. else
  1464. iPins = 8;
  1465. }
  1466. else if (iPatID == HT_PATSIZE_6x6_M || iPatID == HT_PATSIZE_12x12_M)
  1467. iPins = 24;
  1468. else if (iPatID == HT_PATSIZE_10x10_M)
  1469. iPins = 40;
  1470. else if (iPatID == HT_PATSIZE_14x14_M)
  1471. iPins = 56;
  1472. else if (iPatID == HT_PATSIZE_16x16_M)
  1473. iPins = 16;
  1474. else
  1475. iPins = 8;
  1476. }
  1477. else
  1478. iPins = (pPDev->pResolutionEx->dwPinsPerLogPass + BBITS - 1) & ~(BBITS - 1);
  1479. if (dwNumBands <= 1)
  1480. dwNumBands = SHRINK_FACTOR;
  1481. while (1)
  1482. {
  1483. //
  1484. // Shrink the bitmap each time around. Note that we are
  1485. // rotation sensitive. In portrait mode, we shrink the
  1486. // Y coordinate, so that the bands fit across the page.
  1487. // In landscape when we rotate, shrink the X coordinate, since
  1488. // that becomes the Y coordinate after transposing.
  1489. //
  1490. if( pPDev->fMode & PF_ROTATE )
  1491. {
  1492. //
  1493. // We rotate the bitmap, so shrink the X coordinates.
  1494. //
  1495. szSurface.cx = pPDev->sf.szImageAreaG.cx / dwNumBands;
  1496. if( szSurface.cx < iPins)
  1497. return NULL;
  1498. szSurface.cx += iPins - (szSurface.cx % iPins);
  1499. cbScan = ((szSurface.cx * iBPP + DWBITS - 1) & ~(DWBITS - 1)) / BBITS;
  1500. }
  1501. else
  1502. {
  1503. //
  1504. // Normal operation, so shrink the Y coordinate.
  1505. //
  1506. szSurface.cy = pPDev->sf.szImageAreaG.cy / dwNumBands;
  1507. if( szSurface.cy < iPins)
  1508. return NULL;
  1509. szSurface.cy += iPins - (szSurface.cy % iPins);
  1510. }
  1511. dwNumBands *= SHRINK_FACTOR;
  1512. //
  1513. // Try to allocate the bitmap surface
  1514. //
  1515. if (hBitmap = EngCreateBitmap( szSurface, (LONG) cbScan, iFormat, BMF_TOPDOWN|BMF_NOZEROINIT|BMF_USERMEM, NULL ))
  1516. break;
  1517. //
  1518. // if we failed to allocate the bitmap surface we will give up
  1519. // at some point if the band becomes too small
  1520. //
  1521. if ((cbScan * szSurface.cy / 2) < MIN_SIZE_OF_BITMAP)
  1522. return NULL;
  1523. }
  1524. //
  1525. // Success so mark the surface for banding
  1526. //
  1527. #ifdef DISABLEDEVSURFACE
  1528. EngMarkBandingSurface((HSURF)hBitmap);
  1529. #endif
  1530. pPDev->bBanding = TRUE;
  1531. }
  1532. else
  1533. {
  1534. //
  1535. // The speedy way: into a big bitmap. Set the clipping region
  1536. // to full size, and the journal handle to 0.
  1537. //
  1538. pPDev->rcClipRgn.top = 0;
  1539. pPDev->rcClipRgn.left = 0;
  1540. pPDev->rcClipRgn.right = pPDev->sf.szImageAreaG.cx;
  1541. pPDev->rcClipRgn.bottom = pPDev->sf.szImageAreaG.cy;
  1542. pPDev->bBanding = FALSE;
  1543. }
  1544. pPDev->szBand.cx = szSurface.cx;
  1545. pPDev->szBand.cy = szSurface.cy;
  1546. return hBitmap;
  1547. }
  1548. VOID
  1549. VDisableSurface(
  1550. PDEV * pPDev
  1551. )
  1552. /*++
  1553. Routine Description:
  1554. Clean up resources allocated at DrvEnableSurface and
  1555. call Raster and Font module to clean up their internal data
  1556. and deallocated memory associated with the surface
  1557. Arguments:
  1558. pPDev - Pointer to PDEV structure
  1559. Return Value:
  1560. NONE
  1561. --*/
  1562. {
  1563. //
  1564. // Call the Raster and Font module to free
  1565. // rendering storage, position sorting memory etc.
  1566. //
  1567. ((PRMPROCS)(pPDev->pRasterProcs))->RMDisableSurface(pPDev);
  1568. ((PFMPROCS)(pPDev->pFontProcs))->FMDisableSurface(pPDev);
  1569. //
  1570. // Delete the surface
  1571. //
  1572. if( pPDev->hbm )
  1573. {
  1574. //
  1575. // unlock surface first if necessary
  1576. //
  1577. if (pPDev->pso)
  1578. {
  1579. EngUnlockSurface(pPDev->pso);
  1580. pPDev->pso = NULL;
  1581. }
  1582. EngDeleteSurface( (HSURF)pPDev->hbm );
  1583. pPDev->hbm = (HBITMAP)0;
  1584. }
  1585. if (pPDev->hSurface)
  1586. {
  1587. EngDeleteSurface (pPDev->hSurface);
  1588. pPDev->hSurface = NULL;
  1589. }
  1590. }
  1591. BOOL
  1592. BPaperSizeSourceSame(
  1593. PDEV * pPDevNew,
  1594. PDEV * pPDevOld
  1595. )
  1596. /*++
  1597. Routine Description:
  1598. This function check for the following condition:
  1599. - paper size and souce has not changed.
  1600. Arguments:
  1601. pPDevNew - Pointer to the new PDEV
  1602. pPDevOld - Pointer to the old PDEV
  1603. Return Value:
  1604. TRUE if both are unchanged, otherwise FALSE
  1605. --*/
  1606. {
  1607. // if (pPDevNew->pdm->dmOrientation == pPDevOld->pdm->dmOrientation)
  1608. // return FALSE;
  1609. //
  1610. // Check paper size, Note PDEVICE->pf.szPhysSize is in Portrait mode.
  1611. //
  1612. return (pPDevNew->pf.szPhysSizeM.cx == pPDevOld->pf.szPhysSizeM.cx &&
  1613. pPDevNew->pf.szPhysSizeM.cy == pPDevOld->pf.szPhysSizeM.cy &&
  1614. pPDevNew->pdm->dmDefaultSource == pPDevOld->pdm->dmDefaultSource
  1615. );
  1616. }
  1617. BOOL
  1618. BMergeFormToTrayAssignments(
  1619. PDEV * pPDev
  1620. )
  1621. /*++
  1622. Routine Description:
  1623. This function reads the form to tray table and merges the values in the devmode.
  1624. Arguments:
  1625. pPDev - Pointer to the PDEV
  1626. Return Value:
  1627. TRUE for success, otherwise FALSE
  1628. --*/
  1629. {
  1630. PFEATURE pInputSlotFeature;
  1631. DWORD dwInputSlotIndex, dwIndex;
  1632. POPTION pOption;
  1633. FORM_TRAY_TABLE pFormTrayTable = NULL;
  1634. PUIINFO pUIInfo = pPDev->pUIInfo;
  1635. POPTSELECT pOptionArray = pPDev->pOptionsArray;
  1636. BOOL bFound = FALSE;
  1637. PDEVMODE pdm = pPDev->pdm;
  1638. #if DBG
  1639. PTSTR pTmp;
  1640. PFEATURE pPageSizeFeature;
  1641. DWORD dwPageSizeIndex;
  1642. #endif
  1643. //
  1644. // If there is no *InputSlot feature (which shouldn't happen),
  1645. // simply ignore and return success
  1646. //
  1647. if (! (pInputSlotFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_INPUTSLOT)))
  1648. return TRUE;
  1649. dwInputSlotIndex = GET_INDEX_FROM_FEATURE(pUIInfo, pInputSlotFeature);
  1650. //
  1651. // If the input slot is "AutoSelect", then go through
  1652. // the form-to-tray assignment table and see if the
  1653. // requested form is assigned to an input slot.
  1654. //
  1655. if (((pdm->dmFields & DM_DEFAULTSOURCE) &&
  1656. (pdm->dmDefaultSource == DMBIN_FORMSOURCE)) &&
  1657. (pdm->dmFormName[0] != NUL) &&
  1658. (pFormTrayTable = PGetFormTrayTable(pPDev->devobj.hPrinter, NULL)))
  1659. {
  1660. FINDFORMTRAY FindData;
  1661. PTSTR ptstrName;
  1662. //
  1663. // Find the tray name corresponding to the requested form name
  1664. //
  1665. RESET_FINDFORMTRAY(pFormTrayTable, &FindData);
  1666. ptstrName = pdm->dmFormName;
  1667. #if 0
  1668. pTmp = pFormTrayTable;
  1669. VERBOSE(("Looking for form [%ws] in the Form Tray Table\n",ptstrName));
  1670. VERBOSE(("BEFORE SETTING: Value of pOptionArray[dwInputSlotIndex].ubCurOptIndex is = %d \n",pOptionArray[dwInputSlotIndex].ubCurOptIndex));
  1671. #endif
  1672. while (!bFound && *FindData.ptstrNextEntry)
  1673. {
  1674. if (BSearchFormTrayTable(pFormTrayTable, NULL, ptstrName, &FindData))
  1675. {
  1676. //
  1677. // Convert the tray name to an option index
  1678. //
  1679. bFound = FALSE;
  1680. //
  1681. //Search from index 1 as the first input slot is a dummy tray
  1682. //for DMBIN_FORMSOURCE.
  1683. //
  1684. for (dwIndex = 1; dwIndex < pInputSlotFeature->Options.dwCount; dwIndex++)
  1685. {
  1686. pOption = PGetIndexedOption(pUIInfo, pInputSlotFeature, dwIndex);
  1687. if (pOption->loDisplayName & GET_RESOURCE_FROM_DLL)
  1688. {
  1689. //
  1690. // loOffset specifies a string resource ID
  1691. // in the resource DLL
  1692. //
  1693. WCHAR wchbuf[MAX_DISPLAY_NAME];
  1694. //#ifdef RCSTRINGSUPPORT
  1695. #if 0
  1696. if(((pOption->loDisplayName & ~GET_RESOURCE_FROM_DLL) >= RESERVED_STRINGID_START)
  1697. && ((pOption->loDisplayName & ~GET_RESOURCE_FROM_DLL) <= RESERVED_STRINGID_END))
  1698. {
  1699. if (!ILoadStringW ( &(pPDev->localWinResData),
  1700. (pOption->loDisplayName & ~GET_RESOURCE_FROM_DLL),
  1701. wchbuf, MAX_DISPLAY_NAME) )
  1702. {
  1703. WARNING(("\n UniFont!BMergeFormToTrayAssignments:Input Tray Name not found in resource DLL\n"));
  1704. continue;
  1705. }
  1706. }
  1707. else
  1708. #endif
  1709. if (!ILoadStringW ( &(pPDev->WinResData),
  1710. (pOption->loDisplayName & ~GET_RESOURCE_FROM_DLL),
  1711. wchbuf, MAX_DISPLAY_NAME) )
  1712. {
  1713. WARNING(("\n UniFont!BMergeFormToTrayAssignments:Input Tray Name not found in resource DLL\n"));
  1714. continue;
  1715. }
  1716. ptstrName = wchbuf;
  1717. }
  1718. else
  1719. ptstrName = OFFSET_TO_POINTER(pPDev->pDriverInfo->pubResourceData, pOption->loDisplayName);
  1720. ASSERTMSG((ptstrName && FindData.ptstrTrayName),("\n NULL Tray Name,\
  1721. ptstrName = 0x%p,FindData.ptstrTrayName = 0x%p\n",
  1722. ptstrName, FindData.ptstrTrayName ));
  1723. #if 0
  1724. VERBOSE(("\nInput Tray Name for Option %d = %ws\n",dwIndex, ptstrName));
  1725. VERBOSE(("The required Tray Name = %ws\n",FindData.ptstrTrayName));
  1726. VERBOSE(("\tInput TrayName for FormTray table index %d = %ws\n",dwIndex, pTmp));
  1727. pTmp += (wcslen(pTmp) + 1);
  1728. VERBOSE(("\tForm Name for FormTray table index %d = %ws\n\n",dwIndex, pTmp));
  1729. #endif
  1730. if (ptstrName && (_tcsicmp(ptstrName, FindData.ptstrTrayName) == EQUAL_STRING))
  1731. {
  1732. pOptionArray[dwInputSlotIndex].ubCurOptIndex = (BYTE) dwIndex;
  1733. bFound = TRUE;
  1734. break;
  1735. }
  1736. }
  1737. }
  1738. }
  1739. MemFree(pFormTrayTable);
  1740. }
  1741. if (!bFound)
  1742. {
  1743. if (pFormTrayTable)
  1744. {
  1745. TERSE(("Form '%ws' is not currently assigned to a tray.\n",
  1746. pdm->dmFormName));
  1747. }
  1748. //
  1749. // Set the Inputbin option to default input Bin, if current value is
  1750. // set to dummy one.
  1751. //
  1752. if (pOptionArray[dwInputSlotIndex].ubCurOptIndex == 0)
  1753. {
  1754. pOptionArray[dwInputSlotIndex].ubCurOptIndex =
  1755. (BYTE)pInputSlotFeature->dwDefaultOptIndex;
  1756. }
  1757. }
  1758. pPDev->pdmPrivate->aOptions[dwInputSlotIndex].ubCurOptIndex = pOptionArray[dwInputSlotIndex].ubCurOptIndex;
  1759. //
  1760. //TRACE CODE
  1761. //
  1762. #if 0
  1763. if (pPageSizeFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_PAGESIZE))
  1764. dwPageSizeIndex = GET_INDEX_FROM_FEATURE(pUIInfo, pPageSizeFeature);
  1765. if (pdm->dmFields & DM_DEFAULTSOURCE)
  1766. {
  1767. VERBOSE(("DM_DEFAULTSOURCE BIT IS ON. \n"));
  1768. }
  1769. else
  1770. {
  1771. VERBOSE(("DM_DEFAULTSOURCE BIT IS OFF.\n"));
  1772. }
  1773. VERBOSE(("pdm->dmDefaultSource = %d\n",pdm->dmDefaultSource));
  1774. VERBOSE(("pFormTrayTable = 0x%p\n",pFormTrayTable));
  1775. VERBOSE(("Value of pOptionArray[dwPageSizeIndex].ubCurOptIndex = %d \n",pOptionArray[dwPageSizeIndex].ubCurOptIndex));
  1776. VERBOSE(("AFTER SETTING:Value of pOptionArray[dwInputSlotIndex].ubCurOptIndex = %d\n",pOptionArray[dwInputSlotIndex].ubCurOptIndex));
  1777. VERBOSE(("AFTER SETTING:Value of pdmPrivate->aOptions[dwInputSlotIndex].ubCurOptIndex = %d\n",pPDev->pdmPrivate->aOptions[dwInputSlotIndex].ubCurOptIndex));
  1778. VERBOSE(("Value of pInputSlotFeature->dwDefaultOptIndex is %d \n",pInputSlotFeature->dwDefaultOptIndex));
  1779. VERBOSE(("END TRACING BMergeFormToTrayAssignments.\n\n"));
  1780. #endif
  1781. return TRUE;
  1782. }
  1783. #undef FILETRACE