x11gfx.hidd: support 32 bit modes
[AROS.git] / rom / hyperlayers / changelayershape.c
blob50e755be193e1fbb5c916fbde65bae42c4b9c3e9
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
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 /*****************************************************************************
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, 37, 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:
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));
45 INPUTS
46 L - pointer to layer
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
50 is given.
52 RESULT
53 Pointer to the previously installed region.
55 NOTES
57 EXAMPLE
59 BUGS
61 SEE ALSO
63 INTERNALS
65 HISTORY
67 *****************************************************************************/
69 AROS_LIBFUNC_INIT
71 struct Region * returnshape = NULL;
73 LockLayers(l->LayerInfo);
76 struct Region r, cutoldshape, rtmp, cutnewshape;
77 struct Layer * lparent, * _l, * lfirst = NULL;
78 int behind_l = FALSE;
79 InitRegion(&r);
80 InitRegion(&rtmp);
81 InitRegion(&cutoldshape);
82 InitRegion(&cutnewshape);
85 if (IS_VISIBLE(l))
88 * Backup everything that is visible right now into
89 * cliprects.
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;
122 else
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();
137 if (l->shape)
139 struct Rectangle r = {0, 0, l->Width - 1, l->Height - 1};
141 OrRectRegion(l->shape, &r);
142 /* FIXME: handle error here */
145 if (l->shaperegion)
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);
153 if (IS_VISIBLE(l))
156 * Let me backup parts of the layers that are behind the
157 * layer l and the layers that are its family.
160 lparent = l->parent;
161 _l = lfirst;
163 while (1)
165 if ((l != _l))
167 if(IS_VISIBLE(_l) && DO_OVERLAP(&l->visibleshape->bounds, &_l->visibleshape->bounds))
168 _BackupPartsOfLayer(_l, l->visibleshape, 0, FALSE, LayersBase);
171 if (_l == lparent)
173 if (IS_VISIBLE(_l) || (NULL == lparent->parent))
174 break;
175 else
176 lparent = lparent->parent;
179 _l = _l->back;
180 } /* while (1) */
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...
188 _l = lfirst;
189 lparent = l->parent;
191 while (1)
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);
200 else
201 SetRegion(&r, _l->VisibleRegion);
204 if ((TRUE == behind_l) && (IS_VISIBLE(_l) || IS_ROOTLAYER(_l)))
205 AndRegionRegion(_l->VisibleRegion, &cutoldshape);
207 if (_l == lparent)
209 if (IS_VISIBLE(_l) || (NULL == lparent->parent))
210 break;
211 else
212 lparent = lparent->parent;
215 if (l == _l)
216 behind_l = TRUE;
218 if (FALSE == behind_l)
220 SetRegion(_l->shape, _l->visibleshape);
221 AndRegionRegion(_l->parent->visibleshape, _l->visibleshape);
224 if (IS_VISIBLE(_l))
225 ClearRegionRegion(_l->visibleshape, &r);
227 _l = _l->back;
228 } /* while(1) */
230 ClearRegion(&rtmp);
231 ClearRegion(&r);
233 if (!IS_EMPTYREGION(&cutoldshape))
235 if (lparent &&
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);
250 return returnshape;
252 AROS_LIBFUNC_EXIT
253 } /* ChangeLayerShape */