Exec locks provides means to protect exec's lists from beeing accessed. The lock...
[AROS.git] / rom / hyperlayers / collectpixelslayer.c
blob29b192593c382e530fb8d2f6633cade298805c18
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 #include <aros/libcall.h>
10 #include <utility/hooks.h>
11 #include <proto/alib.h>
12 #include <proto/exec.h>
13 #include <proto/graphics.h>
14 #include <proto/utility.h>
16 #include "layers_intern.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))
131 struct CollectPixelsLayerMsg cplm;
133 cplm.xSrc = intersect.MinX;
134 cplm.ySrc = intersect.MinY;
135 cplm.width = intersect.MaxX - intersect.MinX + 1;
136 cplm.height = intersect.MaxY - intersect.MinY + 1;
137 cplm.xDest = intersect.MinX;
138 cplm.yDest = intersect.MinY;
139 cplm.bm = l->rp->BitMap;
140 cplm.layer = l;
141 cplm.minterm = 0x0;
142 D(bug("SimpleRefresh: Calling callback now! bm=%p\n",cplm.bm));
143 CallHookPkt(callback,l,&cplm);
144 D(bug("Returned from callback!\n"));
147 cr = cr->Next;
150 _rr = _rr->Next;
152 } else
153 if (IS_SMARTREFRESH(l)) {
154 struct RegionRectangle * _rr = _r->RegionRectangle;
155 D(bug("SMARTREFRESH layer found!\n"));
156 while (NULL != _rr) {
157 struct Rectangle _rect;
158 struct ClipRect * cr;
160 _rect = _rr->bounds;
161 _rect.MinX += _r->bounds.MinX;
162 _rect.MinY += _r->bounds.MinY;
163 _rect.MaxX += _r->bounds.MinX;
164 _rect.MaxY += _r->bounds.MinY;
165 //Following does not work for some reason!
166 //_TranslateRect(&_rect,_r->bounds.MinX,_r->bounds.MinY);
168 * Compare this rr against all hidden cliprects...
170 cr = l->ClipRect;
171 while (NULL != cr) {
172 struct Rectangle intersect;
174 * Check for overlap with _rect
175 * Call callback with overlapping area!
177 if (AndRectRect(&_rect,&cr->bounds,&intersect)) {
178 struct CollectPixelsLayerMsg cplm;
179 D(bug("Overlapping: %d/%d-%d/%d\n",
180 intersect.MinX,
181 intersect.MinY,
182 intersect.MaxX,
183 intersect.MaxY));
184 D(bug("CR: %d/%d-%d/%d\n",
185 cr->bounds.MinX,
186 cr->bounds.MinY,
187 cr->bounds.MaxX,
188 cr->bounds.MaxY));
189 D(bug("Rect: %d/%d-%d/%d\n",
190 _rect.MinX,
191 _rect.MinY,
192 _rect.MaxX,
193 _rect.MaxY));
194 D(bug("Visible: %s\n",
195 (NULL == cr->lobs) ? "TRUE"
196 : "FALSE" ));
198 if (NULL == cr->lobs) {
200 * Take data from sceen's bitmap
202 cplm.xSrc = intersect.MinX;
203 cplm.ySrc = intersect.MinY;
204 cplm.width = intersect.MaxX - intersect.MinX + 1;
205 cplm.height= intersect.MaxY - intersect.MinY + 1;
206 cplm.xDest = intersect.MinX;
207 cplm.yDest = intersect.MinY;
208 cplm.bm = l->rp->BitMap;
209 } else {
210 cplm.xSrc = intersect.MinX - cr->bounds.MinX + ALIGN_OFFSET(intersect.MinX);
211 cplm.ySrc = intersect.MinY - cr->bounds.MinY;
212 cplm.width = intersect.MaxX - intersect.MinX + 1;
213 cplm.height= intersect.MaxY - intersect.MinY + 1;
214 cplm.xDest = intersect.MinX;
215 cplm.yDest = intersect.MinY;
216 cplm.bm = cr->BitMap;
218 cplm.layer = l;
219 cplm.minterm = 0x0c0;
220 D(bug("SmartRefresh: Calling callback now! bm=%p\n",cplm.bm));
221 CallHookPkt(callback,l,&cplm);
224 cr = cr->Next;
226 _rr = _rr->Next;
228 } else
229 if (IS_SUPERREFRESH(l)) {
232 * Region _r was treated. No need to look at it somewhere else.
233 * Could call this function again, but better in a loop...
235 ClearRegionRegion(_r,r);
236 DisposeRegion(_r);
237 if (IS_EMPTYREGION(r)) {
238 D(bug("Got empty region now!\n"));
240 } else {
242 * Jump to the parent layer.
244 /* FIXME: Potential deadlock! */
245 if (l->parent) {
246 LockLayer(0,l->parent);
248 UnlockLayer(l);
249 l = l->parent;
252 /* FIXME: Potential deadlock! */
253 if (l->back) {
254 LockLayer(0,l->back);
256 UnlockLayer(l);
257 l = l->back;
259 if (l)
260 UnlockLayer(l);
262 if (!IS_EMPTYREGION(r)) {
263 struct RegionRectangle * _rr = r->RegionRectangle;
264 while (NULL != _rr) {
265 struct CollectPixelsLayerMsg cplm;
266 struct Rectangle _rect = _rr->bounds;
267 _rect.MinX += r->bounds.MinX;
268 _rect.MinY += r->bounds.MinY;
269 _rect.MaxX += r->bounds.MinX;
270 _rect.MaxY += r->bounds.MinY;
271 D(bug("Rect: %d/%d-%d/%d\n",
272 _rect.MinX,
273 _rect.MinY,
274 _rect.MaxX,
275 _rect.MaxY));
276 D(bug("Directly from screen background!\n"));
277 _rr = _rr->Next;
279 cplm.xSrc = _rect.MinX;
280 cplm.xSrc = _rect.MinY;
281 cplm.width = _rect.MaxX - _rect.MinX + 1;
282 cplm.height= _rect.MaxY - _rect.MinY + 1;
283 cplm.xDest = _rect.MinX;
284 cplm.yDest = _rect.MaxY;
285 cplm.bm = NULL;
286 cplm.layer = NULL;
287 D(bug("Calling callback now!\n"));
288 CallHookPkt(callback,NULL,&cplm);
291 } else {
292 D(bug("Complete region handled! - Nothing to take from screen!\n"));
294 UnlockLayers(l->LayerInfo);
296 AROS_LIBFUNC_EXIT