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.

468 lines
14 KiB

  1. /*****************************************************************************\
  2. * Smart 256 Colour Bank Manager
  3. *
  4. * Copyright (c) 1992 Microsoft Corporation
  5. \*****************************************************************************/
  6. #include "driver.h"
  7. /*****************************************************************************\
  8. * pcoBankStart - Start the bank enumeration using the clip object.
  9. *
  10. * Used when the destination is the screen and we can't do the clipping
  11. * ourselves (as we can for blt's).
  12. \*****************************************************************************/
  13. CLIPOBJ* pcoBankStart(
  14. PPDEV ppdev,
  15. RECTL* prclScans,
  16. SURFOBJ* pso,
  17. CLIPOBJ* pco)
  18. {
  19. LONG iTopScan = max(0, prclScans->top);
  20. if (pco)
  21. {
  22. iTopScan = max(prclScans->top, pco->rclBounds.top);
  23. }
  24. // Adjust for those weird cases where we're asked to start enumerating
  25. // below the bottom of the screen:
  26. iTopScan = min(iTopScan, (LONG) ppdev->cyScreen - 1);
  27. // Map in the bank:
  28. if (iTopScan < ppdev->rcl1WindowClip.top ||
  29. iTopScan >= ppdev->rcl1WindowClip.bottom)
  30. {
  31. ppdev->pfnBankControl(ppdev, iTopScan, JustifyTop);
  32. }
  33. // Remember what the last scan is that we're going to, and
  34. // make sure we only try to go as far as we need to. It could
  35. // happen that when get a prclScans bigger than the screen:
  36. ppdev->iLastScan = min(prclScans->bottom, (LONG) ppdev->cyScreen);
  37. if (pco)
  38. {
  39. ppdev->iLastScan = min(ppdev->iLastScan, pco->rclBounds.bottom);
  40. }
  41. pso->pvScan0 = ppdev->pvBitmapStart;
  42. if (pco == NULL)
  43. {
  44. // The call may have come down to us as having no clipping, but
  45. // we have to clip to the banks, so use our own clip object:
  46. pco = ppdev->pcoNull;
  47. pco->rclBounds = ppdev->rcl1WindowClip;
  48. }
  49. else
  50. {
  51. // Save the engine's clip object data that we'll be tromping on:
  52. ppdev->rclSaveBounds = pco->rclBounds;
  53. ppdev->iSaveDComplexity = pco->iDComplexity;
  54. ppdev->fjSaveOptions = pco->fjOptions;
  55. // Let engine know it has to pay attention to the rclBounds of the
  56. // clip object:
  57. pco->fjOptions |= OC_BANK_CLIP;
  58. if (pco->iDComplexity == DC_TRIVIAL)
  59. pco->iDComplexity = DC_RECT;
  60. // Use the bank bounds if they are tighter than the existing
  61. // bounds. We don't have to check the left case here because we
  62. // know that ppdev->rcl1WindowClip.left == 0.
  63. if (pco->rclBounds.top <= ppdev->rcl1WindowClip.top)
  64. pco->rclBounds.top = ppdev->rcl1WindowClip.top;
  65. if (pco->rclBounds.right >= ppdev->rcl1WindowClip.right)
  66. pco->rclBounds.right = ppdev->rcl1WindowClip.right;
  67. if (pco->rclBounds.bottom >= ppdev->rcl1WindowClip.bottom)
  68. pco->rclBounds.bottom = ppdev->rcl1WindowClip.bottom;
  69. if ((pco->rclBounds.top >= pco->rclBounds.bottom) ||
  70. (pco->rclBounds.left >= pco->rclBounds.right))
  71. {
  72. // It's conceivable that we could get a situation where our
  73. // draw rectangle is completely disjoint from the specified
  74. // rectangle's rclBounds. Make sure we don't puke on our
  75. // shoes:
  76. pco->rclBounds.left = 0;
  77. pco->rclBounds.top = 0;
  78. pco->rclBounds.right = 0;
  79. pco->rclBounds.bottom = 0;
  80. ppdev->iLastScan = 0;
  81. }
  82. }
  83. return(pco);
  84. }
  85. /*****************************************************************************\
  86. * bBankEnum - Continue the bank enumeration.
  87. \*****************************************************************************/
  88. BOOL bBankEnum(PPDEV ppdev, SURFOBJ* pso, CLIPOBJ* pco)
  89. {
  90. // If we're on the first portion of a broken raster, get the next:
  91. LONG yNewTop = ppdev->rcl1WindowClip.bottom;
  92. DISPDBG((4, "bBankEnum: Start.\n"));
  93. if (ppdev->flBank & BANK_BROKEN_RASTER1)
  94. ppdev->pfnBankNext(ppdev);
  95. else if (ppdev->rcl1WindowClip.bottom < ppdev->iLastScan)
  96. ppdev->pfnBankControl(ppdev, yNewTop, JustifyTop);
  97. else
  98. {
  99. // Okay, that was the last bank, so restore our structures:
  100. if (pco != ppdev->pcoNull)
  101. {
  102. pco->rclBounds = ppdev->rclSaveBounds;
  103. pco->iDComplexity = ppdev->iSaveDComplexity;
  104. pco->fjOptions = ppdev->fjSaveOptions;
  105. }
  106. return(FALSE);
  107. }
  108. // Adjust the pvScan0 because we've moved the window to view
  109. // a different area:
  110. pso->pvScan0 = ppdev->pvBitmapStart;
  111. if (pco == ppdev->pcoNull)
  112. {
  113. // If were given a NULL clip object originally, we don't have
  114. // to worry about clipping to ppdev->rclSaveBounds:
  115. pco->rclBounds.top = yNewTop;
  116. pco->rclBounds.left = ppdev->rcl1WindowClip.left;
  117. pco->rclBounds.bottom = ppdev->rcl1WindowClip.bottom;
  118. pco->rclBounds.right = ppdev->rcl1WindowClip.right;
  119. }
  120. else
  121. {
  122. // Use the bank bounds if they are tighter than the bounds
  123. // we were originally given:
  124. pco->rclBounds = ppdev->rclSaveBounds;
  125. if (pco->rclBounds.top <= yNewTop)
  126. pco->rclBounds.top = yNewTop;
  127. if (pco->rclBounds.left <= ppdev->rcl1WindowClip.left)
  128. pco->rclBounds.left = ppdev->rcl1WindowClip.left;
  129. if (pco->rclBounds.right >= ppdev->rcl1WindowClip.right)
  130. pco->rclBounds.right = ppdev->rcl1WindowClip.right;
  131. if (pco->rclBounds.bottom >= ppdev->rcl1WindowClip.bottom)
  132. pco->rclBounds.bottom = ppdev->rcl1WindowClip.bottom;
  133. }
  134. DISPDBG((4, "bBankEnum: Leaving.\n"));
  135. return(TRUE);
  136. }
  137. /***************************************************************************\
  138. * vBankStartBltSrc - Start the bank enumeration for when the screen is
  139. * the source.
  140. \***************************************************************************/
  141. VOID vBankStartBltSrc(
  142. PPDEV ppdev,
  143. SURFOBJ* pso,
  144. POINTL* pptlSrc,
  145. RECTL* prclDest,
  146. POINTL* pptlNewSrc,
  147. RECTL* prclNewDest)
  148. {
  149. LONG xRightSrc;
  150. LONG yBottomSrc;
  151. LONG iTopScan = max(0, pptlSrc->y);
  152. DISPDBG((4, "vBankStartBltSrc: Entering.\n"));
  153. if (iTopScan >= (LONG) ppdev->cyScreen)
  154. {
  155. // In some instances we may be asked to start on a scan below the screen.
  156. // Since we obviously won't be drawing anything, don't bother mapping in
  157. // a bank:
  158. return;
  159. }
  160. // Map in the bank:
  161. if (iTopScan < ppdev->rcl1WindowClip.top ||
  162. iTopScan >= ppdev->rcl1WindowClip.bottom)
  163. {
  164. ppdev->pfnBankControl(ppdev, iTopScan, JustifyTop);
  165. }
  166. if (ppdev->rcl1WindowClip.right <= pptlSrc->x)
  167. {
  168. // We have to watch out for those rare cases where we're starting
  169. // on a broken raster and we won't be drawing on the first part:
  170. ASSERTVGA(ppdev->flBank & BANK_BROKEN_RASTER1, "Weird start bounds");
  171. ppdev->pfnBankNext(ppdev);
  172. }
  173. pso->pvScan0 = ppdev->pvBitmapStart;
  174. // Adjust the source:
  175. pptlNewSrc->x = pptlSrc->x;
  176. pptlNewSrc->y = pptlSrc->y;
  177. // Adjust the destination:
  178. prclNewDest->left = prclDest->left;
  179. prclNewDest->top = prclDest->top;
  180. yBottomSrc = pptlSrc->y + prclDest->bottom - prclDest->top;
  181. prclNewDest->bottom = min(ppdev->rcl1WindowClip.bottom, yBottomSrc);
  182. prclNewDest->bottom += prclDest->top - pptlSrc->y;
  183. xRightSrc = pptlSrc->x + prclDest->right - prclDest->left;
  184. prclNewDest->right = min(ppdev->rcl1WindowClip.right, xRightSrc);
  185. prclNewDest->right += prclDest->left - pptlSrc->x;
  186. DISPDBG((4, "vBankStartBltSrc: Leaving.\n"));
  187. }
  188. /***************************************************************************\
  189. * bBankEnumBltSrc - Continue the bank enumeration for when the screen is
  190. * the source.
  191. \***************************************************************************/
  192. BOOL bBankEnumBltSrc(
  193. PPDEV ppdev,
  194. SURFOBJ* pso,
  195. POINTL* pptlSrc,
  196. RECTL* prclDest,
  197. POINTL* pptlNewSrc,
  198. RECTL* prclNewDest)
  199. {
  200. LONG xLeftSrc;
  201. LONG xRightSrc;
  202. LONG yBottomSrc;
  203. LONG cx = prclDest->right - prclDest->left;
  204. LONG cy = prclDest->bottom - prclDest->top;
  205. LONG dx;
  206. LONG dy;
  207. LONG yBottom = min(pptlSrc->y + cy, (LONG) ppdev->cyScreen);
  208. LONG yNewTop = ppdev->rcl1WindowClip.bottom;
  209. DISPDBG((4, "bBankEnumBltSrc: Entering.\n"));
  210. if (ppdev->flBank & BANK_BROKEN_RASTER1)
  211. {
  212. ppdev->pfnBankNext(ppdev);
  213. if (ppdev->rcl1WindowClip.left >= pptlSrc->x + cx)
  214. {
  215. if (ppdev->rcl1WindowClip.bottom < yBottom)
  216. ppdev->pfnBankNext(ppdev);
  217. else
  218. {
  219. // We're done:
  220. return(FALSE);
  221. }
  222. }
  223. }
  224. else if (yNewTop < yBottom)
  225. {
  226. ppdev->pfnBankControl(ppdev, yNewTop, JustifyTop);
  227. if (ppdev->rcl1WindowClip.right <= pptlSrc->x)
  228. {
  229. ASSERTVGA(ppdev->flBank & BANK_BROKEN_RASTER1, "Weird bounds");
  230. ppdev->pfnBankNext(ppdev);
  231. }
  232. }
  233. else
  234. {
  235. // We're done:
  236. return(FALSE);
  237. }
  238. // Adjust the source:
  239. pso->pvScan0 = ppdev->pvBitmapStart;
  240. pptlNewSrc->x = max(ppdev->rcl1WindowClip.left, pptlSrc->x);
  241. pptlNewSrc->y = yNewTop;
  242. // Adjust the destination:
  243. dy = prclDest->top - pptlSrc->y; // y delta from source to dest
  244. prclNewDest->top = yNewTop + dy;
  245. yBottomSrc = pptlSrc->y + cy;
  246. prclNewDest->bottom = min(ppdev->rcl1WindowClip.bottom, yBottomSrc) + dy;
  247. dx = prclDest->left - pptlSrc->x; // x delta from source to dest
  248. xLeftSrc = pptlSrc->x;
  249. prclNewDest->left = pptlNewSrc->x + dx;
  250. xRightSrc = pptlSrc->x + cx;
  251. prclNewDest->right = min(ppdev->rcl1WindowClip.right, xRightSrc) + dx;
  252. DISPDBG((4, "bBankEnumBltSrc: Leaving.\n"));
  253. return(TRUE);
  254. }
  255. /***************************************************************************\
  256. * vBankStartBltDest - Start the bank enumeration for when the screen is
  257. * the destination.
  258. \***************************************************************************/
  259. VOID vBankStartBltDest(
  260. PPDEV ppdev,
  261. SURFOBJ* pso,
  262. POINTL* pptlSrc,
  263. RECTL* prclDest,
  264. POINTL* pptlNewSrc,
  265. RECTL* prclNewDest)
  266. {
  267. LONG iTopScan = max(0, prclDest->top);
  268. DISPDBG((4, "vBankSTartBltDest: Entering.\n"));
  269. if (iTopScan >= (LONG) ppdev->cyScreen)
  270. {
  271. // In some instances we may be asked to start on a scan below the screen.
  272. // Since we obviously won't be drawing anything, don't bother mapping in
  273. // a bank:
  274. return;
  275. }
  276. // Map in the bank:
  277. if (iTopScan < ppdev->rcl1WindowClip.top ||
  278. iTopScan >= ppdev->rcl1WindowClip.bottom)
  279. {
  280. ppdev->pfnBankControl(ppdev, iTopScan, JustifyTop);
  281. }
  282. if (ppdev->rcl1WindowClip.right <= prclDest->left)
  283. {
  284. // We have to watch out for those rare cases where we're starting
  285. // on a broken raster and we won't be drawing on the first part:
  286. ASSERTVGA(ppdev->flBank & BANK_BROKEN_RASTER1, "Weird start bounds");
  287. ppdev->pfnBankNext(ppdev);
  288. }
  289. pso->pvScan0 = ppdev->pvBitmapStart;
  290. // Adjust the destination:
  291. prclNewDest->left = prclDest->left;
  292. prclNewDest->top = prclDest->top;
  293. prclNewDest->bottom = min(ppdev->rcl1WindowClip.bottom, prclDest->bottom);
  294. prclNewDest->right = min(ppdev->rcl1WindowClip.right, prclDest->right);
  295. // Adjust the source if there is one:
  296. if (pptlSrc != NULL)
  297. *pptlNewSrc = *pptlSrc;
  298. DISPDBG((4, "vBankStartBltDest: Leaving.\n"));
  299. }
  300. /***************************************************************************\
  301. * bBankEnumBltDest - Continue the bank enumeration for when the screen is
  302. * the destination.
  303. \***************************************************************************/
  304. BOOL bBankEnumBltDest(
  305. PPDEV ppdev,
  306. SURFOBJ* pso,
  307. POINTL* pptlSrc,
  308. RECTL* prclDest,
  309. POINTL* pptlNewSrc,
  310. RECTL* prclNewDest)
  311. {
  312. LONG yBottom = min(prclDest->bottom, (LONG) ppdev->cyScreen);
  313. LONG yNewTop = ppdev->rcl1WindowClip.bottom;
  314. DISPDBG((4, "bBankEnumBltDest: Entering.\n"));
  315. if (ppdev->flBank & BANK_BROKEN_RASTER1)
  316. {
  317. ppdev->pfnBankNext(ppdev);
  318. if (ppdev->rcl1WindowClip.left >= prclDest->right)
  319. {
  320. if (ppdev->rcl1WindowClip.bottom < yBottom)
  321. ppdev->pfnBankNext(ppdev);
  322. else
  323. {
  324. // We're done:
  325. return(FALSE);
  326. }
  327. }
  328. }
  329. else if (yNewTop < yBottom)
  330. {
  331. ppdev->pfnBankControl(ppdev, yNewTop, JustifyTop);
  332. if (ppdev->rcl1WindowClip.right <= prclDest->left)
  333. {
  334. ASSERTVGA(ppdev->flBank & BANK_BROKEN_RASTER1, "Weird bounds");
  335. ppdev->pfnBankNext(ppdev);
  336. }
  337. }
  338. else
  339. {
  340. // We're done:
  341. return(FALSE);
  342. }
  343. pso->pvScan0 = ppdev->pvBitmapStart;
  344. // Adjust the destination:
  345. prclNewDest->top = yNewTop;
  346. prclNewDest->left = max(ppdev->rcl1WindowClip.left, prclDest->left);
  347. prclNewDest->bottom = min(ppdev->rcl1WindowClip.bottom, prclDest->bottom);
  348. prclNewDest->right = min(ppdev->rcl1WindowClip.right, prclDest->right);
  349. // Adjust the source if there is one:
  350. if (pptlSrc != NULL)
  351. {
  352. pptlNewSrc->x = pptlSrc->x + (prclNewDest->left - prclDest->left);
  353. pptlNewSrc->y = pptlSrc->y + (prclNewDest->top - prclDest->top);
  354. }
  355. DISPDBG((4, "bBankEnumBltDest: Leaving.\n"));
  356. return(TRUE);
  357. }