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 struct TagItem
*tag
, *tstate
= tagList
;
102 while((tag
= NextTagItem(&tstate
)))
107 priority
= tag
->ti_Data
;
111 hook
= (struct Hook
*)tag
->ti_Data
;
115 superbitmap
= (struct BitMap
*)tag
->ti_Data
;
119 parent
= (struct Layer
*)tag
->ti_Data
;
125 infrontof
= (struct Layer
*)tag
->ti_Data
;
131 behind
= (struct Layer
*)tag
->ti_Data
;
135 visible
= tag
->ti_Data
;
139 layershape
= (struct Region
*)tag
->ti_Data
;
143 shapehook
= (struct Hook
*)tag
->ti_Data
;
148 } /* while((tag = NextTagItem(&tstate))) */
150 if ((flags
& LAYERSUPER
) && (NULL
== superbitmap
))
155 parent
= li
->check_lp
;
158 /* Root layer not yet installed */
160 if (!(flags
& LAYER_ROOT_LAYER
)) /* avoid endless recursion */
162 struct TagItem tags
[] =
164 {LA_Visible
, FALSE
},
165 {LA_Priority
, ROOTPRIORITY
},
169 if (!(CreateLayerTagList(li
,
173 GetBitMapAttr(bm
, BMA_WIDTH
) - 1,
174 GetBitMapAttr(bm
, BMA_HEIGHT
) - 1,
182 parent
= li
->check_lp
;
188 * User gives coordinates reltive to parent.
189 * Adjust the shape to the absolute coordinates
190 * If this is the root layer, I don't have to
191 * do anything. I recognize the root layer if there
195 if (infrontof
&& infrontof
->priority
> priority
)
198 if (behind
&& behind
->priority
< priority
)
201 /* First create the shape region relative to nothing, that is 0,0 origin */
203 shape
= NewRectRegion(0, 0, x1
- x0
, y1
- y0
);
209 struct ShapeHookMsg msg
;
211 msg
.Action
= SHAPEHOOKACTION_CREATELAYER
;
213 msg
.ActualShape
= layershape
;
214 msg
.NewBounds
.MinX
= x0
;
215 msg
.NewBounds
.MinY
= y0
;
216 msg
.NewBounds
.MaxX
= x1
;
217 msg
.NewBounds
.MaxY
= y1
;
218 msg
.OldBounds
.MinX
= 0;
219 msg
.OldBounds
.MinY
= 0;
220 msg
.OldBounds
.MaxX
= 0;
221 msg
.OldBounds
.MaxY
= 0;
223 layershape
= (struct Region
*)CallHookPkt(shapehook
, NULL
, &msg
);
226 if (layershape
) if (!AndRegionRegion(layershape
, shape
))
228 DisposeRegion(shape
);
234 /* Convert from parent layer relative coords to screen relative coords */
236 x0
+= parent
->bounds
.MinX
;
237 y0
+= parent
->bounds
.MinY
;
238 x1
+= parent
->bounds
.MinX
;
239 y1
+= parent
->bounds
.MinY
;
242 /* Make shape region relative to screen */
243 _TranslateRect(&shape
->bounds
, x0
, y0
);
245 l
= AllocMem(sizeof(struct IntLayer
), MEMF_CLEAR
|MEMF_PUBLIC
);
246 rp
= CreateRastPort();
252 IL(l
)->shapehook
= shapehook
;
253 l
->shaperegion
= layershape
;
264 l
->Flags
= (WORD
) flags
;
266 l
->Width
= x1
- x0
+ 1;
267 l
->Height
= y1
- y0
+ 1;
269 l
->SuperBitMap
= superbitmap
;
271 l
->priority
= priority
;
273 InitSemaphore(&l
->Lock
);
276 if (NULL
== (l
->DamageList
= NewRegion()))
278 if (NULL
== (l
->VisibleRegion
= NewRegion()))
280 if (NULL
== (l
->visibleshape
= NewRegion()))
283 l
->visible
= visible
;
285 if (NULL
== li
->check_lp
)
291 l
->nesting
= parent
->nesting
+1;
299 * If neither a layer in front or behind is
300 * given the search for the place according to
301 * the priority and insert it there. I
302 * determine behind or infrontof here!
304 if (NULL
!= li
->top_layer
)
306 if (!infrontof
&& !behind
)
309 struct Layer
* lastgood
;
314 lastgood
= infrontof
;
315 infrontof
= infrontof
->front
;
316 if (NULL
== infrontof
)
318 infrontof
= lastgood
;
321 if (infrontof
->parent
!= l
->parent
)
323 infrontof
= lastgood
;
326 while (infrontof
->nesting
>= l
->nesting
)
328 lastgood
= infrontof
;
329 infrontof
= infrontof
->front
;
330 if (NULL
== infrontof
||
331 infrontof
->priority
> l
->priority
)
333 infrontof
= lastgood
;
341 while (FALSE
== end
);
346 if (infrontof
|| (NULL
== behind
))
348 if (NULL
== infrontof
)
349 infrontof
= li
->top_layer
;
351 if (li
->top_layer
== infrontof
)
356 if (NULL
!= infrontof
)
357 infrontof
->front
= l
;
361 l
->front
= infrontof
->front
;
363 infrontof
->front
->back
= l
;
364 infrontof
->front
= l
;
370 l
->back
= behind
->back
;
378 SetRegion(l
->shape
, l
->visibleshape
);
380 AndRegionRegion(l
->parent
->shape
, l
->visibleshape
);
386 * layer is to be visible
388 struct Layer
* _l
= l
->back
;
389 struct Layer
* lparent
= l
->parent
;
392 * Does this layer have a layer in front of it?
393 * If yes, then take that layer's VisibleRegion and
394 * cut out that layer's shape. This is then the
395 * VisibleRegion of my layer.
399 SetRegion(l
->front
->VisibleRegion
, l
->VisibleRegion
);
400 ClearRegionRegion(l
->front
->visibleshape
, l
->VisibleRegion
);
403 SetRegion(li
->check_lp
->shape
, l
->VisibleRegion
);
407 * First tell all layers behind this layer to
408 * back up their parts that the new layer will
413 if (IS_VISIBLE(_l
) && DO_OVERLAP(&l
->shape
->bounds
, &_l
->shape
->bounds
))
414 _BackupPartsOfLayer(_l
, l
->visibleshape
, 0, FALSE
, LayersBase
);
416 ClearRegionRegion(l
->visibleshape
, _l
->VisibleRegion
);
420 if (IS_VISIBLE(_l
) || (NULL
== lparent
->parent
))
423 lparent
= lparent
->parent
;
430 * Show the layer according to its visible area
431 * This function creates the cliprects in the area
433 * This also works for invisible layers since their Visible
434 * Region is non existent.
436 if (!IS_ROOTLAYER(l
))
437 _ShowLayer(l
, LayersBase
);
449 if (l
->VisibleRegion
)
450 DisposeRegion(l
->VisibleRegion
);
452 DisposeRegion(l
->DamageList
);
454 DisposeRegion(l
->visibleshape
);
455 FreeMem(l
, sizeof(struct IntLayer
));
464 } /* CreateBehindHookLayer */