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.

2153 lines
59 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. Implemenation of the following initialization functions:
  7. BInitGDIInfo
  8. BInitDevInfo
  9. BInitPDEV
  10. Environment:
  11. Windows NT Unidrv driver
  12. Revision History:
  13. 10/21/96 -amandan-
  14. Created
  15. --*/
  16. #include "unidrv.h"
  17. INT iHypot( INT, INT);
  18. INT iGCD(INT, INT);
  19. VOID VInitFMode(PDEV *);
  20. VOID VInitFYMove(PDEV *);
  21. BOOL BInitOptions(PDEV *);
  22. BOOL BInitCmdTable(PDEV *);
  23. BOOL BInitStdTable(PDEV *);
  24. BOOL BInitPaperFormat(PDEV *, RECTL *);
  25. VOID VInitOutputCTL(PDEV *, PRESOLUTIONEX);
  26. VOID VGetPaperMargins(PDEV *, PAGESIZE *, PAGESIZEEX *, SIZEL, RECTL *);
  27. VOID VOptionsToDevmodeFields(PDEV *pPDev) ;
  28. VOID VSwapL(
  29. long *pl1,
  30. long *pl2)
  31. {
  32. long ltemp;
  33. ltemp = *pl1;
  34. *pl1 = *pl2;
  35. *pl2 = ltemp;
  36. }
  37. BOOL
  38. BInitPDEV (
  39. PDEV *pPDev,
  40. RECTL *prcFormImageArea
  41. )
  42. /*++
  43. Routine Description:
  44. Initialize the PDEVICE
  45. Arguments:
  46. pPDev - Points to the current PDEV structure
  47. pdm - Points to the input devmode
  48. prcFormInageArea - pointer image area of form selected
  49. Return Value:
  50. TRUE if successful, FALSE if there is an error
  51. --*/
  52. {
  53. pPDev->sCopies = pPDev->pdm->dmCopies;
  54. pPDev->pGlobals = &(pPDev->pDriverInfo->Globals);
  55. //
  56. // Initializes Options structs
  57. //
  58. if (BInitOptions(pPDev) == FALSE)
  59. return FALSE;
  60. //
  61. // Initializes pPDev->ptGrxRes and pPDev->ptTextRes based on the
  62. // current resolution selection
  63. //
  64. //
  65. // Initializes the graphics and text resolution of PDEV
  66. //
  67. ASSERT(pPDev->pResolution && pPDev->pResolutionEx);
  68. pPDev->ptGrxRes.x = pPDev->pResolutionEx->ptGrxDPI.x;
  69. pPDev->ptGrxRes.y = pPDev->pResolutionEx->ptGrxDPI.y;
  70. pPDev->ptTextRes.x = pPDev->pResolutionEx->ptTextDPI.x;
  71. pPDev->ptTextRes.y = pPDev->pResolutionEx->ptTextDPI.y;
  72. pPDev->ptGrxScale.x = pPDev->pGlobals->ptMasterUnits.x / pPDev->ptGrxRes.x;
  73. pPDev->ptGrxScale.y = pPDev->pGlobals->ptMasterUnits.y / pPDev->ptGrxRes.y;
  74. if (pPDev->pdm->dmOrientation == DMORIENT_LANDSCAPE)
  75. {
  76. VSwapL(&pPDev->ptGrxRes.x, &pPDev->ptGrxRes.y);
  77. VSwapL(&pPDev->ptTextRes.x, &pPDev->ptTextRes.y);
  78. VSwapL(&pPDev->ptGrxScale.x, &pPDev->ptGrxScale.y);
  79. }
  80. if (pPDev->pGlobals->ptDeviceUnits.x)
  81. pPDev->ptDeviceFac.x = pPDev->pGlobals->ptMasterUnits.x / pPDev->pGlobals->ptDeviceUnits.x;
  82. if (pPDev->pGlobals->ptDeviceUnits.y)
  83. pPDev->ptDeviceFac.y = pPDev->pGlobals->ptMasterUnits.y / pPDev->pGlobals->ptDeviceUnits.y;
  84. //
  85. // Init OUTPUTCTL
  86. //
  87. VInitOutputCTL(pPDev, pPDev->pResolutionEx);
  88. //
  89. // Initializes pPDev->sBitsPixel
  90. //
  91. if (pPDev->pColorModeEx != NULL)
  92. pPDev->sBitsPixel = (short)pPDev->pColorModeEx->dwDrvBPP;
  93. else
  94. pPDev->sBitsPixel = 1;
  95. //
  96. // Init PAPERFORMAT struct
  97. //
  98. ASSERT(pPDev->pPageSize != NULL);
  99. if (BInitPaperFormat(pPDev, prcFormImageArea) == FALSE)
  100. return FALSE;
  101. //
  102. // Initialize the amount of free memory in the device
  103. //
  104. if (pPDev->pMemOption)
  105. {
  106. pPDev->dwFreeMem = pPDev->pMemOption->dwFreeMem;
  107. }
  108. else
  109. {
  110. pPDev->dwFreeMem = 0;
  111. }
  112. //
  113. // Initialize the command table from the Unidrv predefined command index
  114. // as defined in GPD.H
  115. //
  116. if (BInitCmdTable(pPDev) == FALSE)
  117. return FALSE;
  118. //
  119. // Initialize the pPDev->fMode flag
  120. //
  121. VInitFMode(pPDev);
  122. //
  123. // Initialize the pPDev->fYMove flag
  124. //
  125. VInitFYMove(pPDev);
  126. //
  127. // Initialize the standard variable table in PDEVICE.
  128. // This table is used to access state variable controls by the driver
  129. //
  130. if (BInitStdTable(pPDev) == FALSE)
  131. return FALSE;
  132. //
  133. // Initialize misc. variables that need to be in pdev since
  134. // we unloads the binary data at DrvEnablePDEV and reloads it at
  135. // DrvEnableSurface
  136. //
  137. pPDev->dwMaxCopies = pPDev->pGlobals->dwMaxCopies;
  138. pPDev->dwMaxGrayFill = pPDev->pGlobals->dwMaxGrayFill;
  139. pPDev->dwMinGrayFill = pPDev->pGlobals->dwMinGrayFill;
  140. pPDev->cxafterfill = pPDev->pGlobals->cxafterfill;
  141. pPDev->cyafterfill = pPDev->pGlobals->cyafterfill;
  142. pPDev->dwCallingFuncID = INVALID_EP;
  143. return TRUE;
  144. }
  145. BOOL
  146. BInitGdiInfo(
  147. PDEV *pPDev,
  148. ULONG *pGdiInfoBuffer,
  149. ULONG ulBufferSize
  150. )
  151. /*++
  152. Routine Description:
  153. Initializes the GDIINFO struct
  154. Arguments:
  155. pPDev - Points to the current PDEV structure
  156. pGdiInfoBuffer - Points to the output GDIINFO buffer passed in from GDI
  157. ulBufferSize - Size of the output buffer
  158. Return Value:
  159. TRUE if successful, FALSE if there is an error
  160. --*/
  161. {
  162. GDIINFO gdiinfo;
  163. DEVHTINFO DevHTInfo;
  164. // initialize GDIINFO structure
  165. //
  166. ZeroMemory(&gdiinfo, sizeof(GDIINFO));
  167. //
  168. // Driver version
  169. //
  170. gdiinfo.ulVersion = UNIDRIVER_VERSION;
  171. if ( pPDev->pGlobals->printertype == PT_TTY)
  172. {
  173. pPDev->bTTY = TRUE;
  174. gdiinfo.ulTechnology = DT_CHARSTREAM;
  175. }
  176. else
  177. {
  178. pPDev->bTTY = FALSE;
  179. gdiinfo.ulTechnology = DT_RASPRINTER;
  180. }
  181. //
  182. // Width and Height of physical display in milimeters
  183. //
  184. //
  185. // Returning a negative number for ulHorzSize and ulVertSize means
  186. // the values are in micrometers. (25400 micrometer in 1 inch)
  187. //
  188. gdiinfo.ulHorzSize = (ULONG)MulDiv(-pPDev->sf.szImageAreaG.cx,
  189. 25400, pPDev->ptGrxRes.x);
  190. gdiinfo.ulVertSize = (ULONG)MulDiv(-pPDev->sf.szImageAreaG.cy,
  191. 25400, pPDev->ptGrxRes.y);
  192. //
  193. // Width and height of physical surface measured in device pixels
  194. //
  195. gdiinfo.ulHorzRes = pPDev->sf.szImageAreaG.cx;
  196. gdiinfo.ulVertRes = pPDev->sf.szImageAreaG.cy;
  197. gdiinfo.cBitsPixel = pPDev->sBitsPixel;
  198. gdiinfo.cPlanes = 1;
  199. gdiinfo.ulNumColors = (1 << gdiinfo.cBitsPixel);
  200. #ifdef WINNT_40
  201. if (gdiinfo.ulNumColors > 0x7fff)
  202. gdiinfo.ulNumColors = 0x7fff;
  203. #endif
  204. gdiinfo.flRaster = 0;
  205. gdiinfo.ulLogPixelsX = pPDev->ptGrxRes.x;
  206. gdiinfo.ulLogPixelsY = pPDev->ptGrxRes.y;
  207. //
  208. // BUG_BUG, The FMInit() function fills out gdiinfo.flTextCaps field
  209. // gdiinfo.flTextCaps = pPDev->flTextCaps;
  210. //
  211. //
  212. // The following are for Win 3.1 compatability. The X and Y values
  213. // are reversed.
  214. //
  215. gdiinfo.ulAspectX = pPDev->ptTextRes.y;
  216. gdiinfo.ulAspectY = pPDev->ptTextRes.x;
  217. gdiinfo.ulAspectXY = iHypot( gdiinfo.ulAspectX, gdiinfo.ulAspectY);
  218. //
  219. // Set the styled line information for this printer
  220. //
  221. if(pPDev->ptGrxRes.x == pPDev->ptGrxRes.y)
  222. {
  223. //
  224. // Special case: resolution is the same in both directions. This
  225. // is typically true for laser and inkjet printers.
  226. //
  227. gdiinfo.xStyleStep = 1;
  228. gdiinfo.yStyleStep = 1;
  229. gdiinfo.denStyleStep = pPDev->ptGrxRes.x / 50; // 50 elements per inch
  230. if ( gdiinfo.denStyleStep == 0 )
  231. gdiinfo.denStyleStep = 1;
  232. }
  233. else
  234. {
  235. //
  236. // Resolutions differ, so figure out lowest common multiple
  237. //
  238. INT igcd;
  239. igcd = iGCD( pPDev->ptGrxRes.x, pPDev->ptGrxRes.y);
  240. gdiinfo.xStyleStep = pPDev->ptGrxRes.y / igcd;
  241. gdiinfo.yStyleStep = pPDev->ptGrxRes.x / igcd;
  242. gdiinfo.denStyleStep = gdiinfo.xStyleStep * gdiinfo.yStyleStep / 2;
  243. }
  244. //
  245. // Size and margins of physical surface measured in device pixels
  246. //
  247. gdiinfo.ptlPhysOffset.x = pPDev->sf.ptImageOriginG.x;
  248. gdiinfo.ptlPhysOffset.y = pPDev->sf.ptImageOriginG.y;
  249. gdiinfo.szlPhysSize.cx = pPDev->sf.szPhysPaperG.cx;
  250. gdiinfo.szlPhysSize.cy = pPDev->sf.szPhysPaperG.cy;
  251. //
  252. // BUG_BUG, RMInit should fill out the following fields in GDIINFO
  253. // gdiinfo.ciDevice
  254. // gdiinfo.ulDevicePelsDPI
  255. // gdiinfo.ulPrimaryOrder
  256. // gdiinfo.ulHTPatternSize
  257. // gdiinfo.ulHTOutputFormat
  258. // gdiinfo.flHTFlags
  259. //
  260. //
  261. // Copy ulBufferSize bytes of gdiinfo to pGdiInfoBuffer.
  262. //
  263. if (ulBufferSize != sizeof(gdiinfo))
  264. ERR(("Incorrect GDIINFO buffer size: %d != %d\n", ulBufferSize, sizeof(gdiinfo)));
  265. CopyMemory(pGdiInfoBuffer, &gdiinfo, min(ulBufferSize, sizeof(gdiinfo)));
  266. return TRUE;
  267. }
  268. BOOL
  269. BInitDevInfo(
  270. PDEV *pPDev,
  271. DEVINFO *pDevInfoBuffer,
  272. ULONG ulBufferSize
  273. )
  274. /*++
  275. Routine Description:
  276. Initialize the output DEVINFO buffer
  277. Arguments:
  278. pPDev - Points to the current PDEV structure
  279. pDevInfoBuffer - Points to the output DEVINFO buffer passed in from GDI
  280. ulBufferSize - Size of the output buffer
  281. Return Value:
  282. TRUE if successful, FALSE if there is an error
  283. --*/
  284. {
  285. DEVINFO devinfo;
  286. ZeroMemory(&devinfo, sizeof(devinfo));
  287. //
  288. // Fill in the graphics capabilities flags
  289. // BUBUG, RMInit() function should fill out devinfo.flGraphicsCaps
  290. // should fill this out later
  291. //
  292. //
  293. // Determine whether we should do metafile spooling or not
  294. //
  295. if( pPDev->pdmPrivate->dwFlags & DXF_NOEMFSPOOL )
  296. devinfo.flGraphicsCaps |= GCAPS_DONTJOURNAL;
  297. #ifndef WINNT_40 // NT5
  298. if (pPDev->pdmPrivate->iLayout != ONE_UP)
  299. devinfo.flGraphicsCaps |= GCAPS_NUP;
  300. #endif // !WINNT_40
  301. //
  302. // Get information about the default device font. Default size 10 point.
  303. //
  304. //
  305. // BUG_BUG, RMInit() should initialize the following DEVINFO fields
  306. // flGraphicsCaps
  307. // iDitherFormat
  308. // cxDither
  309. // cyDither
  310. // hpalDefault
  311. //
  312. if (ulBufferSize != sizeof(devinfo))
  313. ERR(("Invalid DEVINFO buffer size: %d != %d\n", ulBufferSize, sizeof(devinfo)));
  314. CopyMemory(pDevInfoBuffer, &devinfo, min(ulBufferSize, sizeof(devinfo)));
  315. return TRUE;
  316. }
  317. BOOL
  318. BInitCmdTable(
  319. PDEV *pPDev
  320. )
  321. /*++
  322. Routine Description:
  323. The GPD specification defines a list of predefined command. Each of these
  324. command has an enumration value as defined in CMDINDEX enumeration.
  325. This function will look up the indices of the predefined command and
  326. convert them to COMMAND pointers.
  327. Arguments:
  328. pPDev - Points to the current PDEV structure
  329. Return Value:
  330. TRUE if successful, FALSE if there is an error
  331. --*/
  332. {
  333. INT iCmd;
  334. for (iCmd = 0; iCmd < CMD_MAX; iCmd++)
  335. {
  336. //
  337. // CMDPOINTER will return NULL if the predefined command
  338. // is not supported by the device
  339. //
  340. pPDev->arCmdTable[iCmd] = COMMANDPTR(pPDev->pDriverInfo, iCmd);
  341. }
  342. return TRUE;
  343. }
  344. BOOL
  345. BInitStdTable(
  346. PDEV *pPDev
  347. )
  348. /*++
  349. Routine Description:
  350. Initialize the array of pointers to the standard variables. In the TOKENSTREAM
  351. struct, the parser will specify the actual parameter value or reference to one
  352. of the standard variable index defined in STDVARIABLE enumeration. The
  353. driver use the pPDev->arStdPtrs to reference the actual values of the paramters,
  354. which are kept in various fields of the PDEVICE.
  355. Arguments:
  356. pPDev - Points to the current PDEV structure
  357. Return Value:
  358. TRUE if successful, FALSE if there is an error
  359. --*/
  360. {
  361. //
  362. // BUG_BUG, need to go back and fill this table out completely once
  363. // the FONT and RASTER PDEVICE are completely defined.
  364. // note: I could not find any uninitialized sv_fields.
  365. // perhaps this is too paranoid.
  366. //
  367. pPDev->arStdPtrs[SV_NUMDATABYTES] = &pPDev->dwNumOfDataBytes;
  368. pPDev->arStdPtrs[SV_WIDTHINBYTES] = &pPDev->dwWidthInBytes;
  369. pPDev->arStdPtrs[SV_HEIGHTINPIXELS] = &pPDev->dwHeightInPixels;
  370. pPDev->arStdPtrs[SV_COPIES] = (PDWORD)&pPDev->sCopies;
  371. pPDev->arStdPtrs[SV_PRINTDIRECTION] = &pPDev->dwPrintDirection;
  372. pPDev->arStdPtrs[SV_DESTX] = &pPDev->ctl.ptAbsolutePos.x;
  373. pPDev->arStdPtrs[SV_DESTY] = &pPDev->ctl.ptAbsolutePos.y;
  374. pPDev->arStdPtrs[SV_DESTXREL] = &pPDev->ctl.ptRelativePos.x;
  375. pPDev->arStdPtrs[SV_DESTYREL] = &pPDev->ctl.ptRelativePos.y;
  376. pPDev->arStdPtrs[SV_LINEFEEDSPACING]= (PDWORD)&pPDev->ctl.lLineSpacing;
  377. pPDev->arStdPtrs[SV_RECTXSIZE] = &pPDev->dwRectXSize;
  378. pPDev->arStdPtrs[SV_RECTYSIZE] = &pPDev->dwRectYSize;
  379. pPDev->arStdPtrs[SV_GRAYPERCENT] = &pPDev->dwGrayPercentage;
  380. pPDev->arStdPtrs[SV_NEXTFONTID] = &pPDev->dwNextFontID;
  381. pPDev->arStdPtrs[SV_NEXTGLYPH] = &pPDev->dwNextGlyph;
  382. pPDev->arStdPtrs[SV_PHYSPAPERLENGTH]= &pPDev->pf.szPhysSizeM.cy;
  383. pPDev->arStdPtrs[SV_PHYSPAPERWIDTH] = &pPDev->pf.szPhysSizeM.cx;
  384. pPDev->arStdPtrs[SV_FONTHEIGHT] = &pPDev->dwFontHeight;
  385. pPDev->arStdPtrs[SV_FONTWIDTH] = &pPDev->dwFontWidth;
  386. pPDev->arStdPtrs[SV_FONTMAXWIDTH] = &pPDev->dwFontMaxWidth;
  387. pPDev->arStdPtrs[SV_FONTBOLD] = &pPDev->dwFontBold;
  388. pPDev->arStdPtrs[SV_FONTITALIC] = &pPDev->dwFontItalic;
  389. pPDev->arStdPtrs[SV_FONTUNDERLINE] = &pPDev->dwFontUnderline;
  390. pPDev->arStdPtrs[SV_FONTSTRIKETHRU] = &pPDev->dwFontStrikeThru;
  391. pPDev->arStdPtrs[SV_CURRENTFONTID] = &pPDev->dwCurrentFontID;
  392. pPDev->arStdPtrs[SV_TEXTYRES] = &pPDev->ptTextRes.y;
  393. pPDev->arStdPtrs[SV_TEXTXRES] = &pPDev->ptTextRes.x;
  394. #ifdef BETA2
  395. pPDev->arStdPtrs[SV_GRAPHICSYRES] = &pPDev->ptGrxRes.y;
  396. pPDev->arStdPtrs[SV_GRAPHICSXRES] = &pPDev->ptGrxRes.x;
  397. #endif
  398. pPDev->arStdPtrs[SV_ROP3] = &pPDev->dwRop3;
  399. pPDev->arStdPtrs[SV_REDVALUE] = &pPDev->dwRedValue ;
  400. pPDev->arStdPtrs[SV_GREENVALUE] = &pPDev->dwGreenValue ;
  401. pPDev->arStdPtrs[SV_BLUEVALUE] = &pPDev->dwBlueValue ;
  402. pPDev->arStdPtrs[SV_PALETTEINDEXTOPROGRAM] = &pPDev->dwPaletteIndexToProgram;
  403. pPDev->arStdPtrs[SV_CURRENTPALETTEINDEX] = &pPDev->dwCurrentPaletteIndex ;
  404. pPDev->arStdPtrs[SV_PATTERNBRUSH_TYPE] = &pPDev->dwPatternBrushType;
  405. pPDev->arStdPtrs[SV_PATTERNBRUSH_ID] = &pPDev->dwPatternBrushID;
  406. pPDev->arStdPtrs[SV_PATTERNBRUSH_SIZE] = &pPDev->dwPatternBrushSize;
  407. pPDev->arStdPtrs[SV_CURSORORIGINX] = &(pPDev->sf.ptPrintOffsetM.x);
  408. pPDev->arStdPtrs[SV_CURSORORIGINY] = &(pPDev->sf.ptPrintOffsetM.y);
  409. pPDev->arStdPtrs[SV_PAGENUMBER] = &pPDev->dwPageNumber;
  410. return TRUE;
  411. }
  412. BOOL
  413. BMergeAndValidateDevmode(
  414. PDEV *pPDev,
  415. PDEVMODE pdmInput,
  416. PRECTL prcFormImageArea
  417. )
  418. /*++
  419. Routine Description:
  420. Validate the input devmode and merge it with the defaults
  421. Arguments:
  422. pPDev - Points to the current PDEV structure
  423. pdmInput - Points to the input devmode passed in from GDI
  424. prcImageArea - Returns the logical imageable area associated with the requested form
  425. Return Value:
  426. TRUE if successful, FALSE if there is an error
  427. --*/
  428. {
  429. PPRINTER_INFO_2 pPrinterInfo2;
  430. //
  431. // Start with the driver default devmode
  432. //
  433. pPDev->pdm = PGetDefaultDevmodeWithOemPlugins(
  434. NULL,
  435. pPDev->pUIInfo,
  436. pPDev->pRawData,
  437. (pPDev->PrinterData.dwFlags & PFLAGS_METRIC),
  438. pPDev->pOemPlugins,
  439. pPDev->devobj.hPrinter);
  440. if (pPDev->pdm == NULL)
  441. return FALSE;
  442. //
  443. // Merge with system default devmode. In the case where the input devmode
  444. // is NULL, we want to use the system default devmode.
  445. //
  446. pPrinterInfo2 = MyGetPrinter(pPDev->devobj.hPrinter, 2);
  447. if (pPrinterInfo2 && pPrinterInfo2->pDevMode &&
  448. ! BValidateAndMergeDevmodeWithOemPlugins(
  449. pPDev->pdm,
  450. pPDev->pUIInfo,
  451. pPDev->pRawData,
  452. pPrinterInfo2->pDevMode,
  453. pPDev->pOemPlugins,
  454. pPDev->devobj.hPrinter))
  455. {
  456. MemFree(pPrinterInfo2);
  457. return FALSE;
  458. }
  459. MemFree(pPrinterInfo2);
  460. //
  461. // Merge it with the input devmode
  462. //
  463. if (pdmInput != NULL &&
  464. !BValidateAndMergeDevmodeWithOemPlugins(
  465. pPDev->pdm,
  466. pPDev->pUIInfo,
  467. pPDev->pRawData,
  468. pdmInput,
  469. pPDev->pOemPlugins,
  470. pPDev->devobj.hPrinter))
  471. {
  472. return FALSE;
  473. }
  474. pPDev->pdmPrivate = (PUNIDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pPDev->pdm);
  475. //
  476. // Validate form-related devmode fields and convert information
  477. // in public devmode fields to feature option indices
  478. //
  479. //
  480. // ChangeOptionsViaID expects a combined option array
  481. //
  482. CombineOptionArray(pPDev->pRawData,
  483. pPDev->pOptionsArray,
  484. MAX_PRINTER_OPTIONS,
  485. pPDev->pdmPrivate->aOptions,
  486. pPDev->PrinterData.aOptions
  487. );
  488. VFixOptionsArray( pPDev,
  489. /* pPDev->devobj.hPrinter,
  490. pPDev->pInfoHeader,
  491. pPDev->pOptionsArray,
  492. pPDev->pdm,
  493. pPDev->PrinterData.dwFlags & PFLAGS_METRIC, */
  494. prcFormImageArea
  495. );
  496. VOptionsToDevmodeFields( pPDev) ;
  497. SeparateOptionArray(
  498. pPDev->pRawData,
  499. pPDev->pOptionsArray,
  500. pPDev->pdmPrivate->aOptions,
  501. MAX_PRINTER_OPTIONS,
  502. MODE_DOCUMENT_STICKY);
  503. pPDev->devobj.pPublicDM = pPDev->pdm;
  504. return TRUE;
  505. }
  506. VOID
  507. VOptionsToDevmodeFields(
  508. PDEV *pPDev
  509. )
  510. /*++
  511. Routine Description:
  512. Convert options in pPDev->pOptionsArray into public devmode fields
  513. Arguments:
  514. pPDev - Points to UIDATA structure
  515. Return Value:
  516. None
  517. --*/
  518. {
  519. PFEATURE pFeature;
  520. POPTION pOption;
  521. DWORD dwGID, dwFeatureIndex, dwOptionIndex;
  522. PUIINFO pUIInfo;
  523. PDEVMODE pdm;
  524. //
  525. // Go through all predefine IDs and propagate the option selection
  526. // into appropriate devmode fields
  527. //
  528. pUIInfo = pPDev->pUIInfo;
  529. pdm = pPDev->pdm;
  530. for (dwGID=0 ; dwGID < MAX_GID ; dwGID++)
  531. {
  532. //
  533. // Get the feature to get the options, and get the index
  534. // into the option array
  535. //
  536. if ((pFeature = GET_PREDEFINED_FEATURE(pUIInfo, dwGID)) == NULL)
  537. {
  538. switch(dwGID)
  539. {
  540. case GID_RESOLUTION:
  541. break; // can't happen
  542. case GID_DUPLEX:
  543. pdm->dmFields &= ~DM_DUPLEX;
  544. pdm->dmDuplex = DMDUP_SIMPLEX;
  545. break;
  546. case GID_INPUTSLOT:
  547. pdm->dmFields &= ~DM_DEFAULTSOURCE;
  548. pdm->dmDefaultSource = DMBIN_ONLYONE;
  549. break;
  550. case GID_MEDIATYPE:
  551. pdm->dmFields &= ~DM_MEDIATYPE;
  552. pdm->dmMediaType = DMMEDIA_STANDARD;
  553. break;
  554. case GID_ORIENTATION:
  555. pdm->dmFields &= ~DM_ORIENTATION;
  556. pdm->dmOrientation = DMORIENT_PORTRAIT;
  557. break;
  558. case GID_PAGESIZE: // can't happen : required feature
  559. break;
  560. case GID_COLLATE:
  561. pdm->dmFields &= ~DM_COLLATE ;
  562. pdm->dmCollate = DMCOLLATE_FALSE ;
  563. break;
  564. }
  565. continue;
  566. }
  567. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pUIInfo, pFeature);
  568. dwOptionIndex = pPDev->pOptionsArray[dwFeatureIndex].ubCurOptIndex;
  569. //
  570. // Get the pointer to the option array for the feature
  571. //
  572. if ((pOption = PGetIndexedOption(pUIInfo, pFeature, dwOptionIndex)) == NULL)
  573. continue;
  574. switch(dwGID)
  575. {
  576. case GID_RESOLUTION:
  577. {
  578. PRESOLUTION pRes = (PRESOLUTION)pOption;
  579. //
  580. // Get to the option selected
  581. //
  582. pdm->dmFields |= (DM_PRINTQUALITY|DM_YRESOLUTION);
  583. pdm->dmPrintQuality = GETQUALITY_X(pRes);
  584. pdm->dmYResolution = GETQUALITY_Y(pRes);
  585. }
  586. break;
  587. case GID_DUPLEX:
  588. //
  589. // Get to the option selected
  590. //
  591. pdm->dmFields |= DM_DUPLEX;
  592. pdm->dmDuplex = (SHORT) ((PDUPLEX) pOption)->dwDuplexID;
  593. break;
  594. case GID_INPUTSLOT:
  595. //
  596. // Get to the option selected
  597. //
  598. pdm->dmFields |= DM_DEFAULTSOURCE;
  599. pdm->dmDefaultSource = (SHORT) ((PINPUTSLOT) pOption)->dwPaperSourceID;
  600. break;
  601. case GID_MEDIATYPE:
  602. //
  603. // Get to the option selected
  604. //
  605. pdm->dmFields |= DM_MEDIATYPE;
  606. pdm->dmMediaType = (SHORT) ((PMEDIATYPE) pOption)->dwMediaTypeID;
  607. break;
  608. case GID_ORIENTATION:
  609. if (((PORIENTATION) pOption)->dwRotationAngle == ROTATE_NONE)
  610. pdm->dmOrientation = DMORIENT_PORTRAIT;
  611. else
  612. pdm->dmOrientation = DMORIENT_LANDSCAPE;
  613. pdm->dmFields |= DM_ORIENTATION;
  614. break;
  615. case GID_COLLATE:
  616. pdm->dmFields |= DM_COLLATE ;
  617. pdm->dmCollate = (SHORT) ((PCOLLATE) pOption)->dwCollateID ;
  618. break;
  619. case GID_PAGESIZE: // taken care of by BValidateDevmodeFormFields()
  620. // which is called from init.c:VFixOptionsArray()
  621. break;
  622. }
  623. }
  624. }
  625. VOID
  626. VInitOutputCTL(
  627. PDEV *pPDev,
  628. PRESOLUTIONEX pResEx
  629. )
  630. /*++
  631. Routine Description:
  632. Initializes the OUTPUTCTL struct
  633. Arguments:
  634. pPDev - Points to the current PDEV structure
  635. Return Value:
  636. None
  637. --*/
  638. {
  639. //
  640. // Init currrent cursor position, desired absolute and relative pos
  641. //
  642. pPDev->ctl.ptCursor.x = pPDev->ctl.ptCursor.y = 0;
  643. pPDev->ctl.dwMode |= MODE_CURSOR_UNINITIALIZED;
  644. pPDev->ctl.ptRelativePos.x = pPDev->ctl.ptRelativePos.y = 0;
  645. pPDev->ctl.ptAbsolutePos.x = pPDev->ctl.ptAbsolutePos.y = 0;
  646. //
  647. // Init sColor which represent last grx and text color chosen
  648. //
  649. if (pPDev->pUIInfo->dwFlags & FLAG_COLOR_DEVICE)
  650. {
  651. //
  652. // Force sending the color command sequence before any output
  653. //
  654. pPDev->ctl.sColor = -1;
  655. }
  656. else
  657. {
  658. //
  659. // The device is monochrome, don't send color command sequence
  660. // before output
  661. //
  662. pPDev->ctl.sColor = 0;
  663. }
  664. //
  665. // Init lLineSpacing, which represents the last line spacing chosen
  666. // init to -1 to indicate unknown state
  667. //
  668. pPDev->ctl.lLineSpacing = -1;
  669. //
  670. // Init the sBytesPerPinPass which represents the physical number
  671. // of bytes per row of printhead
  672. //
  673. pPDev->ctl.sBytesPerPinPass = (SHORT)((pResEx->dwPinsPerPhysPass + 7) >> 3);
  674. }
  675. BOOL
  676. BInitOptions(
  677. PDEV *pPDev
  678. )
  679. /*++
  680. Routine Description:
  681. This function looked at the currently selected UI options (stored in
  682. DEVMODE and merged into combined options array - pDevice->pOptionsArray)
  683. It stored the option structures for predefined features in the PDEVICE
  684. for later access.
  685. Arguments:
  686. pPDev - Points to the current PDEV structure
  687. Return Value:
  688. TRUE if successful and FALSE if not
  689. --*/
  690. {
  691. WORD wGID;
  692. PFEATURE pFeature;
  693. DWORD dwFeatureIndex;
  694. POPTSELECT pOptions;
  695. pOptions = pPDev->pOptionsArray;
  696. for ( wGID = 0 ; wGID < MAX_GID; wGID++)
  697. {
  698. switch (wGID)
  699. {
  700. case GID_RESOLUTION:
  701. {
  702. //
  703. // Required feature
  704. //
  705. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_RESOLUTION))
  706. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  707. else
  708. return FALSE;
  709. pPDev->pResolution = (PRESOLUTION)PGetIndexedOption(
  710. pPDev->pUIInfo,
  711. pFeature,
  712. pOptions[dwFeatureIndex].ubCurOptIndex);
  713. pPDev->pResolutionEx = OFFSET_TO_POINTER(pPDev->pInfoHeader,
  714. pPDev->pResolution->GenericOption.loRenderOffset);
  715. ASSERT(pPDev->pResolution && pPDev->pResolutionEx);
  716. }
  717. break;
  718. case GID_PAGESIZE:
  719. {
  720. //
  721. // Required feature
  722. //
  723. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_PAGESIZE))
  724. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  725. else
  726. return FALSE;
  727. pPDev->pPageSize = (PPAGESIZE)PGetIndexedOption(
  728. pPDev->pUIInfo,
  729. pFeature,
  730. pOptions[dwFeatureIndex].ubCurOptIndex);
  731. pPDev->pPageSizeEx = OFFSET_TO_POINTER(pPDev->pInfoHeader,
  732. pPDev->pPageSize->GenericOption.loRenderOffset);
  733. ASSERT(pPDev->pPageSize &&
  734. pPDev->pPageSizeEx );
  735. }
  736. break;
  737. case GID_DUPLEX:
  738. {
  739. //
  740. // Optional
  741. //
  742. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_DUPLEX))
  743. {
  744. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  745. pPDev->pDuplex = (PDUPLEX)PGetIndexedOption(
  746. pPDev->pUIInfo,
  747. pFeature,
  748. pOptions[dwFeatureIndex].ubCurOptIndex);
  749. }
  750. else
  751. {
  752. pPDev->pDuplex = NULL;
  753. }
  754. }
  755. break;
  756. case GID_INPUTSLOT:
  757. {
  758. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_INPUTSLOT))
  759. {
  760. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  761. pPDev->pInputSlot = (PINPUTSLOT)PGetIndexedOption(
  762. pPDev->pUIInfo,
  763. pFeature,
  764. pOptions[dwFeatureIndex].ubCurOptIndex);
  765. ASSERT(pPDev->pInputSlot);
  766. #if 0
  767. //
  768. // InputSlotEx struct is deleted.
  769. //
  770. pPDev->pInputSlotEx = OFFSET_TO_POINTER(pPDev->pInfoHeader,
  771. pPDev->pInputSlot->GenericOption.loRenderOffset);
  772. ASSERT(pPDev->pInputSlotEx);
  773. #endif
  774. }
  775. else
  776. {
  777. pPDev->pInputSlot = NULL;
  778. // pPDev->pInputSlotEx = NULL;
  779. }
  780. }
  781. break;
  782. case GID_MEMOPTION:
  783. {
  784. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_MEMOPTION))
  785. {
  786. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  787. pPDev->pMemOption = (PMEMOPTION)PGetIndexedOption(
  788. pPDev->pUIInfo,
  789. pFeature,
  790. pOptions[dwFeatureIndex].ubCurOptIndex);
  791. }
  792. else
  793. {
  794. pPDev->pMemOption = NULL;
  795. }
  796. }
  797. break;
  798. case GID_COLORMODE:
  799. {
  800. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_COLORMODE))
  801. {
  802. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  803. pPDev->pColorMode = (PCOLORMODE)PGetIndexedOption(
  804. pPDev->pUIInfo,
  805. pFeature,
  806. pOptions[dwFeatureIndex].ubCurOptIndex);
  807. pPDev->pColorModeEx = OFFSET_TO_POINTER(pPDev->pInfoHeader,
  808. pPDev->pColorMode->GenericOption.loRenderOffset);
  809. }
  810. else
  811. {
  812. pPDev->pColorMode = NULL;
  813. }
  814. }
  815. break;
  816. case GID_ORIENTATION:
  817. {
  818. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_ORIENTATION))
  819. {
  820. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  821. pPDev->pOrientation = (PORIENTATION)PGetIndexedOption(
  822. pPDev->pUIInfo,
  823. pFeature,
  824. pOptions[dwFeatureIndex].ubCurOptIndex);
  825. }
  826. else
  827. {
  828. pPDev->pOrientation = NULL;
  829. }
  830. }
  831. break;
  832. case GID_PAGEPROTECTION:
  833. {
  834. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_PAGEPROTECTION))
  835. {
  836. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  837. pPDev->pPageProtect = (PPAGEPROTECT)PGetIndexedOption(
  838. pPDev->pUIInfo,
  839. pFeature,
  840. pOptions[dwFeatureIndex].ubCurOptIndex);
  841. }
  842. else
  843. {
  844. pPDev->pPageProtect = NULL;
  845. }
  846. }
  847. break;
  848. case GID_HALFTONING:
  849. {
  850. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_HALFTONING))
  851. {
  852. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  853. pPDev->pHalftone = (PHALFTONING)PGetIndexedOption(
  854. pPDev->pUIInfo,
  855. pFeature,
  856. pOptions[dwFeatureIndex].ubCurOptIndex);
  857. }
  858. else
  859. {
  860. pPDev->pHalftone = NULL;
  861. }
  862. }
  863. break;
  864. #if 0
  865. case GID_MEDIATYPE:
  866. {
  867. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_MEDIATYPE))
  868. {
  869. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  870. pPDev->pMediaType = (PMEDIATYPE)PGetIndexedOption(
  871. pPDev->pUIInfo,
  872. pFeature,
  873. pOptions[dwFeatureIndex].ubCurOptIndex);
  874. }
  875. else
  876. {
  877. pPDev->pMediaType = NULL;
  878. }
  879. }
  880. break;
  881. case GID_COLLATE:
  882. {
  883. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_COLLATE))
  884. {
  885. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  886. pPDev->pCollate = PGetIndexedOption(
  887. pPDev->pUIInfo,
  888. pFeature,
  889. pOptions[dwFeatureIndex].ubCurOptIndex);
  890. }
  891. else
  892. {
  893. pPDev->pCollate = NULL;
  894. }
  895. }
  896. break;
  897. case GID_OUTPUTBIN:
  898. {
  899. if (pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_OUTPUTBIN))
  900. {
  901. dwFeatureIndex = GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature);
  902. pPDev->pOutputBin = PGetIndexedOption(
  903. pPDev->pUIInfo,
  904. pFeature,
  905. pOptions[dwFeatureIndex].ubCurOptIndex);
  906. }
  907. else
  908. {
  909. pPDev->pOutputBin = NULL;
  910. }
  911. }
  912. break;
  913. #endif
  914. default:
  915. break;
  916. }
  917. }
  918. return TRUE;
  919. }
  920. BOOL
  921. BInitPaperFormat(
  922. PDEV *pPDev,
  923. RECTL *pFormImageArea
  924. )
  925. /*++
  926. Routine Description:
  927. Figure out the currently selected paper size and initialize
  928. the PAPERFORMAT & SURFACEFORMAT structs
  929. Arguments:
  930. pPDev - Pointer to PDEVICE
  931. pFormImageArea - Pointer to Imageable area of the form
  932. Return Value:
  933. TRUE if successful, FALSE if there is an error
  934. Note:
  935. The followings are assumptions made by this function regarding information
  936. in the parser snapshot.
  937. - szPaperSize in PAGESIZE is always in portrait mode.
  938. - szImageArea in PAGESIZE is always in portrait mode.
  939. - ptImageOrigin in PAGESIZE is always in portrait mode.
  940. - Printer cursor offset calculation is dependent of pGlobals->bRotateCoordinate.
  941. If this is set to TRUE, must calculate it according to the rotation angle
  942. specified in ORIENATION.dwRotationAngle
  943. --*/
  944. {
  945. PPAGESIZE pPaper;
  946. PPAGESIZEEX pPaperEx;
  947. RECTL rcMargins, rcImgArea, rcIntersectArea;
  948. SIZEL szPaperSize, szImageArea;
  949. PFN_OEMTTYGetInfo pfnOemTTYGetInfo;
  950. DWORD cbcNeeded;
  951. BOOL bOEMinfo = FALSE ;
  952. //
  953. // Get the current selected paper size and paper source
  954. //
  955. pPaper = pPDev->pPageSize;
  956. pPaperEx = pPDev->pPageSizeEx;
  957. ASSERT(pPaper && pPaperEx);
  958. //
  959. // Convert pFormImageArea from microns to master units
  960. //
  961. pFormImageArea->left = MICRON_TO_MASTER(pFormImageArea->left,
  962. pPDev->pGlobals->ptMasterUnits.x);
  963. pFormImageArea->top = MICRON_TO_MASTER(pFormImageArea->top ,
  964. pPDev->pGlobals->ptMasterUnits.y);
  965. pFormImageArea->right = MICRON_TO_MASTER(pFormImageArea->right ,
  966. pPDev->pGlobals->ptMasterUnits.x);
  967. pFormImageArea->bottom = MICRON_TO_MASTER(pFormImageArea->bottom ,
  968. pPDev->pGlobals->ptMasterUnits.y);
  969. //
  970. // If it's a user defined paper size, use the dimensions in devmode
  971. // otherwise get it from the pagesize option
  972. //
  973. if (pPaper->dwPaperSizeID == DMPAPER_USER)
  974. {
  975. //
  976. // Need to convert from 0.1mm to micrometer
  977. // .1mm * 100 gives micrometer. and convert to Master unit
  978. //
  979. szPaperSize.cx = MICRON_TO_MASTER(
  980. pPDev->pdm->dmPaperWidth * 100,
  981. pPDev->pGlobals->ptMasterUnits.x);
  982. szPaperSize.cy = MICRON_TO_MASTER(
  983. pPDev->pdm->dmPaperLength * 100,
  984. pPDev->pGlobals->ptMasterUnits.y);
  985. // calculate szImageArea after margins
  986. }
  987. else
  988. {
  989. CopyMemory(&szPaperSize, &pPaper->szPaperSize, sizeof(SIZEL));
  990. CopyMemory(&szImageArea, &pPaperEx->szImageArea, sizeof(SIZEL));
  991. //
  992. // Exchange X & Y dimensions: This is used only when the paper size( like
  993. // envelopes) does not suit the printer's paper feeding method.
  994. // equivalent to PS_ROTATE in GPC
  995. //
  996. if (pPaperEx->bRotateSize)
  997. {
  998. VSwapL(&szPaperSize.cx, &szPaperSize.cy);
  999. VSwapL(&pFormImageArea->right, &pFormImageArea->bottom);
  1000. }
  1001. }
  1002. //
  1003. // GetPaperMargins calculates the margins based on the paper size margins,
  1004. // forms margins, and feed margins.
  1005. // rcMargins returned is in portrait mode
  1006. //
  1007. bOEMinfo = FALSE ;
  1008. if (pPDev->pGlobals->printertype == PT_TTY)
  1009. {
  1010. if (!pPDev->pOemHookInfo || !(pPDev->pOemHookInfo[EP_OEMTTYGetInfo].pOemEntry))
  1011. return(FALSE) ; // TTY driver must support this function.
  1012. FIX_DEVOBJ(pPDev, EP_OEMTTYGetInfo);
  1013. if(pPDev->pOemEntry)
  1014. {
  1015. if( ((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem ) // OEM plug in uses COM and function is implemented.
  1016. {
  1017. HRESULT hr ;
  1018. hr = HComTTYGetInfo((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
  1019. (PDEVOBJ)pPDev, OEMTTY_INFO_MARGINS, &rcMargins, sizeof(RECTL), &cbcNeeded);
  1020. if(!SUCCEEDED(hr))
  1021. bOEMinfo = FALSE ;
  1022. else
  1023. bOEMinfo = TRUE ;
  1024. }
  1025. else if( (pfnOemTTYGetInfo = (PFN_OEMTTYGetInfo)pPDev->pOemHookInfo[EP_OEMTTYGetInfo].pfnHook) &&
  1026. (pfnOemTTYGetInfo((PDEVOBJ)pPDev, OEMTTY_INFO_MARGINS, &rcMargins, sizeof(RECTL), &cbcNeeded)))
  1027. bOEMinfo = TRUE ;
  1028. }
  1029. }
  1030. if(bOEMinfo)
  1031. {
  1032. //
  1033. // Need to convert .1mm to Master Units
  1034. //
  1035. rcMargins.left = MICRON_TO_MASTER(rcMargins.left * 100,
  1036. pPDev->pGlobals->ptMasterUnits.x);
  1037. rcMargins.top = MICRON_TO_MASTER(rcMargins.top * 100,
  1038. pPDev->pGlobals->ptMasterUnits.y);
  1039. rcMargins.right = MICRON_TO_MASTER(rcMargins.right * 100,
  1040. pPDev->pGlobals->ptMasterUnits.x);
  1041. rcMargins.bottom = MICRON_TO_MASTER(rcMargins.bottom * 100,
  1042. pPDev->pGlobals->ptMasterUnits.y);
  1043. }
  1044. else
  1045. {
  1046. VGetPaperMargins(pPDev, pPaper, pPaperEx, szPaperSize, &rcMargins);
  1047. }
  1048. if (pPaper->dwPaperSizeID == DMPAPER_USER)
  1049. {
  1050. szImageArea.cx = szPaperSize.cx - rcMargins.left - rcMargins.right;
  1051. szImageArea.cy = szPaperSize.cy - rcMargins.top - rcMargins.bottom;
  1052. }
  1053. //
  1054. // Adjust margins and szImageArea to take into account the
  1055. // form margins, just in case the form is not a built-in form
  1056. //
  1057. rcImgArea.left = rcMargins.left;
  1058. rcImgArea.top = rcMargins.top;
  1059. rcImgArea.right = rcMargins.left + szImageArea.cx;
  1060. rcImgArea.bottom = rcMargins.top + szImageArea.cy;
  1061. if (!BIntersectRect(&rcIntersectArea, &rcImgArea, pFormImageArea))
  1062. return FALSE;
  1063. rcMargins.left = rcIntersectArea.left;
  1064. rcMargins.top = rcIntersectArea.top;
  1065. rcMargins.right = szPaperSize.cx - rcIntersectArea.right;
  1066. rcMargins.bottom = szPaperSize.cy - rcIntersectArea.bottom;
  1067. szImageArea.cx = rcIntersectArea.right - rcIntersectArea.left;
  1068. szImageArea.cy = rcIntersectArea.bottom - rcIntersectArea.top;
  1069. //
  1070. // ready to initialize PAPERFORMAT struct now
  1071. //
  1072. pPDev->pf.szPhysSizeM.cx = szPaperSize.cx;
  1073. pPDev->pf.szPhysSizeM.cy = szPaperSize.cy;
  1074. pPDev->pf.szImageAreaM.cx = szImageArea.cx;
  1075. pPDev->pf.szImageAreaM.cy = szImageArea.cy;
  1076. pPDev->pf.ptImageOriginM.x = rcMargins.left;
  1077. pPDev->pf.ptImageOriginM.y = rcMargins.top;
  1078. //
  1079. // Now, take current orientation into consideration and set up
  1080. // SURFACEFORMAT struct.
  1081. // Note that pPDev->ptGrxScale has alreay been rotated to suit the orientation.
  1082. //
  1083. if (pPDev->pdm->dmOrientation == DMORIENT_LANDSCAPE)
  1084. {
  1085. pPDev->sf.szPhysPaperG.cx = szPaperSize.cy / pPDev->ptGrxScale.x;
  1086. pPDev->sf.szPhysPaperG.cy = szPaperSize.cx / pPDev->ptGrxScale.y;
  1087. pPDev->sf.szImageAreaG.cx = szImageArea.cy / pPDev->ptGrxScale.x;
  1088. pPDev->sf.szImageAreaG.cy = szImageArea.cx / pPDev->ptGrxScale.y;
  1089. //
  1090. // 2 scenarios for landscape mode
  1091. // CC_90, rotate CC 90 degrees, for dot matrix style printers
  1092. // CC_270, rotate CC 270 degrees, for Laser Jet style printers
  1093. //
  1094. if ( pPDev->pOrientation && pPDev->pOrientation->dwRotationAngle == ROTATE_90)
  1095. {
  1096. pPDev->sf.ptImageOriginG.x = rcMargins.bottom / pPDev->ptGrxScale.x;
  1097. pPDev->sf.ptImageOriginG.y = rcMargins.left / pPDev->ptGrxScale.y;
  1098. }
  1099. else
  1100. {
  1101. pPDev->sf.ptImageOriginG.x = rcMargins.top / pPDev->ptGrxScale.x;
  1102. pPDev->sf.ptImageOriginG.y = rcMargins.right / pPDev->ptGrxScale.y;
  1103. }
  1104. if (!pPDev->pOrientation || pPDev->pGlobals->bRotateCoordinate == FALSE)
  1105. {
  1106. pPDev->sf.ptPrintOffsetM.x = pPDev->pf.ptImageOriginM.x - pPaperEx->ptPrinterCursorOrig.x;
  1107. pPDev->sf.ptPrintOffsetM.y = pPDev->pf.ptImageOriginM.y - pPaperEx->ptPrinterCursorOrig.y;
  1108. }
  1109. else
  1110. {
  1111. if ( pPDev->pOrientation->dwRotationAngle == ROTATE_90)
  1112. {
  1113. pPDev->sf.ptPrintOffsetM.x =
  1114. rcMargins.bottom + pPaperEx->ptPrinterCursorOrig.y - pPDev->pf.szPhysSizeM.cy;
  1115. pPDev->sf.ptPrintOffsetM.y =
  1116. rcMargins.left - pPaperEx->ptPrinterCursorOrig.x;
  1117. }
  1118. else
  1119. {
  1120. pPDev->sf.ptPrintOffsetM.x =
  1121. rcMargins.top - pPaperEx->ptPrinterCursorOrig.y;
  1122. pPDev->sf.ptPrintOffsetM.y =
  1123. rcMargins.right + pPaperEx->ptPrinterCursorOrig.x - pPDev->pf.szPhysSizeM.cx;
  1124. }
  1125. }
  1126. }
  1127. else
  1128. {
  1129. pPDev->sf.szPhysPaperG.cx = szPaperSize.cx / pPDev->ptGrxScale.x;
  1130. pPDev->sf.szPhysPaperG.cy = szPaperSize.cy / pPDev->ptGrxScale.y;
  1131. pPDev->sf.szImageAreaG.cx = szImageArea.cx / pPDev->ptGrxScale.x;
  1132. pPDev->sf.szImageAreaG.cy = szImageArea.cy / pPDev->ptGrxScale.y;
  1133. pPDev->sf.ptImageOriginG.x = rcMargins.left / pPDev->ptGrxScale.x;
  1134. pPDev->sf.ptImageOriginG.y = rcMargins.top / pPDev->ptGrxScale.y;
  1135. pPDev->sf.ptPrintOffsetM.x = pPDev->pf.ptImageOriginM.x - pPaperEx->ptPrinterCursorOrig.x;
  1136. pPDev->sf.ptPrintOffsetM.y = pPDev->pf.ptImageOriginM.y - pPaperEx->ptPrinterCursorOrig.y;
  1137. }
  1138. return TRUE;
  1139. }
  1140. VOID
  1141. VGetPaperMargins(
  1142. PDEV *pPDev,
  1143. PAGESIZE *pPageSize,
  1144. PAGESIZEEX *pPageSizeEx,
  1145. SIZEL szPhysSize,
  1146. PRECTL prcMargins
  1147. )
  1148. /*++
  1149. Routine Description:
  1150. Calculate the margins based on paper margins and the input slot feed margins.
  1151. Arguments:
  1152. pPDev - Pointer to PDEVICE
  1153. pPageSize - pointer to PAGESIZE
  1154. pPageSizeEx - Pointer to PAGESIZEEX
  1155. szPhysSize - physical dimensions (after applying *RotateSize?)
  1156. prcMargins - Pointer to RECTL to hold the margins calculated
  1157. Return Value:
  1158. None
  1159. Note:
  1160. All margins calculations are in Portrait mode.
  1161. The margins returned in prcMargins are in portrait mode
  1162. Assumed that physical paper size, image area, and image origin in binary
  1163. data are in portrait mode.
  1164. --*/
  1165. {
  1166. if (pPageSize->dwPaperSizeID == DMPAPER_USER)
  1167. {
  1168. if(pPageSizeEx->strCustCursorOriginX.dwCount == 5 &&
  1169. pPageSizeEx->strCustCursorOriginY.dwCount == 5 &&
  1170. pPageSizeEx->strCustPrintableOriginX.dwCount == 5 &&
  1171. pPageSizeEx->strCustPrintableOriginY.dwCount == 5 &&
  1172. pPageSizeEx->strCustPrintableSizeX.dwCount == 5 &&
  1173. pPageSizeEx->strCustPrintableSizeY.dwCount == 5 ) // if all parameters present...
  1174. {
  1175. SIZEL szImageArea; // *PrintableArea, for CUSTOMSIZE options
  1176. POINT ptImageOrigin; // *PrintableOrigin, for CUSTOMSIZE options
  1177. BYTE *pInvocationStr; // points to parameter reference: "%dddd"
  1178. PARAMETER *pParameter; // points to parameter structure referenced by "%dddd"
  1179. BOOL bMaxRepeat = FALSE; // dummy placeholder.
  1180. // init standard variable for papersize! since these are not yet initialized at this time!
  1181. // this implies GPD writer may only reference the standard vars "PhysPaperLength"
  1182. // and "PhysPaperWidth" in these parameters.
  1183. pPDev->pf.szPhysSizeM.cx = szPhysSize.cx;
  1184. pPDev->pf.szPhysSizeM.cy = szPhysSize.cy;
  1185. pPDev->arStdPtrs[SV_PHYSPAPERLENGTH]= &pPDev->pf.szPhysSizeM.cy;
  1186. pPDev->arStdPtrs[SV_PHYSPAPERWIDTH] = &pPDev->pf.szPhysSizeM.cx;
  1187. pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustCursorOriginX.loOffset);
  1188. // pInvocationStr[0] == '%'
  1189. pParameter = PGetParameter(pPDev, pInvocationStr + 1);
  1190. pPageSizeEx->ptPrinterCursorOrig.x = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
  1191. pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustCursorOriginY.loOffset);
  1192. // pInvocationStr[0] == '%'
  1193. pParameter = PGetParameter(pPDev, pInvocationStr + 1);
  1194. pPageSizeEx->ptPrinterCursorOrig.y = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
  1195. pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustPrintableOriginX.loOffset);
  1196. // pInvocationStr[0] == '%'
  1197. pParameter = PGetParameter(pPDev, pInvocationStr + 1);
  1198. ptImageOrigin.x = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
  1199. pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustPrintableOriginY.loOffset);
  1200. // pInvocationStr[0] == '%'
  1201. pParameter = PGetParameter(pPDev, pInvocationStr + 1);
  1202. ptImageOrigin.y = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
  1203. pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustPrintableSizeX.loOffset);
  1204. // pInvocationStr[0] == '%'
  1205. pParameter = PGetParameter(pPDev, pInvocationStr + 1);
  1206. szImageArea.cx = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
  1207. pInvocationStr = CMDOFFSET_TO_PTR(pPDev, pPageSizeEx->strCustPrintableSizeY.loOffset);
  1208. // pInvocationStr[0] == '%'
  1209. pParameter = PGetParameter(pPDev, pInvocationStr + 1);
  1210. szImageArea.cy = IProcessTokenStream(pPDev, &pParameter->arTokens, &bMaxRepeat);
  1211. prcMargins->left = ptImageOrigin.x;
  1212. prcMargins->top = ptImageOrigin.y;
  1213. prcMargins->right = szPhysSize.cx - szImageArea.cx - ptImageOrigin.x;
  1214. prcMargins->bottom = szPhysSize.cy - szImageArea.cy - ptImageOrigin.y;
  1215. }
  1216. else
  1217. {
  1218. DWORD dwHorMargin, dwLeftMargin;
  1219. //
  1220. // calculate the margins and printable area based on info in pPageSizeEx
  1221. //
  1222. prcMargins->top = pPageSizeEx->dwTopMargin;
  1223. prcMargins->bottom = pPageSizeEx->dwBottomMargin;
  1224. //
  1225. // Calculate the horizontal margin and adjust it if the user specified
  1226. // centering the printable area along the paper path
  1227. //
  1228. if((DWORD)szPhysSize.cx < pPageSizeEx->dwMaxPrintableWidth)
  1229. dwHorMargin = 0;
  1230. else
  1231. dwHorMargin = szPhysSize.cx - pPageSizeEx->dwMaxPrintableWidth;
  1232. //
  1233. // Determine the horizontal margins. If they are centered, then the
  1234. // Left margin is simply the overall divided in two. But, we need to
  1235. // consider both the printer's and form's margins, and choose the largest.
  1236. //
  1237. if( pPageSizeEx->bCenterPrintArea)
  1238. dwLeftMargin = (dwHorMargin / 2);
  1239. else
  1240. dwLeftMargin = 0;
  1241. prcMargins->left = dwLeftMargin < pPageSizeEx->dwMinLeftMargin ?
  1242. pPageSizeEx->dwMinLeftMargin : dwLeftMargin;
  1243. if( dwHorMargin > (DWORD)prcMargins->left ) // still have margin to distribute
  1244. prcMargins->right = dwHorMargin - prcMargins->left;
  1245. else
  1246. prcMargins->right = 0;
  1247. }
  1248. }
  1249. else
  1250. {
  1251. prcMargins->left = pPageSizeEx->ptImageOrigin.x;
  1252. prcMargins->top = pPageSizeEx->ptImageOrigin.y;
  1253. prcMargins->right = szPhysSize.cx - pPageSizeEx->szImageArea.cx
  1254. - pPageSizeEx->ptImageOrigin.x;
  1255. prcMargins->bottom = szPhysSize.cy - pPageSizeEx->szImageArea.cy
  1256. - pPageSizeEx->ptImageOrigin.y;
  1257. }
  1258. //
  1259. // All margins are positive or zero
  1260. //
  1261. if( prcMargins->top < 0 )
  1262. prcMargins->top = 0;
  1263. if( prcMargins->bottom < 0 )
  1264. prcMargins->bottom = 0;
  1265. if( prcMargins->left < 0 )
  1266. prcMargins->left = 0;
  1267. if( prcMargins->right < 0 )
  1268. prcMargins->right = 0;
  1269. }
  1270. VOID
  1271. VInitFYMove(
  1272. PDEV *pPDev
  1273. )
  1274. /*++
  1275. Routine Description:
  1276. Initialize the fYMove flag in PDEVICE from reading the
  1277. YMoveAttributes keyword
  1278. Arguments:
  1279. pPDEV - Pointer to PDEVICE
  1280. Return Value:
  1281. None
  1282. --*/
  1283. {
  1284. PLISTNODE pListNode = LISTNODEPTR(pPDev->pDriverInfo,
  1285. pPDev->pGlobals->liYMoveAttributes);
  1286. pPDev->fYMove = 0;
  1287. while (pListNode)
  1288. {
  1289. if (pListNode->dwData == YMOVE_FAVOR_LINEFEEDSPACING)
  1290. pPDev->fYMove |= FYMOVE_FAVOR_LINEFEEDSPACING;
  1291. if (pListNode->dwData == YMOVE_SENDCR_FIRST)
  1292. pPDev->fYMove |= FYMOVE_SEND_CR_FIRST;
  1293. if (pListNode->dwNextItem == END_OF_LIST)
  1294. break;
  1295. else
  1296. pListNode = LISTNODEPTR(pPDev->pDriverInfo,
  1297. pListNode->dwNextItem);
  1298. }
  1299. }
  1300. VOID
  1301. VInitFMode(
  1302. PDEV *pPDev
  1303. )
  1304. /*++
  1305. Routine Description:
  1306. Initialize the fMode flag in PDEVICE to reflect the settings saved
  1307. in Devmode.dmPrivate.dwFlags AND to reflect the device capabilities
  1308. Arguments:
  1309. pPDEV - Pointer to PDEVICE
  1310. Return Value:
  1311. None
  1312. --*/
  1313. {
  1314. if (pPDev->pdmPrivate->dwFlags & DXF_NOEMFSPOOL)
  1315. pPDev->fMode |= PF_NOEMFSPOOL;
  1316. //
  1317. // Adjust memory for page protection only if the user selects
  1318. // to turn on page protection and this feature exists.
  1319. //
  1320. if ( (pPDev->PrinterData.dwFlags & PFLAGS_PAGE_PROTECTION) &&
  1321. pPDev->pPageProtect &&
  1322. (pPDev->pPageProtect->dwPageProtectID == PAGEPRO_ON) )
  1323. {
  1324. //
  1325. // Look up the page protection value in the PAGESIZE struct for the
  1326. // paper size selected
  1327. //
  1328. DWORD dwPageMem = pPDev->pPageSize->dwPageProtectionMemory;
  1329. if (dwPageMem < pPDev->dwFreeMem)
  1330. {
  1331. pPDev->fMode |= PF_PAGEPROTECT;
  1332. pPDev->dwFreeMem -= dwPageMem;
  1333. }
  1334. ASSERT(pPDev->dwFreeMem > 0);
  1335. }
  1336. //
  1337. // Check whether the device can do landscape rotation
  1338. //
  1339. if (pPDev->pOrientation && pPDev->pOrientation->dwRotationAngle != ROTATE_NONE &&
  1340. pPDev->pGlobals->bRotateRasterData == FALSE)
  1341. {
  1342. //
  1343. // bRotateRasterData is set to TRUE if the device can rotate
  1344. // graphics data. Otherwise, the driver will have to do it.
  1345. // PF_ROTATE is set to indicate that the driver needs to rotate
  1346. // the graphics data, for when we do banding.
  1347. //
  1348. pPDev->fMode |= PF_ROTATE;
  1349. if (pPDev->pOrientation->dwRotationAngle == ROTATE_90)
  1350. pPDev->fMode |= PF_CCW_ROTATE90;
  1351. }
  1352. //
  1353. // Init X and Y move CMD capabilities
  1354. //
  1355. if (pPDev->arCmdTable[CMD_XMOVERELLEFT] == NULL &&
  1356. pPDev->arCmdTable[CMD_XMOVERELRIGHT] == NULL)
  1357. {
  1358. pPDev->fMode |= PF_NO_RELX_MOVE;
  1359. }
  1360. if (pPDev->arCmdTable[CMD_YMOVERELUP] == NULL &&
  1361. pPDev->arCmdTable[CMD_YMOVERELDOWN] == NULL)
  1362. {
  1363. pPDev->fMode |= PF_NO_RELY_MOVE;
  1364. }
  1365. if (pPDev->arCmdTable[CMD_XMOVEABSOLUTE] == NULL &&
  1366. pPDev->arCmdTable[CMD_XMOVERELRIGHT] == NULL)
  1367. {
  1368. pPDev->fMode |= PF_NO_XMOVE_CMD;
  1369. }
  1370. if (pPDev->arCmdTable[CMD_YMOVEABSOLUTE] == NULL &&
  1371. pPDev->arCmdTable[CMD_YMOVERELDOWN] == NULL)
  1372. {
  1373. pPDev->fMode |= PF_NO_YMOVE_CMD;
  1374. }
  1375. if (pPDev->arCmdTable[CMD_SETRECTWIDTH] != NULL &&
  1376. pPDev->arCmdTable[CMD_SETRECTHEIGHT] != NULL)
  1377. {
  1378. pPDev->fMode |= PF_RECT_FILL;
  1379. }
  1380. if (pPDev->arCmdTable[CMD_RECTWHITEFILL] != NULL)
  1381. pPDev->fMode |= PF_RECTWHITE_FILL;
  1382. //
  1383. // Init brush selection capabilities
  1384. //
  1385. if (pPDev->arCmdTable[CMD_DOWNLOAD_PATTERN] )
  1386. pPDev->fMode |= PF_DOWNLOAD_PATTERN;
  1387. if (pPDev->arCmdTable[CMD_SELECT_PATTERN])
  1388. pPDev->fMode |= PF_SHADING_PATTERN;
  1389. //
  1390. // BUG_BUG, need to get rid of CMD_WHITETEXTON, CMD_WHITETEXTOFF once
  1391. // all the GPD changes have completed for CMD_SELECT_WHITEBRUSH, CMD_SELECT_BLACKBRUSH
  1392. // no harm done either way.
  1393. if ( (pPDev->arCmdTable[CMD_SELECT_WHITEBRUSH] &&
  1394. pPDev->arCmdTable[CMD_SELECT_BLACKBRUSH]) ||
  1395. (pPDev->arCmdTable[CMD_WHITETEXTON] &&
  1396. pPDev->arCmdTable[CMD_WHITETEXTOFF]) )
  1397. pPDev->fMode |= PF_WHITEBLACK_BRUSH;
  1398. //
  1399. // Init raster mirroring flag
  1400. //
  1401. if (pPDev->pGlobals->bMirrorRasterPage)
  1402. pPDev->fMode2 |= PF2_MIRRORING_ENABLED;
  1403. }
  1404. INT
  1405. iHypot(
  1406. INT iX,
  1407. INT iY
  1408. )
  1409. /*++
  1410. Routine Description:
  1411. Calculates the length of the hypotenous of a right triangle whose
  1412. sides are passed in as parameters
  1413. Arguments:
  1414. iX, iY - Sides of a right triangle
  1415. Return Value:
  1416. The hypotenous of the triangle
  1417. --*/
  1418. {
  1419. register INT iHypo;
  1420. INT iDelta, iTarget;
  1421. /*
  1422. * Finds the hypoteneous of a right triangle with legs equal to x
  1423. * and y. Assumes x, y, hypo are integers.
  1424. * Use sq(x) + sq(y) = sq(hypo);
  1425. * Start with MAX(x, y),
  1426. * use sq(x + 1) = sq(x) + 2x + 1 to incrementally get to the
  1427. * target hypotenouse.
  1428. */
  1429. iHypo = max( iX, iY );
  1430. iTarget = min( iX,iY );
  1431. iTarget = iTarget * iTarget;
  1432. for( iDelta = 0; iDelta < iTarget; iHypo++ )
  1433. iDelta += (iHypo << 1) + 1;
  1434. return iHypo;
  1435. }
  1436. INT
  1437. iGCD(
  1438. INT i0,
  1439. INT i1
  1440. )
  1441. /*++
  1442. Routine Description:
  1443. Calculates the Greatest Common Divisor. Use Euclid's algorith.
  1444. Arguments:
  1445. i0, i1 - the first and second number
  1446. Return Value:
  1447. The greatest common divisor
  1448. --*/
  1449. {
  1450. int iRem; /* Will be the remainder */
  1451. if( i0 < i1 )
  1452. {
  1453. /* Need to interchange them */
  1454. iRem = i0;
  1455. i0 = i1;
  1456. i1 = iRem;
  1457. }
  1458. while( iRem = (i0 % i1) )
  1459. {
  1460. /* Step along to the next value */
  1461. i0 = i1;
  1462. i1 = iRem;
  1463. }
  1464. return i1; /* The answer! */
  1465. }
  1466. BOOL
  1467. BIntersectRect(
  1468. OUT PRECTL prcDest,
  1469. IN PRECTL prcRect1,
  1470. IN PRECTL prcRect2
  1471. )
  1472. /*++
  1473. Routine Description:
  1474. Intersect the Rec1 and Rect2
  1475. and store the result in the destination rectangle
  1476. Arguments:
  1477. prcDest - Points to the destination rectangle
  1478. prcSrc - Points to the source rectangle
  1479. Return Value:
  1480. FALSE if the intersected rectangle is empty
  1481. TRUE otherwise
  1482. --*/
  1483. {
  1484. ASSERT(prcDest != NULL && prcRect1 != NULL && prcRect2 != NULL);
  1485. if (prcRect1->left < prcRect2->left)
  1486. prcDest->left = prcRect2->left;
  1487. else
  1488. prcDest->left = prcRect1->left;
  1489. if (prcRect1->top < prcRect2->top)
  1490. prcDest->top = prcRect2->top;
  1491. else
  1492. prcDest->top = prcRect1->top;
  1493. if (prcRect1->right > prcRect2->right)
  1494. prcDest->right = prcRect2->right;
  1495. else
  1496. prcDest->right = prcRect1->right;
  1497. if (prcRect1->bottom > prcRect2->bottom)
  1498. prcDest->bottom = prcRect2->bottom;
  1499. else
  1500. prcDest->bottom = prcRect1->bottom;
  1501. return (prcDest->right > prcDest->left) &&
  1502. (prcDest->bottom > prcDest->top);
  1503. }
  1504. VOID
  1505. SetRop3(
  1506. PDEV *pPDev,
  1507. DWORD dwRop3
  1508. )
  1509. /*++
  1510. Routine Description:
  1511. This function set the Rop3 value for the Raster and Font module
  1512. Arguments:
  1513. pPDev Pointer to PDEVICE
  1514. dwRop3 Rop3 value
  1515. Return Value:
  1516. FALSE if the intersected rectangle is empty
  1517. TRUE otherwise
  1518. --*/
  1519. {
  1520. ASSERT(VALID_PDEV(pPDev));
  1521. pPDev->dwRop3 = dwRop3;
  1522. }
  1523. VOID
  1524. VUnloadFreeBinaryData(
  1525. IN PDEV *pPDev
  1526. )
  1527. /*++
  1528. Routine Description:
  1529. This function frees the binary data
  1530. Arguments:
  1531. pPDev - Pointer to PDEV
  1532. Return Value:
  1533. None
  1534. Note:
  1535. --*/
  1536. {
  1537. INT iCmd;
  1538. //
  1539. // Call parser to free memory allocated for binary data
  1540. //
  1541. if (pPDev->pRawData)
  1542. UnloadRawBinaryData(pPDev->pRawData);
  1543. if (pPDev->pInfoHeader)
  1544. FreeBinaryData(pPDev->pInfoHeader);
  1545. pPDev->pRawData = NULL;
  1546. pPDev->pInfoHeader = NULL;
  1547. pPDev->pUIInfo = NULL;
  1548. //
  1549. // pPDev->pUIInfo is reset so update the winresdata pUIInfo also.
  1550. //
  1551. pPDev->WinResData.pUIInfo = NULL;
  1552. pPDev->pDriverInfo = NULL;
  1553. pPDev->pGlobals = NULL;
  1554. for (iCmd = 0; iCmd < CMD_MAX; iCmd++)
  1555. {
  1556. pPDev->arCmdTable[iCmd] = NULL;
  1557. }
  1558. pPDev->pOrientation = NULL;
  1559. pPDev->pResolution = NULL;
  1560. pPDev->pResolutionEx = NULL;
  1561. pPDev->pColorMode = NULL;
  1562. pPDev->pColorModeEx = NULL;
  1563. pPDev->pDuplex = NULL;
  1564. pPDev->pPageSize = NULL;
  1565. pPDev->pPageSizeEx = NULL;
  1566. pPDev->pInputSlot = NULL;
  1567. pPDev->pMemOption = NULL;
  1568. pPDev->pHalftone = NULL;
  1569. pPDev->pPageProtect = NULL;
  1570. }
  1571. BOOL
  1572. BReloadBinaryData(
  1573. IN PDEV *pPDev
  1574. )
  1575. /*++
  1576. Routine Description:
  1577. This function reloads the binary data and reinitializes the
  1578. offsets and pointers for access to snapshot data
  1579. Arguments:
  1580. pPDev - Pointer to PDEV
  1581. Return Value:
  1582. Returns TRUE if successful, otherwise FALSE
  1583. Note:
  1584. --*/
  1585. {
  1586. //
  1587. // Reloads binary data and reinit data pointers
  1588. //
  1589. if (! (pPDev->pRawData = LoadRawBinaryData(pPDev->pDriverInfo3->pDataFile)) ||
  1590. ! (pPDev->pInfoHeader = InitBinaryData(pPDev->pRawData, NULL, pPDev->pOptionsArray)) ||
  1591. ! (pPDev->pDriverInfo = OFFSET_TO_POINTER(pPDev->pInfoHeader, pPDev->pInfoHeader->loDriverOffset)) ||
  1592. ! (pPDev->pUIInfo = OFFSET_TO_POINTER(pPDev->pInfoHeader, pPDev->pInfoHeader->loUIInfoOffset)) ||
  1593. ! (pPDev->pGlobals = &(pPDev->pDriverInfo->Globals)) )
  1594. return FALSE;
  1595. //
  1596. // pPDev->pUIInfo is reset so update the winresdata pUIInfo also.
  1597. //
  1598. pPDev->WinResData.pUIInfo = pPDev->pUIInfo;
  1599. //
  1600. // Rebuilds the command table
  1601. //
  1602. if (BInitCmdTable(pPDev) == FALSE)
  1603. return FALSE;
  1604. //
  1605. // Rebuilds all the options pointers in PDEV
  1606. //
  1607. if (BInitOptions(pPDev) == FALSE)
  1608. return FALSE;
  1609. return TRUE;
  1610. }