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.

362 lines
9.9 KiB

  1. #include <windef.h>
  2. #include <wingdi.h>
  3. #include <unidrv.h>
  4. #include "../modinit.c"
  5. #define SCANLINE_BUFFER_SIZE 1280 // A3 landscape scanline length + extra
  6. #define ALL_COLOR_Y_MOVE_CMD_LEN 12 // length of Y move command for all colors
  7. #define CC_CYAN 5 //current plain is cyan
  8. #define CC_MAGENTA 6 //current plain is magenta
  9. #define CC_YELLOW 7 //current plain is yellow
  10. #define CC_BLACK 4 //current plain is black
  11. // Block Image 2 Compression routines
  12. WORD B2Compress(LPBYTE, LPBYTE, LPBYTE, WORD);
  13. LPBYTE RLE_comp(LPBYTE);
  14. WORD RLEencoding(LPBYTE, LPBYTE, WORD);
  15. LPWRITESPOOLBUF WriteSpoolBuf;
  16. LPALLOCMEM UniDrvAllocMem;
  17. LPFREEMEM UniDrvFreeMem;
  18. typedef struct tagVLASERDV
  19. {
  20. BOOL bFirst;
  21. WORD wCyanLastScanLineLen;
  22. WORD wMagentaLastScanLineLen;
  23. WORD wYellowLastScanLineLen;
  24. WORD wBlackLastScanLineLen;
  25. BYTE lpCyanLastScanLine[SCANLINE_BUFFER_SIZE];
  26. BYTE lpMagentaLastScanLine[SCANLINE_BUFFER_SIZE];
  27. BYTE lpYellowLastScanLine[SCANLINE_BUFFER_SIZE];
  28. BYTE lpBlackLastScanLine[SCANLINE_BUFFER_SIZE];
  29. UINT fColor;
  30. } VLASERDV, FAR *LPVLASERDV;
  31. BOOL MiniDrvEnablePDEV(LPDV lpdv, ULONG *pdevcaps)
  32. {
  33. lpdv->fMdv = FALSE;
  34. if (!(lpdv->lpMdv = UniDrvAllocMem(sizeof(VLASERDV))))
  35. return FALSE;
  36. lpdv->fMdv = TRUE;
  37. ((LPVLASERDV)lpdv->lpMdv)->bFirst = FALSE;
  38. ((LPVLASERDV)lpdv->lpMdv)->wCyanLastScanLineLen = 0;
  39. ((LPVLASERDV)lpdv->lpMdv)->wMagentaLastScanLineLen = 0;
  40. ((LPVLASERDV)lpdv->lpMdv)->wYellowLastScanLineLen = 0;
  41. ((LPVLASERDV)lpdv->lpMdv)->wBlackLastScanLineLen = 0;
  42. return TRUE;
  43. }
  44. VOID MiniDrvDisablePDEV(LPDV lpdv)
  45. {
  46. if (lpdv->fMdv)
  47. {
  48. UniDrvFreeMem(lpdv->lpMdv);
  49. lpdv->fMdv = FALSE;
  50. }
  51. }
  52. VOID FAR PASCAL fnOEMOutputCmd(LPDV lpdv, WORD wCmdCbId, PDWORD lpdwParams)
  53. {
  54. DWORD i, nYMove;
  55. BYTE cYMoveCommand[ALL_COLOR_Y_MOVE_CMD_LEN];
  56. LPBYTE lpBuf;
  57. switch (wCmdCbId) // StartPage
  58. {
  59. case 1: // StartPage
  60. WriteSpoolBuf(lpdv, "\x1B}0;0;6B", 8);
  61. ((LPVLASERDV)lpdv->lpMdv)->bFirst = TRUE;
  62. break;
  63. case 2: // AbortDoc
  64. lpBuf = UniDrvAllocMem(256);
  65. ZeroMemory(lpBuf, 256);
  66. WriteSpoolBuf(lpdv, lpBuf, 256);
  67. WriteSpoolBuf(lpdv, "\001\001\003\014\033}0D\0331S", 10);
  68. UniDrvFreeMem(lpBuf);
  69. break;
  70. case 100: ((LPVLASERDV)lpdv->lpMdv)->fColor = CC_CYAN; break;
  71. case 101: ((LPVLASERDV)lpdv->lpMdv)->fColor = CC_MAGENTA; break;
  72. case 102: ((LPVLASERDV)lpdv->lpMdv)->fColor = CC_YELLOW; break;
  73. case 103: ((LPVLASERDV)lpdv->lpMdv)->fColor = CC_BLACK; break;
  74. case 150: for (nYMove = *lpdwParams; nYMove > 255; nYMove -= 255) // 0xFF
  75. {
  76. WriteSpoolBuf(lpdv, (LPBYTE)
  77. "\x04\x00\xFF\x05\x00\xFF\x06\x00\xFF\x07\x00\xFF",
  78. ALL_COLOR_Y_MOVE_CMD_LEN);
  79. }
  80. if (nYMove > 0)
  81. {
  82. cYMoveCommand[0] = 0x04;
  83. cYMoveCommand[1] = 0;
  84. cYMoveCommand[2] = (BYTE) nYMove;
  85. cYMoveCommand[3] = 0x05;
  86. cYMoveCommand[4] = 0;
  87. cYMoveCommand[5] = (BYTE) nYMove;
  88. cYMoveCommand[6] = 0x06;
  89. cYMoveCommand[7] = 0;
  90. cYMoveCommand[8] = (BYTE) nYMove;
  91. cYMoveCommand[9] = 0x07;
  92. cYMoveCommand[10] = 0;
  93. cYMoveCommand[11] = (BYTE) nYMove;
  94. WriteSpoolBuf(lpdv, (LPBYTE) cYMoveCommand,
  95. ALL_COLOR_Y_MOVE_CMD_LEN);
  96. }
  97. break;
  98. default: ;
  99. }
  100. }
  101. WORD FAR PASCAL CBFilterGraphics(LPDV lpdv, LPBYTE lpBuf, WORD wLen)
  102. {
  103. WORD wLastScanLineLen;
  104. LPBYTE lpLastScanLine;
  105. BYTE CompressedScanLine[SCANLINE_BUFFER_SIZE];
  106. BYTE HeaderColorPlain;
  107. BYTE HeaderScanLine[3];
  108. WORD nCompBufLen;
  109. LPVLASERDV lpQDV = lpdv->lpMdv;
  110. if (lpQDV->bFirst)
  111. {
  112. ZeroMemory(lpQDV->lpCyanLastScanLine, (WORD)SCANLINE_BUFFER_SIZE);
  113. ZeroMemory(lpQDV->lpMagentaLastScanLine, (WORD)SCANLINE_BUFFER_SIZE);
  114. ZeroMemory(lpQDV->lpYellowLastScanLine, (WORD)SCANLINE_BUFFER_SIZE);
  115. ZeroMemory(lpQDV->lpBlackLastScanLine, (WORD)SCANLINE_BUFFER_SIZE);
  116. lpQDV->bFirst = FALSE;
  117. }
  118. switch (lpQDV->fColor)
  119. {
  120. case CC_CYAN:
  121. HeaderColorPlain = 0x05;
  122. wLastScanLineLen = lpQDV->wCyanLastScanLineLen;
  123. lpLastScanLine = (LPBYTE) lpQDV->lpCyanLastScanLine;
  124. break;
  125. case CC_MAGENTA:
  126. HeaderColorPlain = 0x06;
  127. wLastScanLineLen = lpQDV->wMagentaLastScanLineLen;
  128. lpLastScanLine = (LPBYTE) lpQDV->lpMagentaLastScanLine;
  129. break;
  130. case CC_YELLOW:
  131. HeaderColorPlain = 0x07;
  132. wLastScanLineLen = lpQDV->wYellowLastScanLineLen;
  133. lpLastScanLine = (LPBYTE) lpQDV->lpYellowLastScanLine;
  134. break;
  135. case CC_BLACK:
  136. HeaderColorPlain = 0x04;
  137. wLastScanLineLen = lpQDV->wBlackLastScanLineLen;
  138. lpLastScanLine = (LPBYTE) lpQDV->lpBlackLastScanLine;
  139. break;
  140. default: // Black&White mode
  141. HeaderColorPlain = 0x04;
  142. wLastScanLineLen = lpQDV->wBlackLastScanLineLen;
  143. lpLastScanLine = (LPBYTE) lpQDV->lpBlackLastScanLine;
  144. }
  145. nCompBufLen = B2Compress(lpLastScanLine, lpBuf,
  146. CompressedScanLine, (wLastScanLineLen > wLen)
  147. ? wLastScanLineLen : wLen);
  148. // send color plain command
  149. WriteSpoolBuf(lpdv, (LPBYTE) &HeaderColorPlain, 1);
  150. if (nCompBufLen == 0) // same two line
  151. {
  152. WriteSpoolBuf(lpdv, (LPBYTE) "\x01", 1);
  153. }
  154. else
  155. {
  156. HeaderScanLine[0] = 0x02;
  157. HeaderScanLine[1] = (BYTE) (nCompBufLen >> 8);
  158. HeaderScanLine[2] = (BYTE) nCompBufLen;
  159. WriteSpoolBuf(lpdv, (LPBYTE) HeaderScanLine, 3);
  160. WriteSpoolBuf(lpdv, (LPBYTE) CompressedScanLine, nCompBufLen);
  161. switch (((LPVLASERDV)lpdv->lpMdv)->fColor)
  162. {
  163. case CC_CYAN: lpQDV->wCyanLastScanLineLen = wLen; break;
  164. case CC_MAGENTA: lpQDV->wMagentaLastScanLineLen = wLen; break;
  165. case CC_YELLOW: lpQDV->wYellowLastScanLineLen = wLen; break;
  166. case CC_BLACK: lpQDV->wBlackLastScanLineLen = wLen; break;
  167. default: lpQDV->wBlackLastScanLineLen = wLen; // Black&White mode
  168. }
  169. }
  170. return nCompBufLen;
  171. }
  172. DRVFN MiniDrvFnTab[] =
  173. {
  174. { INDEX_MiniDrvEnablePDEV, (PFN)MiniDrvEnablePDEV },
  175. { INDEX_MiniDrvDisablePDEV, (PFN)MiniDrvDisablePDEV },
  176. { INDEX_OEMOutputCmd, (PFN)fnOEMOutputCmd },
  177. { INDEX_OEMWriteSpoolBuf, (PFN)CBFilterGraphics },
  178. };
  179. BOOL MiniDrvEnableDriver(MINIDRVENABLEDATA *pEnableData)
  180. {
  181. if (pEnableData == NULL)
  182. return FALSE;
  183. if (pEnableData->cbSize == 0)
  184. {
  185. pEnableData->cbSize = sizeof (MINIDRVENABLEDATA);
  186. return TRUE;
  187. }
  188. if (pEnableData->cbSize < sizeof (MINIDRVENABLEDATA)
  189. || HIBYTE(pEnableData->DriverVersion)
  190. < HIBYTE(MDI_DRIVER_VERSION))
  191. {
  192. // Wrong size and/or mismatched version
  193. return FALSE;
  194. }
  195. // Load callbacks provided by the Unidriver
  196. if (!bLoadUniDrvCallBack(pEnableData,
  197. INDEX_UniDrvWriteSpoolBuf, (PFN *) &WriteSpoolBuf)
  198. || !bLoadUniDrvCallBack(pEnableData,
  199. INDEX_UniDrvAllocMem, (PFN *) &UniDrvAllocMem)
  200. || !bLoadUniDrvCallBack(pEnableData,
  201. INDEX_UniDrvFreeMem, (PFN *) &UniDrvFreeMem))
  202. {
  203. return FALSE;
  204. }
  205. pEnableData->cMiniDrvFn
  206. = sizeof (MiniDrvFnTab) / sizeof(MiniDrvFnTab[0]);
  207. pEnableData->pMiniDrvFn = MiniDrvFnTab;
  208. return TRUE;
  209. }
  210. //
  211. // Block Image 2 Compression
  212. //
  213. WORD B2Compress(LPBYTE pLastScanLine, LPBYTE pCurrentScanLine, LPBYTE pPrnBuf, WORD nImageWidth)
  214. {
  215. LPBYTE pLast, pCurrent, pComp;
  216. LPBYTE pByteNum, pCountByte;
  217. WORD i;
  218. BYTE nSameCount, nDiffCount;
  219. BOOL bSame = TRUE;
  220. pLast = pLastScanLine;
  221. pCurrent = pCurrentScanLine;
  222. pComp = pPrnBuf;
  223. pByteNum = pComp;
  224. nSameCount = 0;
  225. nDiffCount = 0;
  226. pCountByte = pComp++;
  227. for(i=0; i < nImageWidth; i++) {
  228. if(*pCurrent != *pLast) {
  229. bSame = FALSE;
  230. nDiffCount++;
  231. if(nSameCount) {
  232. *pCountByte = nSameCount;
  233. pCountByte = pComp++;
  234. nSameCount = 0;
  235. }
  236. if(nDiffCount > 127) {
  237. *pCountByte = 127 + 128;
  238. pComp = RLE_comp(pCountByte);
  239. pCountByte = pComp++;
  240. nDiffCount -= 127;
  241. }
  242. *pLast = *pCurrent;
  243. *pComp++ = *pCurrent;
  244. } else {
  245. nSameCount++;
  246. if(nDiffCount) {
  247. *pCountByte = nDiffCount + 128;
  248. pComp = RLE_comp(pCountByte);
  249. pCountByte = pComp++;
  250. nDiffCount = 0;
  251. }
  252. if(nSameCount > 127) {
  253. *pCountByte = 127;
  254. pCountByte = pComp++;
  255. nSameCount -= 127;
  256. }
  257. }
  258. pCurrent++;
  259. pLast++;
  260. } // end of for loop
  261. if(nSameCount) *pCountByte = nSameCount;
  262. if(nDiffCount) {
  263. *pCountByte = nDiffCount+128;
  264. pComp = RLE_comp(pCountByte);
  265. }
  266. // if (bSame)
  267. // return((WORD) 0);
  268. // else
  269. return((WORD) (pComp - pByteNum));
  270. }
  271. LPBYTE RLE_comp(LPBYTE p)
  272. {
  273. WORD i, count, RLEEncodedCount;
  274. LPBYTE p1;
  275. BYTE RLEBuffer[SCANLINE_BUFFER_SIZE];
  276. count = (WORD) (*p - 128);
  277. if(count > 4) {
  278. RLEEncodedCount = RLEencoding(p+1, (LPBYTE) RLEBuffer, count);
  279. if(RLEEncodedCount < count) {
  280. *p++ = 0; // RLE encode indicator
  281. *p++ = (BYTE) RLEEncodedCount;
  282. p1 = RLEBuffer;
  283. for(i=0; i<RLEEncodedCount; i++) {
  284. *p++ = *p1++;
  285. }
  286. return(p);
  287. }
  288. }
  289. return(p+1+count);
  290. }
  291. WORD RLEencoding(LPBYTE pCurrent, LPBYTE pComp, WORD count)
  292. {
  293. WORD i, nByteNum;
  294. BYTE curr, next, RLEcount;
  295. nByteNum = 0;
  296. RLEcount = 1;
  297. for(i=0; i<count-1; i++) {
  298. curr = *pCurrent++;
  299. next = *pCurrent;
  300. if(curr == next) {
  301. if(RLEcount == 255) {
  302. *pComp++ = RLEcount;
  303. *pComp++ = curr;
  304. nByteNum += 2;
  305. RLEcount = 1;
  306. } else {
  307. RLEcount++;
  308. }
  309. } else {
  310. *pComp++ = RLEcount;
  311. *pComp++ = curr;
  312. nByteNum += 2;
  313. RLEcount = 1;
  314. }
  315. }
  316. *pComp++ = RLEcount;
  317. *pComp++ = next;
  318. nByteNum += 2;
  319. return(nByteNum);
  320. }