2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
6 #include <aros/libcall.h>
7 #include <graphics/clip.h>
8 #include <graphics/layers.h>
9 #include <intuition/extensions.h>
10 #include <utility/tagitem.h>
11 #include <proto/exec.h>
12 #include <proto/utility.h>
13 #include <proto/graphics.h>
14 #include <proto/layers.h>
16 #include "basicfuncs.h"
17 #include "layers_intern.h"
20 * LA_InFrontOf and LA_Behind are intentionally left
21 * because they allow to implement AmigaOS4-compatible functionality.
23 struct Layer
*CreateLayerTagList(struct Layer_Info
*li
, struct BitMap
*bm
, LONG x0
, LONG y0
,
24 LONG x1
, LONG y1
, LONG flags
, int priority
, struct TagItem
*tagList
,
25 struct LayersBase
*LayersBase
)
27 struct BitMap
* superbitmap
= NULL
;
28 struct Hook
* hook
= NULL
, *shapehook
= NULL
;
31 struct Layer
* behind
= NULL
, * infrontof
= NULL
, * parent
= NULL
;
33 struct Region
* layershape
= NULL
, *shape
;
34 struct TagItem
*tag
, *tstate
= tagList
;
36 while((tag
= NextTagItem(&tstate
)))
41 hook
= (struct Hook
*)tag
->ti_Data
;
45 superbitmap
= (struct BitMap
*)tag
->ti_Data
;
49 parent
= (struct Layer
*)tag
->ti_Data
;
53 infrontof
= (struct Layer
*)tag
->ti_Data
;
57 behind
= (struct Layer
*)tag
->ti_Data
;
61 visible
= !tag
->ti_Data
;
65 layershape
= (struct Region
*)tag
->ti_Data
;
69 shapehook
= (struct Hook
*)tag
->ti_Data
;
73 win
= (APTR
)tag
->ti_Data
;
78 } /* while((tag = NextTagItem(&tstate))) */
80 if ((flags
& LAYERSUPER
) && (NULL
== superbitmap
))
85 parent
= li
->check_lp
;
88 /* Root layer not yet installed */
90 if (priority
!= ROOTPRIORITY
) /* avoid endless recursion */
92 struct TagItem tags
[] =
98 if (!(CreateLayerTagList(li
,
102 GetBitMapAttr(bm
, BMA_WIDTH
) - 1,
103 GetBitMapAttr(bm
, BMA_HEIGHT
) - 1,
113 parent
= li
->check_lp
;
119 * User gives coordinates reltive to parent.
120 * Adjust the shape to the absolute coordinates
121 * If this is the root layer, I don't have to
122 * do anything. I recognize the root layer if there
126 if (infrontof
&& infrontof
->priority
> priority
)
129 if (behind
&& behind
->priority
< priority
)
132 /* First create the shape region relative to nothing, that is 0,0 origin */
134 shape
= NewRectRegion(0, 0, x1
- x0
, y1
- y0
);
140 struct ShapeHookMsg msg
;
141 struct Rectangle NewBounds
, OldBounds
;
143 msg
.NewShape
= layershape
;
144 msg
.OldShape
= layershape
;
145 msg
.NewBounds
= &NewBounds
;
146 msg
.OldBounds
= &OldBounds
;
157 if (CallHookPkt(shapehook
, NULL
, &msg
))
158 layershape
= msg
.NewShape
;
161 if (layershape
) if (!AndRegionRegion(layershape
, shape
))
163 DisposeRegion(shape
);
169 /* Convert from parent layer relative coords to screen relative coords */
171 x0
+= parent
->bounds
.MinX
;
172 y0
+= parent
->bounds
.MinY
;
173 x1
+= parent
->bounds
.MinX
;
174 y1
+= parent
->bounds
.MinY
;
177 /* Make shape region relative to screen */
178 _TranslateRect(&shape
->bounds
, x0
, y0
);
180 l
= AllocMem(sizeof(struct IntLayer
), MEMF_CLEAR
|MEMF_PUBLIC
);
183 IL(l
)->shapehook
= shapehook
;
185 l
->shaperegion
= layershape
;
192 l
->Flags
= (WORD
) flags
;
195 l
->SuperBitMap
= superbitmap
;
197 l
->priority
= priority
;
199 InitSemaphore(&l
->Lock
);
206 l
->Width
= x1
- x0
+ 1;
207 l
->Height
= y1
- y0
+ 1;
211 if (NULL
== (l
->DamageList
= NewRegion()))
213 if (NULL
== (l
->VisibleRegion
= NewRegion()))
215 if (NULL
== (l
->visibleshape
= NewRegion()))
218 l
->visible
= visible
;
220 if (NULL
== li
->check_lp
)
226 l
->nesting
= parent
->nesting
+1;
234 * If neither a layer in front or behind is
235 * given the search for the place according to
236 * the priority and insert it there. I
237 * determine behind or infrontof here!
239 if (NULL
!= li
->top_layer
)
241 if (!infrontof
&& !behind
)
244 struct Layer
* lastgood
;
249 lastgood
= infrontof
;
250 infrontof
= infrontof
->front
;
251 if (NULL
== infrontof
)
253 infrontof
= lastgood
;
256 if (infrontof
->parent
!= l
->parent
)
258 infrontof
= lastgood
;
261 while (infrontof
->nesting
>= l
->nesting
)
263 lastgood
= infrontof
;
264 infrontof
= infrontof
->front
;
265 if (NULL
== infrontof
||
266 infrontof
->priority
> l
->priority
)
268 infrontof
= lastgood
;
276 while (FALSE
== end
);
281 if (infrontof
|| (NULL
== behind
))
283 if (NULL
== infrontof
)
284 infrontof
= li
->top_layer
;
286 if (li
->top_layer
== infrontof
)
291 if (NULL
!= infrontof
)
292 infrontof
->front
= l
;
296 l
->front
= infrontof
->front
;
298 infrontof
->front
->back
= l
;
299 infrontof
->front
= l
;
305 l
->back
= behind
->back
;
313 SetRegion(l
->shape
, l
->visibleshape
);
315 AndRegionRegion(l
->parent
->shape
, l
->visibleshape
);
321 * layer is to be visible
323 struct Layer
* _l
= l
->back
;
324 struct Layer
* lparent
= l
->parent
;
327 * Does this layer have a layer in front of it?
328 * If yes, then take that layer's VisibleRegion and
329 * cut out that layer's shape. This is then the
330 * VisibleRegion of my layer.
334 SetRegion(l
->front
->VisibleRegion
, l
->VisibleRegion
);
335 ClearRegionRegion(l
->front
->visibleshape
, l
->VisibleRegion
);
338 SetRegion(li
->check_lp
->shape
, l
->VisibleRegion
);
342 * First tell all layers behind this layer to
343 * back up their parts that the new layer will
348 if (IS_VISIBLE(_l
) && DO_OVERLAP(&l
->shape
->bounds
, &_l
->shape
->bounds
))
349 _BackupPartsOfLayer(_l
, l
->visibleshape
, 0, FALSE
, LayersBase
);
351 ClearRegionRegion(l
->visibleshape
, _l
->VisibleRegion
);
355 if (IS_VISIBLE(_l
) || (NULL
== lparent
->parent
))
358 lparent
= lparent
->parent
;
365 * Show the layer according to its visible area
366 * This function creates the cliprects in the area
368 * This also works for invisible layers since their Visible
369 * Region is non existent.
371 if (!IS_ROOTLAYER(l
))
372 _ShowLayer(l
, LayersBase
);
384 if (l
->VisibleRegion
)
385 DisposeRegion(l
->VisibleRegion
);
387 DisposeRegion(l
->DamageList
);
389 DisposeRegion(l
->visibleshape
);
390 FreeMem(l
, sizeof(struct IntLayer
));
394 } /* CreateBehindHookLayer */