- Wait for mouse acks properly.
[cake.git] / rom / hyperlayers / changelayershape.c
blob60b54d3f2bfef9b3f86586830d4b44a53a27049b
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
8 #include <proto/exec.h>
9 #include <exec/types.h>
10 #include <exec/memory.h>
11 #include "layers_intern.h"
12 #include <aros/libcall.h>
13 #include <proto/graphics.h>
14 #include <proto/utility.h>
15 #include <utility/hooks.h>
16 #include "basicfuncs.h"
18 /*****************************************************************************
20 NAME */
21 #include <proto/layers.h>
22 AROS_LH3(struct Region *, ChangeLayerShape,
24 /* SYNOPSIS */
25 AROS_LHA(struct Layer *, l , A0),
26 AROS_LHA(struct Region *, newshape , A1),
27 AROS_LHA(struct Hook *, callback , A2),
28 /* LOCATION */
29 struct LayersBase *, LayersBase, 41, Layers)
31 /* FUNCTION
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:
38 AROS_UFC4(struct Region *, callback,
39 AROS_UFCA(struct Hook * , hook , A0),
40 AROS_UFCA(struct Layer * , l , A2),
41 AROS_UFCA(struct ScaleLayerParam * , arg , A1));
44 INPUTS
45 L - pointer to layer
46 newshape - pointer to a region that comprises the new shape
47 of the layer. May be NULL if callback is provided.
48 callback - pointer to a callback hook. May be NULL if newshape
49 is given.
51 RESULT
52 Pointer to the previously installed region.
54 NOTES
56 EXAMPLE
58 BUGS
60 SEE ALSO
62 INTERNALS
64 HISTORY
66 *****************************************************************************/
68 AROS_LIBFUNC_INIT
70 struct Region * returnshape = NULL;
72 LockLayers(l->LayerInfo);
75 struct Region r, cutoldshape, rtmp, cutnewshape;
76 struct Layer * lparent, * _l, * lfirst = NULL;
77 int behind_l = FALSE;
78 InitRegion(&r);
79 InitRegion(&rtmp);
80 InitRegion(&cutoldshape);
81 InitRegion(&cutnewshape);
84 if (IS_VISIBLE(l))
87 * Backup everything that is visible right now into
88 * cliprects.
90 lfirst = GetFirstFamilyMember(l);
91 SetRegion(lfirst->VisibleRegion, &r);
93 SetRegion(l->visibleshape, &cutoldshape);
94 _BackupPartsOfLayer(l, &cutoldshape, 0, TRUE, LayersBase);
98 * Get the current layer's shape as the paramter to return
99 * from this function.
101 returnshape = l->shaperegion;
103 if (NULL != callback)
105 struct ChangeLayerShapeMsg clsm;
106 clsm.newshape = newshape;
107 clsm.cliprect = l->ClipRect;
108 clsm.shape = l->shape;
110 * call the callback to the user to give me a new shape
111 * The user can manipulate the cliprects of the layer
112 * l and can have a look at the current shape.
114 l->shaperegion = (struct Region *)CallHookPkt(callback, l, &clsm);
116 else
119 * The user passed me the new shape but no callback.
121 l->shaperegion = newshape;
124 DisposeRegion(l->shape);
126 * At this point l->shaperegion holds the layer that is to be
127 * installed. Let's cut it down to the actually visible part.
130 l->shape = NewRectRegion(0,0,l->Width-1,l->Height-1);
132 if (l->shaperegion)
133 AndRegionRegion(l->shaperegion, l->shape);
135 _TranslateRect(&l->shape->bounds, l->bounds.MinX, l->bounds.MinY);
137 SetRegion(l->shape, l->visibleshape);
138 AndRegionRegion(l->parent->visibleshape, l->visibleshape);
140 if (IS_VISIBLE(l))
143 * Let me backup parts of the layers that are behind the
144 * layer l and the layers that are its family.
147 lparent = l->parent;
148 _l = lfirst;
150 while (1)
152 if ((l != _l))
154 if(IS_VISIBLE(_l) && DO_OVERLAP(&l->visibleshape->bounds, &_l->visibleshape->bounds))
155 _BackupPartsOfLayer(_l, l->visibleshape, 0, FALSE, LayersBase);
158 if (_l == lparent)
160 if (IS_VISIBLE(_l) || (NULL == lparent->parent))
161 break;
162 else
163 lparent = lparent->parent;
166 _l = _l->back;
167 } /* while (1) */
171 * Make the new layer and its family visible
172 * Since the parent might have become bigger more
173 * of the children might become visible...
175 _l = lfirst;
176 lparent = l->parent;
178 while (1)
180 if (IS_VISIBLE(_l) &&
181 (DO_OVERLAP(&cutnewshape.bounds, &_l->visibleshape->bounds) ||
182 DO_OVERLAP(&cutoldshape.bounds, &_l->visibleshape->bounds)))
184 ClearRegion(_l->VisibleRegion);
185 _ShowPartsOfLayer(_l, &r, LayersBase);
187 else
188 SetRegion(&r, _l->VisibleRegion);
191 if ((TRUE == behind_l) && (IS_VISIBLE(_l) || IS_ROOTLAYER(_l)))
192 AndRegionRegion(_l->VisibleRegion, &cutoldshape);
194 if (_l == lparent)
196 if (IS_VISIBLE(_l) || (NULL == lparent->parent))
197 break;
198 else
199 lparent = lparent->parent;
202 if (l == _l)
203 behind_l = TRUE;
205 if (FALSE == behind_l)
207 SetRegion(_l->shape, _l->visibleshape);
208 AndRegionRegion(_l->parent->visibleshape, _l->visibleshape);
211 if (IS_VISIBLE(_l))
212 ClearRegionRegion(_l->visibleshape, &r);
214 _l = _l->back;
215 } /* while(1) */
217 ClearRegion(&rtmp);
218 ClearRegion(&r);
220 if (!IS_EMPTYREGION(&cutoldshape))
222 if (lparent &&
223 (IS_SIMPLEREFRESH(lparent) || IS_ROOTLAYER(lparent)))
224 _BackFillRegion(l->parent, &cutoldshape, TRUE, LayersBase);
227 ClearRegion(&cutoldshape);
229 } /* if (IS_VISIBLE(l)) */
231 ClearRegion(&cutnewshape);
235 UnlockLayers(l->LayerInfo);
237 return returnshape;
239 AROS_LIBFUNC_EXIT
240 } /* ChangeLayerShape */