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.

433 lines
13 KiB

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