Here's an idea: don't add interrupt handlers when they've already been
[AROS.git] / rom / hyperlayers / dohookcliprects.c
blob88fc4861dd8a4d32ca056ba5d2d7c367041cb48d
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
8 #include <aros/debug.h>
9 #include <aros/libcall.h>
10 #include <exec/types.h>
12 #include "layers_intern.h"
13 #include "basicfuncs.h"
14 /*****************************************************************************
16 NAME */
17 #include <proto/layers.h>
19 AROS_LH3(void, DoHookClipRects,
21 /* SYNOPSIS */
22 AROS_LHA(struct Hook *, hook , A0),
23 AROS_LHA(struct RastPort *, rport, A1),
24 AROS_LHA(struct Rectangle *, rect , A2),
26 /* LOCATION */
27 struct LayersBase *, LayersBase, 36, Layers)
29 /* FUNCTION
31 INPUTS
32 hook - pointer to the hook to be called for the cliprects of
33 the given layer
35 rport - pointer to the rastport where the layers upon which the
36 hook is to be called
38 rect - no operation is allowed outside this rectangle. If a layer
39 is bigger than this rectangle only operations in the
40 common area are allowed.
42 RESULT
44 NOTES
46 EXAMPLE
48 BUGS
50 SEE ALSO
52 INTERNALS
54 HISTORY
55 27-11-96 digulla automatically created from
56 layers_lib.fd and clib/layers_protos.h
58 *****************************************************************************/
59 { /* sv */
60 AROS_LIBFUNC_INIT
62 struct Layer *L;
64 D(bug("DoHookClipRects(hook @ $%lx, rport @ $%lx, rect @ $%lx)\n", hook, rport, rect));
66 /* if the hook is LAYERS_NOBACKFILL then I am not doing anything here. */
67 if(hook == (struct Hook *)LAYERS_NOBACKFILL)
69 return;
72 L = rport -> Layer;
73 /* does this rastport have a layer?? */
74 if( NULL == L )
76 /* non-layered rastport */
78 /* You MUST supply a rect to clip the hook's actions! */
79 _CallLayerHook(hook, rport, NULL, rect, rect->MinX, rect->MinY, LayersBase);
81 else
83 struct Rectangle boundrect;
85 /* layered rastport */
87 /* I assume that the given bounds rectangle is relative to the upper left corner of the
88 layer's rastport. This makes more sense than if it was relative to the rastport of
89 the screen where this layer is to be found in
92 LockLayer(0, L);
94 boundrect.MinX = rect->MinX + L->bounds.MinX - L->Scroll_X;
95 boundrect.MinY = rect->MinY + L->bounds.MinY - L->Scroll_Y;
96 boundrect.MaxX = rect->MaxX + L->bounds.MinX - L->Scroll_X;
97 boundrect.MaxY = rect->MaxY + L->bounds.MinY - L->Scroll_Y;
99 /* first check whether this layer is to be considered at all */
100 if (!(boundrect.MinX > L->bounds.MaxX ||
101 boundrect.MinY > L->bounds.MaxY ||
102 boundrect.MaxX < L->bounds.MinX ||
103 boundrect.MaxY < L->bounds.MinY))
105 /* yes, that's a layer to be considered */
106 /* I want nobody else to interrupt me while I call the hook for this layer */
107 struct ClipRect * CR;
109 CR = L->ClipRect; /* must not read this before LockLayer!! */
111 #if 0 /* stegerg: seems to have been crap idea/test. Where the hell did I get this from??? */
113 ** Set rport->Layer to NULL, so that the hook function does not
114 ** need to clone the rport and set clonerp->Layer to NULL in
115 ** order to used rastport based gfx functions
117 ** stegerg: AFAIK this is done only since Kickstart 3.1
120 rport->Layer = NULL;
121 #endif
123 /* process all ClipRects of this layer */
124 while (NULL != CR)
126 /* I am going to call the hook for all visible cliprects and
127 for invisible cliprects belonging to smart or superbitmap
128 layers =>
129 So I am not calling it for invisble cliprects belonging to
130 a simple layer.
133 if (!(NULL != CR->lobs &&
134 0 != (L->Flags & LAYERSIMPLE)) )
136 struct Rectangle bounds;
137 /* That's a ClipRect to visit, if it's inside the given rectangle */
138 /* Generate the bounds rectangle. This rectangle shows the part
139 of the clipRect that is supposed to be changed. So it might get
140 the coordinates of the ClipRect, but it can also be smaller. */
142 bounds.MinX = (boundrect.MinX > CR->bounds.MinX) ? boundrect.MinX
143 : CR->bounds.MinX;
144 bounds.MinY = (boundrect.MinY > CR->bounds.MinY) ? boundrect.MinY
145 : CR->bounds.MinY;
146 bounds.MaxX = (boundrect.MaxX < CR->bounds.MaxX) ? boundrect.MaxX
147 : CR->bounds.MaxX;
148 bounds.MaxY = (boundrect.MaxY < CR->bounds.MaxY) ? boundrect.MaxY
149 : CR->bounds.MaxY;
151 /* Is the cliprect inside the bounds... */
152 if (bounds.MinX <= bounds.MaxX && bounds.MinY <= bounds.MaxY)
154 struct BitMap * bm;
155 WORD offsetX = bounds.MinX - L->bounds.MinX + L->Scroll_X; /* + scrollx is correct! */
156 WORD offsetY = bounds.MinY - L->bounds.MinY + L->Scroll_Y; /* + scrolly is correct! */
158 /* Call the hook for the rectangle given by bounds. */
160 /* If the ClipRect is hidden, then this might get special..., but
161 only for non-simple layers, which are already ignored by an if
162 further above */
163 if (NULL != CR->lobs)
165 bm = rport->BitMap;
167 if (0 != (L->Flags & LAYERSUPER))
169 /* it's a superbitmap layer */
170 bounds.MinX -= ( L->bounds.MinX + L->Scroll_X );
171 bounds.MinY -= ( L->bounds.MinY + L->Scroll_Y );
172 bounds.MaxX -= ( L->bounds.MinX + L->Scroll_X );
173 bounds.MaxY -= ( L->bounds.MinY + L->Scroll_Y );
174 rport->BitMap = L->SuperBitMap;
176 else
178 /* it's a smart layer but not superbitmap */
179 /* it's hidden, the hook has to blit into the hidden cliprect's bitmap now */
180 /* adjust the bounds */
181 bounds.MinX = bounds.MinX - CR->bounds.MinX + ALIGN_OFFSET(CR->bounds.MinX);
182 bounds.MinY = bounds.MinY - CR->bounds.MinY;
183 bounds.MaxX = bounds.MaxX - CR->bounds.MinX + ALIGN_OFFSET(CR->bounds.MinX);
184 bounds.MaxY = bounds.MaxY - CR->bounds.MinY;
185 rport->BitMap = CR->BitMap;
188 _CallLayerHook(hook, rport, L, &bounds, offsetX, offsetY, LayersBase);
189 rport->BitMap = bm;
191 } /* hidden cliprect */
192 else
194 _CallLayerHook(hook, rport, L, &bounds, offsetX, offsetY, LayersBase);
195 } /* visible cliprect */
197 } /* if (cliprect intersects rect in screen coords) */
199 } /* ignore hidden simple refresh cliprects */
201 CR = CR->Next;
203 } /* foreach cliprect */
205 #if 0 /* stegerg: seems to have been crap idea/test. Where the hell did I get this from??? */
207 /* Restore RastPort->Layer which was set to NULL further above */
209 rport->Layer = L;
210 #endif
212 } /* if (rect in screen coords interesects layer coords) */
214 UnlockLayer(L);
216 } /* if (layered rastport) */
218 AROS_LIBFUNC_EXIT
219 } /* DoHookClipRects */