Source code of Windows XP (NT5)
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.

445 lines
10 KiB

  1. /****************************************************************************\
  2. *
  3. * Dirty region calculation
  4. *
  5. * 14-Feb-1995 mikeke Created
  6. *
  7. * Copyright (c) 1994 Microsoft Corporation
  8. \****************************************************************************/
  9. #include "precomp.h"
  10. #pragma hdrstop
  11. /****************************************************************************/
  12. PXLIST XLISTAlloc(
  13. __GLGENbuffers *buffers)
  14. {
  15. PXLIST pxlist;
  16. if (buffers->pxlist != NULL) {
  17. pxlist = buffers->pxlist;
  18. buffers->pxlist = pxlist->pnext;
  19. } else {
  20. pxlist = (PXLIST)ALLOC(sizeof(XLIST));
  21. if (pxlist == NULL) return NULL;
  22. }
  23. pxlist->pnext = NULL;
  24. return pxlist;
  25. }
  26. /****************************************************************************/
  27. void XLISTFree(
  28. __GLGENbuffers *buffers,
  29. PXLIST pxlist)
  30. {
  31. pxlist->pnext = buffers->pxlist;
  32. buffers->pxlist = pxlist;
  33. }
  34. /****************************************************************************/
  35. PXLIST XLISTCopy(
  36. __GLGENbuffers *buffers,
  37. PXLIST pxlist)
  38. {
  39. PXLIST pxlistNew = XLISTAlloc(buffers);
  40. if (pxlistNew != NULL) {
  41. pxlistNew->s = pxlist->s;
  42. pxlistNew->e = pxlist->e;
  43. }
  44. return pxlistNew;
  45. }
  46. /****************************************************************************/
  47. BOOL YLISTAddSpan(
  48. __GLGENbuffers *buffers,
  49. PYLIST pylist,
  50. int xs,
  51. int xe)
  52. {
  53. PXLIST *ppxlist = &(pylist->pxlist);
  54. PXLIST pxlist = XLISTAlloc(buffers);
  55. if (pxlist == NULL) return FALSE;
  56. //
  57. // Create new x span
  58. //
  59. pxlist->s = xs;
  60. pxlist->e = xe;
  61. //
  62. // Insert it in sorted order
  63. //
  64. while (
  65. ((*ppxlist) != NULL)
  66. && ((*ppxlist)->s < xs)
  67. ) {
  68. ppxlist = &((*ppxlist)->pnext);
  69. }
  70. pxlist->pnext = *ppxlist;
  71. *ppxlist = pxlist;
  72. //
  73. // Combine any overlapping spans
  74. //
  75. pxlist = pylist->pxlist;
  76. while (TRUE) {
  77. PXLIST pxlistNext = pxlist->pnext;
  78. if (pxlistNext == NULL) return TRUE;
  79. if (pxlist->e >= pxlistNext->s) {
  80. if (pxlistNext->e > pxlist->e) {
  81. pxlist->e = pxlistNext->e;
  82. }
  83. pxlist->pnext = pxlistNext->pnext;
  84. XLISTFree(buffers, pxlistNext);
  85. } else {
  86. pxlist = pxlist->pnext;
  87. }
  88. }
  89. return TRUE;
  90. }
  91. /****************************************************************************/
  92. PYLIST YLISTAlloc(
  93. __GLGENbuffers *buffers)
  94. {
  95. PYLIST pylist;
  96. if (buffers->pylist != NULL) {
  97. pylist = buffers->pylist;
  98. buffers->pylist = pylist->pnext;
  99. } else {
  100. pylist = (PYLIST)ALLOC(sizeof(YLIST));
  101. if (pylist == NULL) return NULL;
  102. }
  103. pylist->pxlist = NULL;
  104. pylist->pnext = NULL;
  105. return pylist;
  106. }
  107. /****************************************************************************/
  108. void YLISTFree(
  109. __GLGENbuffers *buffers,
  110. PYLIST pylist)
  111. {
  112. PXLIST pxlist = pylist->pxlist;
  113. PXLIST pxlistKill;
  114. while (pxlist != NULL) {
  115. pxlistKill = pxlist;
  116. pxlist = pxlist->pnext;
  117. XLISTFree(buffers, pxlistKill);
  118. }
  119. pylist->pnext = buffers->pylist;
  120. buffers->pylist = pylist;
  121. }
  122. /****************************************************************************/
  123. PYLIST YLISTCopy(
  124. __GLGENbuffers *buffers,
  125. PYLIST pylist)
  126. {
  127. PXLIST pxlist = pylist->pxlist;
  128. PXLIST *ppxlist;
  129. PYLIST pylistNew = YLISTAlloc(buffers);
  130. if (pylistNew != NULL) {
  131. pylistNew->s = pylist->s;
  132. pylistNew->e = pylist->e;
  133. ppxlist = &(pylistNew->pxlist);
  134. while (pxlist != NULL) {
  135. *ppxlist = XLISTCopy(buffers, pxlist);
  136. if (*ppxlist == NULL) {
  137. YLISTFree(buffers, pylistNew);
  138. return NULL;
  139. }
  140. ppxlist = &((*ppxlist)->pnext);
  141. pxlist = pxlist->pnext;
  142. }
  143. *ppxlist = NULL;
  144. }
  145. return pylistNew;
  146. }
  147. /****************************************************************************/
  148. void RECTLISTAddRect(
  149. PRECTLIST prl,
  150. int xs,
  151. int ys,
  152. int xe,
  153. int ye)
  154. {
  155. __GLGENbuffers *buffers = (__GLGENbuffers *)(prl->buffers);
  156. PYLIST* ppylist;
  157. PYLIST pylistNew;
  158. ppylist = &(prl->pylist);
  159. while ((*ppylist) != NULL) {
  160. if (ys < (*ppylist)->e) break;
  161. ppylist = &((*ppylist)->pnext);
  162. }
  163. while ((*ppylist) != NULL) {
  164. if (ys < (*ppylist)->s) {
  165. PYLIST pylistNew = YLISTAlloc(buffers);
  166. if (pylistNew == NULL) {
  167. OutOfMemory:
  168. RECTLISTSetEmpty(prl);
  169. return;
  170. }
  171. pylistNew->s = ys;
  172. pylistNew->e = ye;
  173. if (!YLISTAddSpan(buffers, pylistNew, xs, xe)) {
  174. goto OutOfMemory;
  175. }
  176. pylistNew->pnext = *ppylist;
  177. *ppylist = pylistNew;
  178. ppylist = &((*ppylist)->pnext);
  179. if (ye <= (*ppylist)->s) {
  180. return;
  181. }
  182. pylistNew->e = (*ppylist)->s;
  183. ys = (*ppylist)->s;
  184. } else if (ys == (*ppylist)->s) {
  185. if (ye >= (*ppylist)->e) {
  186. if (!YLISTAddSpan(buffers, *ppylist, xs, xe)) {
  187. goto OutOfMemory;
  188. }
  189. ys = (*ppylist)->e;
  190. if (ys == ye) return;
  191. ppylist = &((*ppylist)->pnext);
  192. } else {
  193. PYLIST pylistNew = YLISTCopy(buffers, *ppylist);
  194. if (pylistNew == NULL) {
  195. goto OutOfMemory;
  196. }
  197. pylistNew->e = ye;
  198. if (!YLISTAddSpan(buffers, pylistNew, xs, xe)) {
  199. goto OutOfMemory;
  200. }
  201. (*ppylist)->s = ye;
  202. pylistNew->pnext = *ppylist;
  203. *ppylist = pylistNew;
  204. return;
  205. }
  206. } else {
  207. PYLIST pylistNew = YLISTCopy(buffers, *ppylist);
  208. if (pylistNew == NULL) {
  209. goto OutOfMemory;
  210. }
  211. pylistNew->e = ys;
  212. (*ppylist)->s = ys;
  213. pylistNew->pnext = *ppylist;
  214. *ppylist = pylistNew;
  215. ppylist = &((*ppylist)->pnext);
  216. }
  217. }
  218. pylistNew = YLISTAlloc(buffers);
  219. if (pylistNew == NULL) {
  220. goto OutOfMemory;
  221. }
  222. pylistNew->s = ys;
  223. pylistNew->e = ye;
  224. if (!YLISTAddSpan(buffers, pylistNew, xs, xe)) {
  225. goto OutOfMemory;
  226. }
  227. pylistNew->pnext = *ppylist;
  228. *ppylist = pylistNew;
  229. }
  230. /****************************************************************************/
  231. #ifdef LATER
  232. // these functions are not required in the server implementation
  233. #define MAXRECTS 1024
  234. HRGN RECTLISTCreateRegion(
  235. PRECTLIST prl)
  236. {
  237. __GLGENbuffers *buffers = (__GLGENbuffers *)(prl->buffers);
  238. PYLIST pylist = prl->pylist;
  239. int irect = 0;
  240. PRGNDATA prgndata;
  241. PRECT prc;
  242. HRGN hrgn;
  243. prgndata = (PRGNDATA)ALLOC(sizeof(RGNDATAHEADER) + MAXRECTS * sizeof(RECT));
  244. if (prgndata == NULL) return NULL;
  245. prc = (PRECT)(prgndata->Buffer);
  246. while (pylist != NULL) {
  247. PXLIST pxlist = pylist->pxlist;
  248. while (pxlist != NULL) {
  249. prc->left = pxlist->s;
  250. prc->right = pxlist->e;
  251. prc->top = pylist->s;
  252. prc->bottom = pylist->e;
  253. prc++;
  254. irect++;
  255. if (irect == MAXRECTS) {
  256. //Error("maxrect");
  257. goto done;
  258. }
  259. pxlist = pxlist->pnext;
  260. }
  261. pylist = pylist->pnext;
  262. }
  263. done:
  264. prgndata->rdh.dwSize = sizeof(RGNDATAHEADER);
  265. prgndata->rdh.iType = RDH_RECTANGLES;
  266. prgndata->rdh.nCount = irect;
  267. prgndata->rdh.nRgnSize = 0;
  268. prgndata->rdh.rcBound.left = 0;
  269. prgndata->rdh.rcBound.right = 4096;
  270. prgndata->rdh.rcBound.top = 0;
  271. prgndata->rdh.rcBound.bottom = 4096;
  272. hrgn = GreExtCreateRegion(NULL, irect * sizeof(RECT) + sizeof(RGNDATAHEADER), prgndata);
  273. #ifdef LATER
  274. if (hrgn == NULL) {
  275. Error1("ExtCreateRegion() Error %d\n", GetLastError());
  276. Error1("%d rects\n", irect);
  277. prc = (PRECT)(prgndata->Buffer);
  278. for (;irect>0; irect--) {
  279. //printf("(%5d, %5d, %5d, %5d)\n", prc->left, prc->right, prc->top, prc->bottom);
  280. prc++;
  281. }
  282. }
  283. #endif
  284. FREE(prgndata);
  285. return hrgn;
  286. }
  287. /****************************************************************************/
  288. //
  289. // !!! make this do everything in one pass
  290. //
  291. void RECTLISTOr(
  292. PRECTLIST prl1,
  293. PRECTLIST prl2)
  294. {
  295. __GLGENbuffers *buffers = (__GLGENbuffers *)(prl1->buffers);
  296. PYLIST pylist = prl2->pylist;
  297. while (pylist != NULL) {
  298. PXLIST pxlist = pylist->pxlist;
  299. while (pxlist != NULL) {
  300. RECTLISTAddRect(prl1, pxlist->s, pylist->s, pxlist->e, pylist->e);
  301. pxlist = pxlist->pnext;
  302. }
  303. pylist = pylist->pnext;
  304. }
  305. }
  306. /****************************************************************************/
  307. void RECTLISTOrAndClear(
  308. PRECTLIST prl1,
  309. PRECTLIST prl2)
  310. {
  311. __GLGENbuffers *buffers = (__GLGENbuffers *)(prl1->buffers);
  312. if (RECTLISTIsMax(prl2)) {
  313. RECTLISTSetMax(prl1);
  314. RECTLISTSetEmpty(prl2);
  315. } else {
  316. if (RECTLISTIsEmpty(prl1)) {
  317. //
  318. // If the clear region is empty just swap them
  319. //
  320. RECTLISTSwap(prl1, prl2);
  321. } else {
  322. //
  323. // The clear region isn't empty so maximize it.
  324. //
  325. RECTLISTSetMax(prl1);
  326. RECTLISTSetEmpty(prl2);
  327. }
  328. }
  329. }
  330. /****************************************************************************/
  331. void RECTLISTSwap(
  332. PRECTLIST prl1,
  333. PRECTLIST prl2)
  334. {
  335. __GLGENbuffers *buffers = (__GLGENbuffers *)(prl1->buffers);
  336. RECTLIST rlTemp = *prl1;
  337. *prl1 = *prl2;
  338. *prl2 = rlTemp;
  339. }
  340. #endif
  341. /****************************************************************************/
  342. void RECTLISTSetEmpty(
  343. PRECTLIST prl)
  344. {
  345. __GLGENbuffers *buffers = (__GLGENbuffers *)(prl->buffers);
  346. PYLIST pylist = prl->pylist;
  347. PYLIST pylistKill;
  348. while (pylist != NULL) {
  349. pylistKill = pylist;
  350. pylist = pylist->pnext;
  351. YLISTFree(buffers, pylistKill);
  352. }
  353. prl->pylist = NULL;
  354. }
  355. /****************************************************************************/
  356. BOOL RECTLISTIsEmpty(
  357. PRECTLIST prl)
  358. {
  359. return (prl->pylist == NULL);
  360. }