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.

395 lines
11 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: PAINT.c
  3. * Author: Noel VanHook
  4. * Date: Mar. 21, 1995
  5. * Purpose: Handle calls to DrvPaint
  6. *
  7. * Copyright (c) 1995 Cirrus Logic, Inc.
  8. *
  9. \**************************************************************************/
  10. /*
  11. This module handles calls to DrvPaint() by converting them into calls
  12. to DrvBitBlt(). The only conversion needed to to change the MIX into
  13. a ROP4.
  14. */
  15. #include "precomp.h"
  16. #define PAINT_DBG_LEVEL 1
  17. //==========================================================================
  18. //
  19. // In an attempt to trace the problems with the FIFO, we supply a few
  20. // macros that will allow us to easily try different FIFO stratagies.
  21. //
  22. //
  23. // This macro is executed at the start of every BLT, before any registers
  24. // are written.
  25. //
  26. #define STARTBLT() \
  27. do { \
  28. }while (0)
  29. //
  30. // This macro is executed at the top of inner BLT loops.
  31. // If there were clipping, for example, STARTBLT() would be executed
  32. // once at the start of the BLT, and STARTBLTLOOP() would be executed
  33. // before each rectangle in the clip list.
  34. //
  35. #define STARTBLTLOOP() \
  36. do { \
  37. REQUIRE(0); \
  38. }while (0)
  39. //==========================================================================
  40. //
  41. // Table to convert ROP2 codes to ROP3 codes.
  42. //
  43. BYTE Rop2ToRop3[]=
  44. {
  45. 0xFF, // R2_WHITE /* 1 */
  46. 0x00, // R2_BLACK /* 0 */
  47. 0x05, // R2_NOTMERGEPEN /* DPon */
  48. 0x0A, // R2_MASKNOTPEN /* DPna */
  49. 0x0F, // R2_NOTCOPYPEN /* PN */
  50. 0x50, // R2_MASKPENNOT /* PDna */
  51. 0x55, // R2_NOT /* Dn */
  52. 0x5A, // R2_XORPEN /* DPx */
  53. 0x5F, // R2_NOTMASKPEN /* DPan */
  54. 0xA0, // R2_MASKPEN /* DPa */
  55. 0xA5, // R2_NOTXORPEN /* DPxn */
  56. 0xAA, // R2_NOP /* D */
  57. 0xAF, // R2_MERGENOTPEN /* DPno */
  58. 0xF0, // R2_COPYPEN /* P */
  59. 0xF5, // R2_MERGEPENNOT /* PDno */
  60. 0xFA, // R2_MERGEPEN /* DPo */
  61. 0xFF // R2_WHITE /* 1 */
  62. };
  63. //
  64. // If data logging is enabled, Prototype the logging files.
  65. //
  66. #if LOG_CALLS
  67. void LogPaint(
  68. int acc,
  69. SURFOBJ* psoDest,
  70. MIX mix,
  71. CLIPOBJ* pco,
  72. BRUSHOBJ* pbo);
  73. //
  74. // If data logging is not enabled, compile out the calls.
  75. //
  76. #else
  77. #define LogPaint(acc, psoDest, mix, pco, pbo)
  78. #endif
  79. /**************************************************************************\
  80. * DrvPaint *
  81. * *
  82. * Paint the clipping region with the specified brush *
  83. * Accomplished by converting into a call to DrvBitBlt() *
  84. * *
  85. \**************************************************************************/
  86. BOOL DrvPaint
  87. (
  88. SURFOBJ *pso,
  89. CLIPOBJ *pco,
  90. BRUSHOBJ *pbo,
  91. POINTL *pptlBrush,
  92. MIX mix
  93. )
  94. {
  95. ULONG fg_rop, bg_rop, rop4;
  96. DWORD color;
  97. PPDEV ppdev;
  98. #if NULL_PAINT
  99. {
  100. if (pointer_switch) return TRUE;
  101. }
  102. #endif
  103. ppdev = (PPDEV) pso->dhpdev;
  104. ASSERTMSG (ppdev,"No PDEV in DrvPaint.");
  105. SYNC_W_3D(ppdev);
  106. //
  107. // The destination rectangle is defined by the clipping region,
  108. // so we should never get a null clipping region.
  109. //
  110. ASSERTMSG (pco, "DrvPaint without a clip object!\n");
  111. DISPDBG((PAINT_DBG_LEVEL,"Drvpaint: Entry.\n"));
  112. // Are we painting to a device bitmap?
  113. if (pso->iType == STYPE_DEVBITMAP)
  114. {
  115. // Yes.
  116. PDSURF pdsurf = (PDSURF)pso->dhsurf;
  117. // Is the device bitmap currently in host memory?
  118. if ( pdsurf->pso )
  119. {
  120. // Yes. Move it into off screen memory.
  121. if ( !bCreateScreenFromDib(ppdev, pdsurf) )
  122. {
  123. // We couldn't move it to off-screen memory.
  124. LogPaint(1, pso, mix, pco, pbo);
  125. return EngPaint(pdsurf->pso, pco, pbo, pptlBrush, mix);
  126. }
  127. }
  128. // The device bitmap now resides in off-screen memory.
  129. // This is the offset to it.
  130. ppdev->ptlOffset.x = pdsurf->ptl.x;
  131. ppdev->ptlOffset.y = pdsurf->ptl.y;
  132. }
  133. else
  134. {
  135. // No, we are not painting to a device bitmap.
  136. ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
  137. }
  138. //
  139. // DrvPaint is most often called with
  140. // mix 0D (PAT COPY) and mix 06 (DEST INVERT).
  141. // It behooves us, therefore, to handle these as
  142. // special cases... provided they aren't clipped.
  143. //
  144. if ((pco->iDComplexity != DC_COMPLEX))
  145. {
  146. // =================== PATCOPY ==================================
  147. if (mix == 0x0D0D)
  148. {
  149. ASSERTMSG(pbo, "DrvPaint PATCOPY without a brush.\n");
  150. if (pbo->iSolidColor != 0xFFFFFFFF) // Solid color
  151. {
  152. color = pbo->iSolidColor;
  153. switch (ppdev->ulBitCount)
  154. {
  155. case 8: // For 8 bpp duplicate byte 0 into byte 1.
  156. color |= (color << 8);
  157. case 16: // For 8,16 bpp, duplicate the low word into the high word.
  158. color |= (color << 16);
  159. break;
  160. }
  161. REQUIRE(9);
  162. LL_BGCOLOR(color, 0);
  163. LL_DRAWBLTDEF(0x100700F0, 0);
  164. LL_OP0(pco->rclBounds.left + ppdev->ptlOffset.x,
  165. pco->rclBounds.top + ppdev->ptlOffset.y);
  166. LL_BLTEXT ((pco->rclBounds.right - pco->rclBounds.left),
  167. (pco->rclBounds.bottom - pco->rclBounds.top));
  168. LogPaint(0, pso, mix, pco, pbo);
  169. return TRUE;
  170. } // End PATCOPY with solid color.
  171. else // PATCOPY with a brush.
  172. {
  173. DWORD bltdef = 0x1000;
  174. if (SetBrush(ppdev, &bltdef, pbo, pptlBrush))
  175. {
  176. REQUIRE(7);
  177. LL_DRAWBLTDEF((bltdef << 16) | 0x00F0, 0);
  178. LL_OP0 (pco->rclBounds.left + ppdev->ptlOffset.x,
  179. pco->rclBounds.top + ppdev->ptlOffset.y);
  180. LL_BLTEXT ((pco->rclBounds.right - pco->rclBounds.left) ,
  181. (pco->rclBounds.bottom - pco->rclBounds.top) );
  182. LogPaint(0, pso, mix, pco, pbo);
  183. return TRUE;
  184. }
  185. } // End PATCOPY with a brush
  186. } // End PATCOPY
  187. // ======================= DEST INVERT ============================
  188. else if (mix == 0x0606)
  189. {
  190. REQUIRE(7);
  191. LL_DRAWBLTDEF(0x11000055, 0);
  192. LL_OP0(pco->rclBounds.left + ppdev->ptlOffset.x,
  193. pco->rclBounds.top + ppdev->ptlOffset.y);
  194. LL_BLTEXT ((pco->rclBounds.right - pco->rclBounds.left),
  195. (pco->rclBounds.bottom - pco->rclBounds.top) );
  196. LogPaint(0, pso, mix, pco, pbo);
  197. return TRUE;
  198. } // End DEST INVERT
  199. } // End special cases
  200. // First, convert the fg and bg mix into a fg and bg rop
  201. fg_rop = Rop2ToRop3[ (mix & 0x0F) ]; // convert fg mix to fg rop.
  202. bg_rop = Rop2ToRop3[ ((mix>>8) & 0x0F) ]; // convert bg mix to bg rop
  203. rop4 = (bg_rop<<8) | fg_rop; // build rop4.
  204. //
  205. // Now convert Paint to BitBLT
  206. //
  207. LogPaint(2, pso, mix, pco, pbo);
  208. DISPDBG((PAINT_DBG_LEVEL,"Drvpaint: Convert to DrvBitBlt().\n"));
  209. return DrvBitBlt(pso, // Target
  210. (SURFOBJ *) NULL, // Source
  211. (SURFOBJ *) NULL, // Mask
  212. pco, // Clip object
  213. (XLATEOBJ *) NULL, // Xlate object
  214. &(pco->rclBounds), // Dest rectangle.
  215. (PPOINTL) NULL, // Src point.
  216. (PPOINTL) NULL, // Mask point.
  217. pbo, // Brush
  218. pptlBrush, // Brush alignment
  219. rop4); // ROP4
  220. }
  221. #if LOG_CALLS
  222. // ============================================================================
  223. //
  224. // Everything from here down is for data logging and is not used in the
  225. // production driver.
  226. //
  227. // ============================================================================
  228. // ****************************************************************************
  229. //
  230. // LogPaint()
  231. // This routine is called only from DrvPaint()
  232. // Dump information to a file about what is going on in DrvPaint land.
  233. //
  234. // ****************************************************************************
  235. void LogPaint(
  236. int acc,
  237. SURFOBJ* psoDest,
  238. MIX mix,
  239. CLIPOBJ* pco,
  240. BRUSHOBJ* pbo)
  241. {
  242. PPDEV dppdev,sppdev,ppdev;
  243. char buf[256];
  244. int i;
  245. BYTE fg_rop, bg_rop;
  246. ULONG iDComplexity;
  247. ppdev = (PPDEV) (psoDest ? psoDest->dhpdev : 0);
  248. #if ENABLE_LOG_SWITCH
  249. if (pointer_switch == 0) return;
  250. #endif
  251. i = sprintf(buf,"DrvPaint: ");
  252. WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  253. switch(acc)
  254. {
  255. case 0: // Accelerated
  256. i = sprintf(buf, "ACCL ");
  257. break;
  258. case 1: // Punted
  259. i = sprintf(buf,"PUNT host ");
  260. break;
  261. case 2: // Punted
  262. i = sprintf(buf, "PUNT BitBlt ");
  263. break;
  264. default:
  265. i = sprintf(buf, "PUNT unknown ");
  266. break;
  267. }
  268. WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  269. //
  270. // Check the DEST
  271. //
  272. if (psoDest)
  273. {
  274. if (psoDest->iType == STYPE_DEVBITMAP)
  275. {
  276. i = sprintf(buf, "Id=%p ", psoDest->dhsurf);
  277. WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  278. if ( ((PDSURF)psoDest->dhsurf)->pso )
  279. i = sprintf(buf,"DST=DH ");
  280. else
  281. i = sprintf(buf,"DST=DF ");
  282. }
  283. else if (psoDest->hsurf == ppdev->hsurfEng)
  284. i = sprintf(buf,"DST=S ");
  285. else
  286. i = sprintf(buf,"DST=H ");
  287. }
  288. else
  289. i = sprintf(buf,"DST=N ");
  290. WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  291. //
  292. // Check the MIX
  293. //
  294. i = sprintf(buf,"MIX = 0x%04X ", mix);
  295. WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  296. //
  297. // Check the type of clipping.
  298. //
  299. iDComplexity = (pco ? pco->iDComplexity : DC_TRIVIAL);
  300. i = sprintf(buf,"CLIP=%s ",
  301. (iDComplexity==DC_TRIVIAL ? "T":
  302. (iDComplexity == DC_RECT ? "R" : "C" )));
  303. WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  304. //
  305. // Type of pattern.
  306. //
  307. if (pbo == NULL)
  308. {
  309. i = sprintf(buf,"BRUSH=N ");
  310. WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  311. }
  312. else if (pbo->iSolidColor == 0xFFFFFFFF )
  313. {
  314. i = sprintf(buf,"BRUSH=P ");
  315. WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  316. }
  317. else
  318. {
  319. i = sprintf(buf,"BRUSH=0x%08X ",(pbo->iSolidColor));
  320. WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  321. }
  322. i = sprintf(buf,"\r\n");
  323. WriteLogFile(ppdev->pmfile, buf, i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  324. }
  325. #endif