2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
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"
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
)) {
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
;
140 D(bug("SimpleRefresh: Calling callback now! bm=%p\n",cplm
.bm
));
141 CallHookPkt(callback
,l
,&cplm
);
142 D(bug("Returned from callback!\n"));
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
;
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...
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",
182 D(bug("CR: %d/%d-%d/%d\n",
187 D(bug("Rect: %d/%d-%d/%d\n",
192 D(bug("Visible: %s\n",
193 (NULL
== cr
->lobs
) ? "TRUE"
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
;
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
;
217 cplm
.minterm
= 0x0c0;
218 D(bug("SmartRefresh: Calling callback now! bm=%p\n",cplm
.bm
));
219 CallHookPkt(callback
,l
,&cplm
);
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
);
235 if (IS_EMPTYREGION(r
)) {
236 D(bug("Got empty region now!\n"));
240 * Jump to the parent layer.
242 #warning Potential deadlock!
244 LockLayer(0,l
->parent
);
250 #warning Potential deadlock!
252 LockLayer(0,l
->back
);
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",
274 D(bug("Directly from screen background!\n"));
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
;
285 D(bug("Calling callback now!\n"));
286 CallHookPkt(callback
,NULL
,&cplm
);
290 D(bug("Complete region handled! - Nothing to take from screen!\n"));
292 UnlockLayers(l
->LayerInfo
);