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.

682 lines
18 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. cmdcb.c
  5. Abstract:
  6. Implementation of GPD command callback for "test.gpd":
  7. OEMCommandCallback
  8. Environment:
  9. Windows NT Unidrv driver
  10. Revision History:
  11. // NOTICE-2002/03/20-v-sueyas-
  12. // 04/07/97 -zhanw-
  13. // Created it.
  14. --*/
  15. #include "pdev.h"
  16. // #289908: pOEMDM -> pdevOEM
  17. PDEVOEM APIENTRY
  18. OEMEnablePDEV(
  19. PDEVOBJ pdevobj,
  20. PWSTR pPrinterName,
  21. ULONG cPatterns,
  22. HSURF *phsurfPatterns,
  23. ULONG cjGdiInfo,
  24. GDIINFO *pGdiInfo,
  25. ULONG cjDevInfo,
  26. DEVINFO *pDevInfo,
  27. DRVENABLEDATA *pded)
  28. {
  29. // NTRAID#NTBUG9-581725-2002/03/20-v-sueyas-: Check for illegal parameters
  30. if (NULL == pdevobj)
  31. {
  32. ERR(("OEMEnablePDEV: Invalid parameter(s).\n"));
  33. return NULL;
  34. }
  35. if(!pdevobj->pdevOEM)
  36. {
  37. if(!(pdevobj->pdevOEM = MemAllocZ(sizeof(QPLKPDEV))))
  38. {
  39. return NULL;
  40. }
  41. }
  42. return pdevobj->pdevOEM;
  43. }
  44. VOID APIENTRY
  45. OEMDisablePDEV(
  46. PDEVOBJ pdevobj)
  47. {
  48. // NTRAID#NTBUG9-581725-2002/03/20-v-sueyas-: Check for illegal parameters
  49. if (NULL == pdevobj)
  50. {
  51. ERR(("OEMDisablePDEV: Invalid parameter(s).\n"));
  52. return;
  53. }
  54. if(pdevobj->pdevOEM)
  55. {
  56. MemFree(pdevobj->pdevOEM);
  57. pdevobj->pdevOEM = NULL;
  58. }
  59. }
  60. BOOL APIENTRY OEMResetPDEV(
  61. PDEVOBJ pdevobjOld,
  62. PDEVOBJ pdevobjNew)
  63. {
  64. PQPLKPDEV pOEMOld, pOEMNew;
  65. // NTRAID#NTBUG9-581725-2002/03/20-v-sueyas-: Check for illegal parameters
  66. if (NULL == pdevobjOld || NULL == pdevobjNew)
  67. {
  68. ERR(("OEMResetPDEV: Invalid parameter(s).\n"));
  69. return FALSE;
  70. }
  71. pOEMOld = (PQPLKPDEV)pdevobjOld->pdevOEM;
  72. pOEMNew = (PQPLKPDEV)pdevobjNew->pdevOEM;
  73. if (pOEMOld != NULL && pOEMNew != NULL)
  74. *pOEMNew = *pOEMOld;
  75. return TRUE;
  76. }
  77. // BInitOEMExtraData() and BMergeOEMExtraData() has moved to common.c
  78. // #######
  79. #define WRITESPOOLBUF(p, s, n) \
  80. ((p)->pDrvProcs->DrvWriteSpoolBuf(p, s, n))
  81. #define PARAM(p,n) \
  82. (*((p)+(n)))
  83. // Private Definition
  84. // Command callback
  85. #define CMD_BEGINPAGE_DELTAROW 1
  86. #define CMD_SENDBLOCKDATA_DELTAROW 2
  87. #define CMD_SENDBLOCKDATA_B2 3
  88. #define CMD_BEGINPAGE_B2 4
  89. // Color support
  90. #define CMD_BEGINPAGE_C1 5
  91. #define CMD_BEGINPAGE_DEFAULT 6
  92. #define CMD_BEGINPAGE_B2_LAND 7
  93. // Special fix for Qnix Picasso 300
  94. #define CMD_BEGINPAGE_B2_PICA 8
  95. #define CMD_CR 10
  96. #define CMD_LF 11
  97. #define CMD_FF 12
  98. // Color support
  99. #define CMD_SELECT_CYAN 100
  100. #define CMD_SELECT_MAGENTA 101
  101. #define CMD_SELECT_YELLOW 102
  102. #define CMD_SELECT_BLACK 103
  103. #define CMD_YMOVE_REL_COLOR 150
  104. // #299937: Incorrect value for Y Move
  105. #define COLOR_MASTERUNIT 600
  106. // Compression Type
  107. #define COMP_DELTARAW 1
  108. #define COMP_B2 2
  109. #define COMP_NOCOMP 3
  110. // Compression routine
  111. WORD DeltaRawCompress(PBYTE, PBYTE, PBYTE, DWORD, DWORD);
  112. WORD B2Compress(PBYTE, PBYTE, PBYTE, DWORD);
  113. PBYTE RLE_comp(PBYTE);
  114. WORD RLEencoding(PBYTE, PBYTE, DWORD);
  115. /*****************************************************************************/
  116. /* */
  117. /* BOOL APIENTRY OEMFilterGraphics( */
  118. /* PDEVOBJ pdevobj */
  119. /* PBYTE pBuf */
  120. /* DWORD dwLen ) */
  121. /* */
  122. /*****************************************************************************/
  123. BOOL APIENTRY
  124. OEMFilterGraphics(
  125. PDEVOBJ pdevobj, // Points to private data required by the Unidriver.dll
  126. PBYTE pBuf, // points to buffer of graphics data
  127. DWORD dwLen) // length of buffer in bytes
  128. {
  129. BYTE CompressedScanLine[COMPRESS_BUFFER_SIZE];
  130. BYTE HeaderScanLine[4];
  131. WORD nCompBufLen;
  132. PQPLKPDEV pOEM;
  133. // Color support
  134. PDWORD pdwLastScanLineLen;
  135. LPSTR lpLastScanLine;
  136. BYTE HeaderColorPlane;
  137. // NTRAID#NTBUG9-581725-2002/03/20-v-sueyas-: Check for illegal parameters
  138. if (NULL == pdevobj || NULL == pBuf || 0 == dwLen)
  139. {
  140. ERR(("OEMFilterGraphics: Invalid parameter(s).\n"));
  141. return FALSE;
  142. }
  143. pOEM = (PQPLKPDEV)pdevobj->pdevOEM;
  144. // NTRAID#NTBUG9-581725-2002/03/20-v-sueyas-: Check for null pointers
  145. if (NULL == pOEM)
  146. {
  147. ERR(("OEMFilterGraphics: pdevobj->pdevOEM = 0.\n"));
  148. return FALSE;
  149. }
  150. if (pOEM->bFirst)
  151. {
  152. // Color support
  153. ZeroMemory(pOEM->lpCyanLastScanLine, sizeof pOEM->lpCyanLastScanLine );
  154. ZeroMemory(pOEM->lpMagentaLastScanLine, sizeof pOEM->lpMagentaLastScanLine );
  155. ZeroMemory(pOEM->lpYellowLastScanLine, sizeof pOEM->lpYellowLastScanLine );
  156. ZeroMemory(pOEM->lpBlackLastScanLine, sizeof pOEM->lpBlackLastScanLine );
  157. pOEM->bFirst = FALSE;
  158. }
  159. // Color support
  160. switch (pOEM->fColor) {
  161. case CC_CYAN:
  162. HeaderColorPlane = 0x05;
  163. pdwLastScanLineLen = &(pOEM->dwCyanLastScanLineLen);
  164. lpLastScanLine = pOEM->lpCyanLastScanLine;
  165. break;
  166. case CC_MAGENTA:
  167. HeaderColorPlane = 0x06;
  168. pdwLastScanLineLen = &(pOEM->dwMagentaLastScanLineLen);
  169. lpLastScanLine = pOEM->lpMagentaLastScanLine;
  170. break;
  171. case CC_YELLOW:
  172. HeaderColorPlane = 0x07;
  173. pdwLastScanLineLen = &(pOEM->dwYellowLastScanLineLen);
  174. lpLastScanLine = pOEM->lpYellowLastScanLine;
  175. break;
  176. case CC_BLACK:
  177. default: // Black&White
  178. HeaderColorPlane = 0x04;
  179. pdwLastScanLineLen = &(pOEM->dwBlackLastScanLineLen);
  180. lpLastScanLine = pOEM->lpBlackLastScanLine;
  181. break;
  182. }
  183. if(pOEM->dwCompType == COMP_DELTARAW)
  184. {
  185. nCompBufLen = (WORD)DeltaRawCompress(pBuf, lpLastScanLine,
  186. CompressedScanLine, (*pdwLastScanLineLen > dwLen) ?
  187. *pdwLastScanLineLen : dwLen, (DWORD)0);
  188. HeaderScanLine[0] = 0;
  189. HeaderScanLine[1] = 0;
  190. HeaderScanLine[2] = HIBYTE(nCompBufLen);
  191. HeaderScanLine[3] = LOBYTE(nCompBufLen);
  192. WRITESPOOLBUF(pdevobj, (PBYTE) HeaderScanLine, 4);
  193. WRITESPOOLBUF(pdevobj, (PBYTE) CompressedScanLine, nCompBufLen);
  194. if( dwLen > SCANLINE_BUFFER_SIZE ) return FALSE;
  195. CopyMemory(lpLastScanLine, pBuf, dwLen);
  196. if (*pdwLastScanLineLen > dwLen) {
  197. if(*pdwLastScanLineLen > SCANLINE_BUFFER_SIZE ) return FALSE;
  198. ZeroMemory(lpLastScanLine + dwLen,
  199. *pdwLastScanLineLen - dwLen);
  200. }
  201. *pdwLastScanLineLen = dwLen;
  202. } else if(pOEM->dwCompType == COMP_B2) {
  203. nCompBufLen = B2Compress(lpLastScanLine, pBuf,
  204. CompressedScanLine, (*pdwLastScanLineLen > dwLen) ?
  205. *pdwLastScanLineLen : dwLen);
  206. // send color plane command
  207. if (pOEM->bColor)
  208. WRITESPOOLBUF(pdevobj, &HeaderColorPlane, 1);
  209. HeaderScanLine[0] = 0x02;
  210. HeaderScanLine[1] = (BYTE) (nCompBufLen >> 8);
  211. HeaderScanLine[2] = (BYTE) nCompBufLen;
  212. WRITESPOOLBUF(pdevobj, (PBYTE) HeaderScanLine, 3);
  213. // #297256: Line is cut and increase
  214. // Do not send if no compressed data.
  215. if (nCompBufLen) {
  216. WRITESPOOLBUF(pdevobj, (PBYTE) CompressedScanLine,
  217. nCompBufLen);
  218. *pdwLastScanLineLen = dwLen;
  219. }
  220. }
  221. return TRUE;
  222. }
  223. /*****************************************************************************/
  224. /* */
  225. /* INT APIENTRY OEMCommandCallback( */
  226. /* PDEVOBJ pdevobj */
  227. /* DWORD dwCmdCbId */
  228. /* DWORD dwCount */
  229. /* PDWORD pdwParams */
  230. /* */
  231. /*****************************************************************************/
  232. INT APIENTRY
  233. OEMCommandCallback(
  234. PDEVOBJ pdevobj, // Points to private data required by the Unidriver.dll
  235. DWORD dwCmdCbId, // Callback ID
  236. DWORD dwCount, // Counts of command parameter
  237. PDWORD pdwParams) // points to values of command params
  238. {
  239. PQPLKPDEV pOEM;
  240. INT iRet = 0;
  241. // Color support
  242. DWORD count, n, unit;
  243. BYTE aCmd[32];
  244. // NTRAID#NTBUG9-581725-2002/03/20-v-sueyas-: Check for illegal parameters
  245. if (NULL == pdevobj)
  246. {
  247. ERR(("OEMCommandCallback: Invalid parameter(s).\n"));
  248. return 0;
  249. }
  250. pOEM = (PQPLKPDEV)(pdevobj->pdevOEM);
  251. // NTRAID#NTBUG9-581725-2002/03/20-v-sueyas-: Check for null pointers
  252. if (NULL == pOEM)
  253. {
  254. ERR(("OEMCommandCallback: pdevobj->pdevOEM = 0.\n"));
  255. return 0;
  256. }
  257. switch(dwCmdCbId)
  258. {
  259. case CMD_BEGINPAGE_DEFAULT:
  260. WRITESPOOLBUF(pdevobj, "\033}0;0;5B", 8);
  261. pOEM->bFirst = TRUE;
  262. break;
  263. case CMD_BEGINPAGE_DELTAROW:
  264. WRITESPOOLBUF(pdevobj, "\033}0;0;3B", 8);
  265. pOEM->bFirst = TRUE;
  266. break;
  267. case CMD_BEGINPAGE_B2:
  268. case CMD_BEGINPAGE_B2_PICA:
  269. WRITESPOOLBUF(pdevobj, "\033}0;0;4B", 8);
  270. pOEM->bFirst = TRUE;
  271. if (dwCmdCbId == CMD_BEGINPAGE_B2_PICA )
  272. {
  273. if (pdwParams[0] == 300 )
  274. WRITESPOOLBUF(pdevobj, "\x00\x1C", 2);
  275. else
  276. WRITESPOOLBUF(pdevobj, "\x00\x38", 2);
  277. }
  278. break;
  279. case CMD_BEGINPAGE_B2_LAND:
  280. WRITESPOOLBUF(pdevobj, "\033}0;0;7B", 8);
  281. pOEM->bFirst = TRUE;
  282. break;
  283. // Color support
  284. case CMD_BEGINPAGE_C1:
  285. WRITESPOOLBUF(pdevobj, "\033}0;0;6B", 8);
  286. // #315089: some lines isn't printed on printable area test.
  287. // move cursor to printable origin.
  288. WRITESPOOLBUF(pdevobj,
  289. "\x05\x00\x03\x06\x00\x03\x07\x00\x03\x04\x00\x03",
  290. 12);
  291. pOEM->bFirst = TRUE;
  292. pOEM->dwCompType = COMP_B2;
  293. pOEM->bColor = TRUE;
  294. break;
  295. case CMD_SENDBLOCKDATA_DELTAROW:
  296. pOEM->dwCompType = COMP_DELTARAW;
  297. break;
  298. case CMD_SENDBLOCKDATA_B2:
  299. pOEM->dwCompType = COMP_B2;
  300. break;
  301. case CMD_CR:
  302. case CMD_LF:
  303. case CMD_FF:
  304. // Dummy support
  305. break;
  306. // Color support
  307. case CMD_SELECT_CYAN:
  308. pOEM->fColor = CC_CYAN;
  309. break;
  310. case CMD_SELECT_MAGENTA:
  311. pOEM->fColor = CC_MAGENTA;
  312. break;
  313. case CMD_SELECT_YELLOW:
  314. pOEM->fColor = CC_YELLOW;
  315. break;
  316. case CMD_SELECT_BLACK:
  317. pOEM->fColor = CC_BLACK;
  318. break;
  319. case CMD_YMOVE_REL_COLOR:
  320. // #299937: Incorrect value for Y Move
  321. // YMove value is always in MasterUnit even YMoveUnit was specified.
  322. if (dwCount < 2 || !pdwParams)
  323. break;
  324. // NTRAID#NTBUG9-581725-2002/03/20-v-sueyas-: Check for deviding by zero
  325. if (0 == pdwParams[1])
  326. return 0;
  327. unit = COLOR_MASTERUNIT / pdwParams[1];
  328. if (unit == 0)
  329. unit = 1; // for our safety
  330. count = pdwParams[0] / unit;
  331. while (count > 0) {
  332. n = min(count, 255);
  333. aCmd[0] = 0x04;
  334. aCmd[1] = 0x00;
  335. aCmd[2] = (BYTE)n;
  336. aCmd[3] = 0x05;
  337. aCmd[4] = 0x00;
  338. aCmd[5] = (BYTE)n;
  339. aCmd[6] = 0x06;
  340. aCmd[7] = 0x00;
  341. aCmd[8] = (BYTE)n;
  342. aCmd[9] = 0x07;
  343. aCmd[10] = 0x00;
  344. aCmd[11] = (BYTE)n;
  345. WRITESPOOLBUF(pdevobj, aCmd, 12);
  346. count -= n;
  347. }
  348. iRet = pdwParams[0];
  349. break;
  350. default:
  351. break;
  352. }
  353. return iRet;
  354. }
  355. /*************************************************
  356. *
  357. * Image Delta Compression Routine
  358. *
  359. *===================================================
  360. * Input:
  361. * nbyte : # of byte, raw data
  362. * Image_string: pointer of raw data
  363. * Prn_string : pointer of compress data
  364. * Output:
  365. * Ret_count : # of byte, compress data
  366. **************************************************/
  367. WORD DeltaRawCompress(
  368. PBYTE Image_string, /* pointer to original string */
  369. PBYTE ORG_image, /* pointer to previous scanline's string */
  370. PBYTE Prn_string, /* pointer to return string */
  371. DWORD nbyte, /* original number of bytes */
  372. DWORD nMagics) //Magic number
  373. {
  374. DWORD c, Ret_count, Skip_flag, Skip_count;
  375. DWORD i, j, k, outcount;
  376. PBYTE Diff_ptr;
  377. PBYTE ORG_ptr;
  378. PBYTE Skip_ptr;
  379. BYTE Diff_byte;
  380. BYTE Diff_mask[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
  381. BOOL bstart = TRUE;
  382. outcount = 0;
  383. Ret_count = 0;
  384. ORG_ptr = ORG_image;
  385. Skip_flag = TRUE;
  386. Skip_ptr = Prn_string++;
  387. Skip_count = (nMagics / 8) / 8;
  388. *Skip_ptr = (BYTE)Skip_count;
  389. k = (nbyte + 7) / 8;
  390. for(i = 0; i < k; i++)
  391. {
  392. Diff_byte = 0;
  393. Diff_ptr = Prn_string++;
  394. for(j = 0; j < 8; j++)
  395. {
  396. if ( (i * 8 + j) >= nbyte )
  397. {
  398. *Prn_string++= 0;
  399. Diff_byte |= Diff_mask[j];
  400. outcount++;
  401. } else {
  402. c = *Image_string++;
  403. if(c != *ORG_ptr)
  404. {
  405. *ORG_ptr++ = (BYTE)c;
  406. *Prn_string++= (BYTE)c;
  407. Diff_byte |= Diff_mask[j];
  408. outcount++;
  409. } else {
  410. ORG_ptr++;
  411. }
  412. }
  413. }
  414. if(Diff_byte == 0)
  415. {
  416. if(Skip_flag == TRUE)
  417. {
  418. Skip_count++;
  419. Prn_string--;
  420. }else{
  421. *Diff_ptr = Diff_byte;
  422. outcount++;
  423. }
  424. }else{
  425. if(Skip_flag == TRUE)
  426. {
  427. Skip_flag = FALSE;
  428. *Skip_ptr = (BYTE)Skip_count;
  429. outcount++;
  430. *Diff_ptr = Diff_byte;
  431. outcount++;
  432. }else{
  433. *Diff_ptr = Diff_byte;
  434. outcount++;
  435. }
  436. Ret_count = outcount;
  437. }
  438. }
  439. return (WORD)Ret_count;
  440. }
  441. /*****************************************************************************/
  442. /* */
  443. /* WORD B2Compress( */
  444. /* PBYTE pLastScanLine */
  445. /* PBYTE pCurrentScanLine */
  446. /* PBYTE pPrnBuf */
  447. /* DWORD nImageWidth */
  448. /* */
  449. /*****************************************************************************/
  450. WORD B2Compress(
  451. PBYTE pLastScanLine,
  452. PBYTE pCurrentScanLine,
  453. PBYTE pPrnBuf,
  454. DWORD nImageWidth)
  455. {
  456. PBYTE pLast, pCurrent, pComp;
  457. PBYTE pByteNum, pCountByte;
  458. WORD i;
  459. BYTE nSameCount, nDiffCount;
  460. // #297256: Line is cut and increase
  461. // Indicate to zero if this place doesn't have any data.
  462. if (nImageWidth == 0)
  463. return 0;
  464. pLast = pLastScanLine;
  465. pCurrent = pCurrentScanLine;
  466. pComp = pPrnBuf;
  467. pByteNum = pComp;
  468. nSameCount = 0;
  469. nDiffCount = 0;
  470. pCountByte = pComp++;
  471. for(i = 0; i < nImageWidth; i++)
  472. {
  473. if(*pCurrent != *pLast)
  474. {
  475. nDiffCount++;
  476. if(nSameCount) // if continuous data remain...
  477. {
  478. *pCountByte = nSameCount;
  479. pCountByte = pComp++;
  480. nSameCount = 0;
  481. }
  482. if(nDiffCount > 127)
  483. {
  484. *pCountByte = 127 + 128;
  485. pComp = RLE_comp(pCountByte);
  486. pCountByte = pComp++;
  487. nDiffCount -= 127;
  488. }
  489. *pLast = *pCurrent;
  490. *pComp++ = *pCurrent;
  491. } else {
  492. nSameCount++;
  493. if(nDiffCount) // if non-continuous data remain...
  494. {
  495. *pCountByte = nDiffCount + 128;
  496. pComp = RLE_comp(pCountByte);
  497. pCountByte = pComp++;
  498. nDiffCount = 0;
  499. }
  500. if(nSameCount > 127)
  501. {
  502. *pCountByte = 127;
  503. pCountByte = pComp++;
  504. nSameCount -= 127;
  505. }
  506. }
  507. pCurrent++;
  508. pLast++;
  509. } // end of for loop
  510. if(nSameCount)
  511. *pCountByte = nSameCount;
  512. if(nDiffCount)
  513. {
  514. *pCountByte = nDiffCount+128;
  515. pComp = RLE_comp(pCountByte);
  516. }
  517. return((WORD) (pComp - pByteNum));
  518. }
  519. /*****************************************************************************/
  520. /* */
  521. /* PBYTE RLE_comp(LPBYTE p) */
  522. /* */
  523. /*****************************************************************************/
  524. PBYTE RLE_comp(PBYTE p)
  525. {
  526. WORD i, count, RLEEncodedCount;
  527. PBYTE p1;
  528. BYTE RLEBuffer[COMPRESS_BUFFER_SIZE];
  529. count = (WORD) (*p - 128);
  530. if(count > 4)
  531. {
  532. RLEEncodedCount = RLEencoding(p + 1, (PBYTE) RLEBuffer, count);
  533. if(RLEEncodedCount < count)
  534. {
  535. *p++ = 0; // RLE encode indicator
  536. *p++ = (BYTE) RLEEncodedCount;
  537. p1 = RLEBuffer;
  538. for(i = 0; i < RLEEncodedCount; i++)
  539. *p++ = *p1++;
  540. return(p);
  541. }
  542. }
  543. return(p + 1 + count);
  544. }
  545. /*****************************************************************************/
  546. /* */
  547. /* WORD RLEencoding( */
  548. /* PBYTE pCurrent */
  549. /* PBYTE pComp */
  550. /* DWORD count */
  551. /* */
  552. /*****************************************************************************/
  553. WORD RLEencoding(
  554. PBYTE pCurrent,
  555. PBYTE pComp,
  556. DWORD count)
  557. {
  558. WORD i, nByteNum;
  559. BYTE curr, next, RLEcount;
  560. nByteNum = 0;
  561. RLEcount = 1;
  562. // NTRAID#NTBUG9-581725-2002/03/20-v-sueyas-: Initialize un-initialized variable
  563. next = 0;
  564. for(i = 0; i < count - 1; i++)
  565. {
  566. curr = *pCurrent++;
  567. next = *pCurrent;
  568. if(curr == next)
  569. {
  570. if(RLEcount == 255)
  571. {
  572. *pComp++ = RLEcount;
  573. *pComp++ = curr;
  574. nByteNum += 2;
  575. RLEcount = 1;
  576. } else {
  577. RLEcount++;
  578. }
  579. } else {
  580. *pComp++ = RLEcount;
  581. *pComp++ = curr;
  582. nByteNum += 2;
  583. RLEcount = 1;
  584. }
  585. }
  586. *pComp++ = RLEcount;
  587. *pComp++ = next;
  588. nByteNum += 2;
  589. return(nByteNum);
  590. }