2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
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"
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 /*****************************************************************************
33 #include <proto/layers.h>
34 AROS_LH3(void, CollectPixelsLayer
,
37 AROS_LHA(struct Layer
*, l
, A0
),
38 AROS_LHA(struct Region
*, r
, A1
),
39 AROS_LHA(struct Hook
*, callback
, A2
),
42 struct LayersBase
*, LayersBase
, 45, Layers
)
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
51 l - pointer to layer where to start out
52 r - region where to look for hidden or
54 callback - the callback will be invoked for the
55 found pixels along with information
56 about the size of the area that may
74 *****************************************************************************/
78 LockLayers(l
->LayerInfo
);
80 D(bug("%s: layer=%p,region=%p\n",
84 while (NULL
!= l
&& !IS_ROOTLAYER(l
) && FALSE
== IS_EMPTYREGION(r
)) {
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
92 if (DO_OVERLAP(&l
->parent
->shape
->bounds
,&r
->bounds
)) {
94 * Find out what both layers have in common.
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",
111 _rr
= _r
->RegionRectangle
;
112 while (NULL
!= _rr
) {
113 struct Rectangle _rect
;
114 struct ClipRect
* cr
= l
->ClipRect
;
117 _rect
.MinX
+= _r
->bounds
.MinX
;
118 _rect
.MinY
+= _r
->bounds
.MinY
;
119 _rect
.MaxX
+= _r
->bounds
.MinX
;
120 _rect
.MaxY
+= _r
->bounds
.MinY
;
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
;
142 D(bug("SimpleRefresh: Calling callback now! bm=%p\n",cplm
.bm
));
143 CallHookPkt(callback
,l
,&cplm
);
144 D(bug("Returned from callback!\n"));
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
;
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...
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",
184 D(bug("CR: %d/%d-%d/%d\n",
189 D(bug("Rect: %d/%d-%d/%d\n",
194 D(bug("Visible: %s\n",
195 (NULL
== cr
->lobs
) ? "TRUE"
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
;
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
;
219 cplm
.minterm
= 0x0c0;
220 D(bug("SmartRefresh: Calling callback now! bm=%p\n",cplm
.bm
));
221 CallHookPkt(callback
,l
,&cplm
);
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
);
237 if (IS_EMPTYREGION(r
)) {
238 D(bug("Got empty region now!\n"));
242 * Jump to the parent layer.
244 /* FIXME: Potential deadlock! */
246 LockLayer(0,l
->parent
);
252 /* FIXME: Potential deadlock! */
254 LockLayer(0,l
->back
);
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",
276 D(bug("Directly from screen background!\n"));
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
;
287 D(bug("Calling callback now!\n"));
288 CallHookPkt(callback
,NULL
,&cplm
);
292 D(bug("Complete region handled! - Nothing to take from screen!\n"));
294 UnlockLayers(l
->LayerInfo
);