Updated PCI IDs to latest snapshot.
[tangerine.git] / rom / hyperlayers / collectpixelslayer.c
blob175037bfe435ee91f0e3e50f03ee5fe73b20ec53
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
8 #include <proto/exec.h>
9 #include <exec/types.h>
10 #include "layers_intern.h"
11 #include <aros/libcall.h>
12 #include <proto/graphics.h>
13 #include <proto/utility.h>
14 #include <utility/hooks.h>
16 #include "../graphics/intregions.h"
17 #include "basicfuncs.h"
19 #define DEBUG 1
20 #include <aros/debug.h>
22 #define MAX(a,b) ((a) > (b) ? (a) : (b))
23 #define MIN(a,b) ((a) < (b) ? (a) : (b))
25 struct CollectPixelsMsg
27 struct Rectangle * rect;
30 /*****************************************************************************
32 NAME */
33 #include <proto/layers.h>
34 AROS_LH3(void, CollectPixelsLayer,
36 /* SYNOPSIS */
37 AROS_LHA(struct Layer *, l , A0),
38 AROS_LHA(struct Region *, r , A1),
39 AROS_LHA(struct Hook *, callback , A2),
41 /* LOCATION */
42 struct LayersBase *, LayersBase, 45, Layers)
44 /* FUNCTION
45 This function collects all the pixel within region r
46 and calls the provided callback hook for all areas
47 that were found. You can do with the pixels whatever
48 you want...
50 INPUTS
51 l - pointer to layer where to start out
52 r - region where to look for hidden or
53 visible pixels
54 callback - the callback will be invoked for the
55 found pixels along with information
56 about the size of the area that may
57 be copied.
60 RESULT
62 NOTES
64 EXAMPLE
66 BUGS
68 SEE ALSO
70 INTERNALS
72 HISTORY
74 *****************************************************************************/
76 AROS_LIBFUNC_INIT
78 LockLayers(l->LayerInfo);
79 LockLayer(0,l);
80 D(bug("%s: layer=%p,region=%p\n",
81 __FUNCTION__,
83 r));
84 while (NULL != l && !IS_ROOTLAYER(l) && FALSE == IS_EMPTYREGION(r)) {
85 if (IS_VISIBLE(l)) {
87 * For every layer check whether its parent is
88 * overlapping with the area of r at all. If it
89 * does not, can immediately jump to the layer
90 * behind the parent.
92 if (DO_OVERLAP(&l->parent->shape->bounds,&r->bounds)) {
94 * Find out what both layers have in common.
96 struct Region * _r;
97 D(bug("l->shape=%p\n",l->shape));
98 _r = AndRegionRegionND(r,l->shape);
100 * Try to find the relevant parts in the
101 * layer l and on those parts of the
102 * bitmap that are relevant to call the callback hook
104 if (IS_SIMPLEREFRESH(l)) {
105 struct RegionRectangle * _rr;
106 D(bug("SIMPLEFRESH layer found! %d/%d - %d/%d\n",
107 l->bounds.MinX,
108 l->bounds.MinY,
109 l->bounds.MaxX,
110 l->bounds.MaxY));
111 _rr = _r->RegionRectangle;
112 while (NULL != _rr) {
113 struct Rectangle _rect;
114 struct ClipRect * cr = l->ClipRect;
116 _rect = _rr->bounds;
117 _rect.MinX += _r->bounds.MinX;
118 _rect.MinY += _r->bounds.MinY;
119 _rect.MaxX += _r->bounds.MinX;
120 _rect.MaxY += _r->bounds.MinY;
122 cr = l->ClipRect;
123 while (NULL != cr) {
124 struct Rectangle intersect;
126 * Check for overlap with _rect
127 * Call callback with overlapping area!
129 if (_AndRectRect(&_rect,&cr->bounds,&intersect)) {
130 struct CollectPixelsLayerMsg cplm;
131 cplm.xSrc = intersect.MinX;
132 cplm.ySrc = intersect.MinY;
133 cplm.width = intersect.MaxX - intersect.MinX + 1;
134 cplm.height = intersect.MaxY - intersect.MinY + 1;
135 cplm.xDest = intersect.MinX;
136 cplm.yDest = intersect.MinY;
137 cplm.bm = l->rp->BitMap;
138 cplm.layer = l;
139 cplm.minterm = 0x0;
140 D(bug("SimpleRefresh: Calling callback now! bm=%p\n",cplm.bm));
141 CallHookPkt(callback,l,&cplm);
142 D(bug("Returned from callback!\n"));
145 cr = cr->Next;
148 _rr = _rr->Next;
150 } else
151 if (IS_SMARTREFRESH(l)) {
152 struct RegionRectangle * _rr = _r->RegionRectangle;
153 D(bug("SMARTREFRESH layer found!\n"));
154 while (NULL != _rr) {
155 struct Rectangle _rect;
156 struct ClipRect * cr;
158 _rect = _rr->bounds;
159 _rect.MinX += _r->bounds.MinX;
160 _rect.MinY += _r->bounds.MinY;
161 _rect.MaxX += _r->bounds.MinX;
162 _rect.MaxY += _r->bounds.MinY;
163 //Following does not work for some reason!
164 //_TranslateRect(&_rect,_r->bounds.MinX,_r->bounds.MinY);
166 * Compare this rr against all hidden cliprects...
168 cr = l->ClipRect;
169 while (NULL != cr) {
170 struct Rectangle intersect;
172 * Check for overlap with _rect
173 * Call callback with overlapping area!
175 if (_AndRectRect(&_rect,&cr->bounds,&intersect)) {
176 struct CollectPixelsLayerMsg cplm;
177 D(bug("Overlapping: %d/%d-%d/%d\n",
178 intersect.MinX,
179 intersect.MinY,
180 intersect.MaxX,
181 intersect.MaxY));
182 D(bug("CR: %d/%d-%d/%d\n",
183 cr->bounds.MinX,
184 cr->bounds.MinY,
185 cr->bounds.MaxX,
186 cr->bounds.MaxY));
187 D(bug("Rect: %d/%d-%d/%d\n",
188 _rect.MinX,
189 _rect.MinY,
190 _rect.MaxX,
191 _rect.MaxY));
192 D(bug("Visible: %s\n",
193 (NULL == cr->lobs) ? "TRUE"
194 : "FALSE" ));
196 if (NULL == cr->lobs) {
198 * Take data from sceen's bitmap
200 cplm.xSrc = intersect.MinX;
201 cplm.ySrc = intersect.MinY;
202 cplm.width = intersect.MaxX - intersect.MinX + 1;
203 cplm.height= intersect.MaxY - intersect.MinY + 1;
204 cplm.xDest = intersect.MinX;
205 cplm.yDest = intersect.MinY;
206 cplm.bm = l->rp->BitMap;
207 } else {
208 cplm.xSrc = intersect.MinX - cr->bounds.MinX + ALIGN_OFFSET(intersect.MinX);
209 cplm.ySrc = intersect.MinY - cr->bounds.MinY;
210 cplm.width = intersect.MaxX - intersect.MinX + 1;
211 cplm.height= intersect.MaxY - intersect.MinY + 1;
212 cplm.xDest = intersect.MinX;
213 cplm.yDest = intersect.MinY;
214 cplm.bm = cr->BitMap;
216 cplm.layer = l;
217 cplm.minterm = 0x0c0;
218 D(bug("SmartRefresh: Calling callback now! bm=%p\n",cplm.bm));
219 CallHookPkt(callback,l,&cplm);
222 cr = cr->Next;
224 _rr = _rr->Next;
226 } else
227 if (IS_SUPERREFRESH(l)) {
230 * Region _r was treated. No need to look at it somewhere else.
231 * Could call this function again, but better in a loop...
233 ClearRegionRegion(_r,r);
234 DisposeRegion(_r);
235 if (IS_EMPTYREGION(r)) {
236 D(bug("Got empty region now!\n"));
238 } else {
240 * Jump to the parent layer.
242 #warning Potential deadlock!
243 if (l->parent) {
244 LockLayer(0,l->parent);
246 UnlockLayer(l);
247 l = l->parent;
250 #warning Potential deadlock!
251 if (l->back) {
252 LockLayer(0,l->back);
254 UnlockLayer(l);
255 l = l->back;
257 if (l)
258 UnlockLayer(l);
260 if (!IS_EMPTYREGION(r)) {
261 struct RegionRectangle * _rr = r->RegionRectangle;
262 while (NULL != _rr) {
263 struct CollectPixelsLayerMsg cplm;
264 struct Rectangle _rect = _rr->bounds;
265 _rect.MinX += r->bounds.MinX;
266 _rect.MinY += r->bounds.MinY;
267 _rect.MaxX += r->bounds.MinX;
268 _rect.MaxY += r->bounds.MinY;
269 D(bug("Rect: %d/%d-%d/%d\n",
270 _rect.MinX,
271 _rect.MinY,
272 _rect.MaxX,
273 _rect.MaxY));
274 D(bug("Directly from screen background!\n"));
275 _rr = _rr->Next;
277 cplm.xSrc = _rect.MinX;
278 cplm.xSrc = _rect.MinY;
279 cplm.width = _rect.MaxX - _rect.MinX + 1;
280 cplm.height= _rect.MaxY - _rect.MinY + 1;
281 cplm.xDest = _rect.MinX;
282 cplm.yDest = _rect.MaxY;
283 cplm.bm = NULL;
284 cplm.layer = NULL;
285 D(bug("Calling callback now!\n"));
286 CallHookPkt(callback,NULL,&cplm);
289 } else {
290 D(bug("Complete region handled! - Nothing to take from screen!\n"));
292 UnlockLayers(l->LayerInfo);
294 AROS_LIBFUNC_EXIT