2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
6 #include <aros/libcall.h>
7 #include <graphics/clip.h>
8 #include <graphics/layers.h>
9 #include <utility/tagitem.h>
10 #include <proto/exec.h>
11 #include <proto/utility.h>
12 #include <proto/graphics.h>
13 #include "basicfuncs.h"
15 /*****************************************************************************
18 #include <proto/layers.h>
19 AROS_LH8(struct Layer
*, CreateLayerTagList
,
22 AROS_LHA(struct Layer_Info
*, li
, A0
),
23 AROS_LHA(struct BitMap
*, bm
, A1
),
24 AROS_LHA(LONG
, x0
, D0
),
25 AROS_LHA(LONG
, y0
, D1
),
26 AROS_LHA(LONG
, x1
, D2
),
27 AROS_LHA(LONG
, y1
, D3
),
28 AROS_LHA(LONG
, flags
, D4
),
29 AROS_LHA(struct TagItem
*, tagList
, A2
),
32 struct LayersBase
*, LayersBase
, 37, Layers
)
35 Create a new layer according to the tags given.
38 li - pointer to LayerInfo structure
39 bm - pointer to common bitmap
40 x0,y0 - upper left corner of the layer (in parent layer coords)
41 x1,y1 - lower right corner of the layer (in parent layer coords)
42 flags - choose the type of layer by setting some flags
43 If it is to be a super bitmap layer then the tag
44 LA_SUPERBITMAP must be provided along with a
45 pointer to a valid super bitmap.
46 tagList - a list of tags that specify the properties of the
47 layer. The following tags are currently supported:
48 LA_PRIORITY : priority class of the layer. The
49 higher the number the further the
50 layer will be in front of everything
52 Default value is UPFRONTPRIORITY.
53 LA_HOOK : Backfill hook
54 LA_SUPERBITMAP : pointer to a superbitmap. The flags
55 must also represent that this
56 layer is supposed to be a superbitmap
58 LA_CHILDOF : pointer to parent layer. If NULL then
59 this layer will be created as a old-style
61 LA_INFRONTOF : pointer to a layer in front of which
62 this layer is to be created.
63 LA_BEHIND : pointer to a layer behind which this layer
64 is to be created. Must not give both LA_INFRONTOF
66 LA_VISIBLE : FALSE if this layer is to be invisible.
68 LA_SHAPE : The region of the layer that comprises its shape.
69 This value is optional. The region must be relative to the layer.
73 Pointer to the newly created layer. NULL if layer could not be
74 created (Probably out of memory).
75 If the layer is created successful you must not free its shape.
76 The shape is automatically freed when the layer is deleted.
88 *****************************************************************************/
92 struct BitMap
* superbitmap
= NULL
;
93 struct Hook
* hook
= NULL
, *shapehook
= NULL
;
94 int priority
= UPFRONTPRIORITY
;
96 struct Layer
* behind
= NULL
, * infrontof
= NULL
, * parent
= NULL
;
99 struct Region
* layershape
= NULL
, *shape
;
100 const struct TagItem
*tstate
= tagList
;
103 while((tag
= NextTagItem(&tstate
)))
108 priority
= tag
->ti_Data
;
112 hook
= (struct Hook
*)tag
->ti_Data
;
116 superbitmap
= (struct BitMap
*)tag
->ti_Data
;
120 parent
= (struct Layer
*)tag
->ti_Data
;
126 infrontof
= (struct Layer
*)tag
->ti_Data
;
132 behind
= (struct Layer
*)tag
->ti_Data
;
136 visible
= tag
->ti_Data
;
140 layershape
= (struct Region
*)tag
->ti_Data
;
144 shapehook
= (struct Hook
*)tag
->ti_Data
;
149 } /* while((tag = NextTagItem(&tstate))) */
151 if ((flags
& LAYERSUPER
) && (NULL
== superbitmap
))
156 parent
= li
->check_lp
;
159 /* Root layer not yet installed */
161 if (!(flags
& LAYER_ROOT_LAYER
)) /* avoid endless recursion */
163 struct TagItem tags
[] =
165 {LA_Visible
, FALSE
},
166 {LA_Priority
, ROOTPRIORITY
},
170 if (!(CreateLayerTagList(li
,
174 GetBitMapAttr(bm
, BMA_WIDTH
) - 1,
175 GetBitMapAttr(bm
, BMA_HEIGHT
) - 1,
183 parent
= li
->check_lp
;
189 * User gives coordinates reltive to parent.
190 * Adjust the shape to the absolute coordinates
191 * If this is the root layer, I don't have to
192 * do anything. I recognize the root layer if there
196 if (infrontof
&& infrontof
->priority
> priority
)
199 if (behind
&& behind
->priority
< priority
)
202 /* First create the shape region relative to nothing, that is 0,0 origin */
204 shape
= NewRectRegion(0, 0, x1
- x0
, y1
- y0
);
210 struct ShapeHookMsg msg
;
212 msg
.Action
= SHAPEHOOKACTION_CREATELAYER
;
214 msg
.ActualShape
= layershape
;
215 msg
.NewBounds
.MinX
= x0
;
216 msg
.NewBounds
.MinY
= y0
;
217 msg
.NewBounds
.MaxX
= x1
;
218 msg
.NewBounds
.MaxY
= y1
;
219 msg
.OldBounds
.MinX
= 0;
220 msg
.OldBounds
.MinY
= 0;
221 msg
.OldBounds
.MaxX
= 0;
222 msg
.OldBounds
.MaxY
= 0;
224 layershape
= (struct Region
*)CallHookPkt(shapehook
, NULL
, &msg
);
227 if (layershape
) if (!AndRegionRegion(layershape
, shape
))
229 DisposeRegion(shape
);
235 /* Convert from parent layer relative coords to screen relative coords */
237 x0
+= parent
->bounds
.MinX
;
238 y0
+= parent
->bounds
.MinY
;
239 x1
+= parent
->bounds
.MinX
;
240 y1
+= parent
->bounds
.MinY
;
243 /* Make shape region relative to screen */
244 _TranslateRect(&shape
->bounds
, x0
, y0
);
246 l
= AllocMem(sizeof(struct IntLayer
), MEMF_CLEAR
|MEMF_PUBLIC
);
247 rp
= CreateRastPort();
253 IL(l
)->shapehook
= shapehook
;
254 l
->shaperegion
= layershape
;
265 l
->Flags
= (WORD
) flags
;
267 l
->Width
= x1
- x0
+ 1;
268 l
->Height
= y1
- y0
+ 1;
270 l
->SuperBitMap
= superbitmap
;
272 l
->priority
= priority
;
274 InitSemaphore(&l
->Lock
);
277 if (NULL
== (l
->DamageList
= NewRegion()))
279 if (NULL
== (l
->VisibleRegion
= NewRegion()))
281 if (NULL
== (l
->visibleshape
= NewRegion()))
284 l
->visible
= visible
;
286 if (NULL
== li
->check_lp
)
292 l
->nesting
= parent
->nesting
+1;
300 * If neither a layer in front or behind is
301 * given the search for the place according to
302 * the priority and insert it there. I
303 * determine behind or infrontof here!
305 if (NULL
!= li
->top_layer
)
307 if (!infrontof
&& !behind
)
310 struct Layer
* lastgood
;
315 lastgood
= infrontof
;
316 infrontof
= infrontof
->front
;
317 if (NULL
== infrontof
)
319 infrontof
= lastgood
;
322 if (infrontof
->parent
!= l
->parent
)
324 infrontof
= lastgood
;
327 while (infrontof
->nesting
>= l
->nesting
)
329 lastgood
= infrontof
;
330 infrontof
= infrontof
->front
;
331 if (NULL
== infrontof
||
332 infrontof
->priority
> l
->priority
)
334 infrontof
= lastgood
;
342 while (FALSE
== end
);
347 if (infrontof
|| (NULL
== behind
))
349 if (NULL
== infrontof
)
350 infrontof
= li
->top_layer
;
352 if (li
->top_layer
== infrontof
)
357 if (NULL
!= infrontof
)
358 infrontof
->front
= l
;
362 l
->front
= infrontof
->front
;
364 infrontof
->front
->back
= l
;
365 infrontof
->front
= l
;
371 l
->back
= behind
->back
;
379 SetRegion(l
->shape
, l
->visibleshape
);
381 AndRegionRegion(l
->parent
->shape
, l
->visibleshape
);
387 * layer is to be visible
389 struct Layer
* _l
= l
->back
;
390 struct Layer
* lparent
= l
->parent
;
393 * Does this layer have a layer in front of it?
394 * If yes, then take that layer's VisibleRegion and
395 * cut out that layer's shape. This is then the
396 * VisibleRegion of my layer.
400 SetRegion(l
->front
->VisibleRegion
, l
->VisibleRegion
);
401 ClearRegionRegion(l
->front
->visibleshape
, l
->VisibleRegion
);
404 SetRegion(li
->check_lp
->shape
, l
->VisibleRegion
);
408 * First tell all layers behind this layer to
409 * back up their parts that the new layer will
414 if (IS_VISIBLE(_l
) && DO_OVERLAP(&l
->shape
->bounds
, &_l
->shape
->bounds
))
415 _BackupPartsOfLayer(_l
, l
->visibleshape
, 0, FALSE
, LayersBase
);
417 ClearRegionRegion(l
->visibleshape
, _l
->VisibleRegion
);
421 if (IS_VISIBLE(_l
) || (NULL
== lparent
->parent
))
424 lparent
= lparent
->parent
;
431 * Show the layer according to its visible area
432 * This function creates the cliprects in the area
434 * This also works for invisible layers since their Visible
435 * Region is non existent.
437 if (!IS_ROOTLAYER(l
))
438 _ShowLayer(l
, LayersBase
);
450 if (l
->VisibleRegion
)
451 DisposeRegion(l
->VisibleRegion
);
453 DisposeRegion(l
->DamageList
);
455 DisposeRegion(l
->visibleshape
);
456 FreeMem(l
, sizeof(struct IntLayer
));
465 } /* CreateBehindHookLayer */