2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
9 #include <proto/exec.h>
10 #include <exec/memory.h>
11 #include <proto/graphics.h>
12 #include <proto/utility.h>
13 #include <utility/hooks.h>
15 #include "layers_intern.h"
16 #include "basicfuncs.h"
18 /*****************************************************************************
21 #include <proto/layers.h>
22 AROS_LH3(struct Region
*, ChangeLayerShape
,
25 AROS_LHA(struct Layer
*, l
, A0
),
26 AROS_LHA(struct Region
*, newshape
, A1
),
27 AROS_LHA(struct Hook
*, callback
, A2
),
29 struct LayersBase
*, LayersBase
, 37, Layers
)
32 Changes the shape of the layer on the fly.
33 When the shape of a layer is changed the current pixel content
34 is copied into its ClipRects so no information is lost.
35 The user can provide a callback hook that will be
36 called when the current layer's information is all backed up
37 in ClipRects. The signature of the callback should look as follows:
39 AROS_UFC3(BOOL, callback,
40 AROS_UFCA(struct Hook * , hook , A0),
41 AROS_UFCA(struct Layer * , l , A2),
42 AROS_UFCA(struct ShapeHookMsg * , arg , A1));
47 newshape - pointer to a region that comprises the new shape
48 of the layer. May be NULL if callback is provided.
49 callback - pointer to a callback hook. May be NULL if newshape
53 Pointer to the previously installed region.
67 *****************************************************************************/
71 struct Region
* returnshape
= NULL
;
73 LockLayers(l
->LayerInfo
);
76 struct Region r
, cutoldshape
, rtmp
, cutnewshape
;
77 struct Layer
* lparent
, * _l
, * lfirst
= NULL
;
81 InitRegion(&cutoldshape
);
82 InitRegion(&cutnewshape
);
88 * Backup everything that is visible right now into
91 lfirst
= GetFirstFamilyMember(l
);
92 SetRegion(lfirst
->VisibleRegion
, &r
);
94 SetRegion(l
->visibleshape
, &cutoldshape
);
95 _BackupPartsOfLayer(l
, &cutoldshape
, 0, TRUE
, LayersBase
);
99 * Get the current layer's shape as the paramter to return
100 * from this function.
102 returnshape
= l
->shaperegion
;
104 if (NULL
!= callback
)
106 struct ShapeHookMsg msg
;
108 msg
.Action
= SHAPEHOOKACTION_CHANGELAYERSHAPE
;
109 msg
.NewShape
= l
->shaperegion
;
110 msg
.OldShape
= l
->shaperegion
;
111 msg
.NewBounds
= &l
->bounds
;
112 msg
.OldBounds
= &l
->bounds
;
115 * call the callback to the user to give me a new shape
116 * The user can manipulate the cliprects of the layer
117 * l and can have a look at the current shape.
119 if (CallHookPkt(callback
, l
, &msg
))
120 l
->shaperegion
= msg
.NewShape
;
125 * The user passed me the new shape but no callback.
127 l
->shaperegion
= newshape
;
130 DisposeRegion(l
->shape
);
132 * At this point l->shaperegion holds the layer that is to be
133 * installed. Let's cut it down to the actually visible part.
136 l
->shape
= NewRegion();
139 struct Rectangle r
= {0, 0, l
->Width
- 1, l
->Height
- 1};
141 OrRectRegion(l
->shape
, &r
);
142 /* FIXME: handle error here */
146 AndRegionRegion(l
->shaperegion
, l
->shape
);
148 _TranslateRect(&l
->shape
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
150 SetRegion(l
->shape
, l
->visibleshape
);
151 AndRegionRegion(l
->parent
->visibleshape
, l
->visibleshape
);
156 * Let me backup parts of the layers that are behind the
157 * layer l and the layers that are its family.
167 if(IS_VISIBLE(_l
) && DO_OVERLAP(&l
->visibleshape
->bounds
, &_l
->visibleshape
->bounds
))
168 _BackupPartsOfLayer(_l
, l
->visibleshape
, 0, FALSE
, LayersBase
);
173 if (IS_VISIBLE(_l
) || (NULL
== lparent
->parent
))
176 lparent
= lparent
->parent
;
184 * Make the new layer and its family visible
185 * Since the parent might have become bigger more
186 * of the children might become visible...
193 if (IS_VISIBLE(_l
) &&
194 (DO_OVERLAP(&cutnewshape
.bounds
, &_l
->visibleshape
->bounds
) ||
195 DO_OVERLAP(&cutoldshape
.bounds
, &_l
->visibleshape
->bounds
)))
197 ClearRegion(_l
->VisibleRegion
);
198 _ShowPartsOfLayer(_l
, &r
, LayersBase
);
201 SetRegion(&r
, _l
->VisibleRegion
);
204 if ((TRUE
== behind_l
) && (IS_VISIBLE(_l
) || IS_ROOTLAYER(_l
)))
205 AndRegionRegion(_l
->VisibleRegion
, &cutoldshape
);
209 if (IS_VISIBLE(_l
) || (NULL
== lparent
->parent
))
212 lparent
= lparent
->parent
;
218 if (FALSE
== behind_l
)
220 SetRegion(_l
->shape
, _l
->visibleshape
);
221 AndRegionRegion(_l
->parent
->visibleshape
, _l
->visibleshape
);
225 ClearRegionRegion(_l
->visibleshape
, &r
);
233 if (!IS_EMPTYREGION(&cutoldshape
))
236 (IS_SIMPLEREFRESH(lparent
) || IS_ROOTLAYER(lparent
)))
237 _BackFillRegion(l
->parent
, &cutoldshape
, TRUE
, LayersBase
);
240 ClearRegion(&cutoldshape
);
242 } /* if (IS_VISIBLE(l)) */
244 ClearRegion(&cutnewshape
);
248 UnlockLayers(l
->LayerInfo
);
253 } /* ChangeLayerShape */