2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
5 Desc: Basic support functions for layers.library.
9 #include <aros/config.h>
10 #include <aros/asmcall.h>
11 #include <exec/memory.h>
12 #include <graphics/rastport.h>
13 #include <graphics/clip.h>
14 #include <graphics/regions.h>
15 #include <graphics/layers.h>
16 #include <graphics/gfx.h>
17 #include <utility/hooks.h>
20 #include <proto/exec.h>
21 #include <proto/alib.h>
22 #include <proto/graphics.h>
23 #include <proto/layers.h>
24 #include <proto/arossupport.h>
26 #include "layers_intern.h"
27 #include "basicfuncs.h"
29 #define CLIPRECTS_OUTSIDE_OF_SHAPE 1
46 /***************************************************************************/
48 /***************************************************************************/
50 #define CR2NR_NOBITMAP 0
51 #define CR2NR_BITMAP 1
53 #if !(AROS_FLAVOUR & AROS_FLAVOUR_NATIVE)
55 * These functions cause the infamous "fixed or forbidden register was spilled"
56 * bug/feature in m68k gcc, so these were written straight in asm. They can be
57 * found in config/m68k-native/layers, for the m68k AROSfA target. Other targets,
58 * that use stack passing, can use these versions.
61 void BltRPtoCR(struct RastPort
* rp
,
64 struct LayersBase
* LayersBase
)
70 ALIGN_OFFSET(cr
->bounds
.MinX
), 0,
71 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1,
72 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
79 void BltCRtoRP(struct RastPort
* rp
,
82 struct LayersBase
* LayersBase
)
85 ALIGN_OFFSET(cr
->bounds
.MinX
),
90 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1,
91 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
98 #endif /* if !native */
100 /***************************************************************************/
102 /***************************************************************************/
107 /* struct Rectangle rect; (replaced by the next line!) */
108 WORD MinX
, MinY
, MaxX
, MaxY
;
109 LONG OffsetX
, OffsetY
;
112 void _CallLayerHook(struct Hook
* h
,
113 struct RastPort
* rp
,
115 struct Rectangle
* R
,
118 struct LayersBase
* LayersBase
)
120 struct BitMap
* bm
= rp
->BitMap
;
124 if (IL(L
)->intflags
& INTFLAG_AVOID_BACKFILL
) return;
127 if (h
== LAYERS_BACKFILL
)
129 /* Use default backfill, which means that I will clear the area */
136 R
->MaxX
- R
->MinX
+ 1,
137 R
->MaxY
- R
->MinY
+ 1,
145 if (h
!= LAYERS_NOBACKFILL
)
147 struct layerhookmsg msg
;
153 msg
.OffsetX
= offsetX
;
154 msg
.OffsetY
= offsetY
;
156 AROS_UFC3NR(void, h
->h_Entry
,
157 AROS_UFCA(struct Hook
*, h
,A0
),
158 AROS_UFCA(struct RastPort
*, rp
,A2
),
159 AROS_UFCA(struct layerhookmsg
*, &msg
,A1
)
166 /***************************************************************************/
168 /***************************************************************************/
171 * Free a layer and all its associated structures
173 void _FreeLayer(struct Layer
* l
, struct LayersBase
*LayersBase
)
175 struct ClipRect
* cr
= l
->ClipRect
, * _cr
;
180 FreeBitMap(cr
->BitMap
);
183 FreePooled(LayersBase
->lb_ClipRectPool
, cr
, sizeof(struct ClipRect
));
189 * also free all backed up cliprects.
191 cr
= l
->SuperSaveClipRects
;
196 FreePooled(LayersBase
->lb_ClipRectPool
, cr
, sizeof(struct ClipRect
));
201 DisposeRegion(l
->DamageList
);
202 DisposeRegion(l
->VisibleRegion
);
203 DisposeRegion(l
->shape
);
204 DisposeRegion(l
->visibleshape
);
206 FreeMem(l
, sizeof(struct IntLayer
));
211 /***************************************************************************/
213 /***************************************************************************/
215 /*-------------------------------------------------------------------------*/
217 * Allocate LayerInfo_extra and initialize its resource list. Layers uses
218 * this resource list to keep track of various memory allocations it makes
219 * for the layers. See ResourceNode and ResData in layers_intern.h for the
220 * node structure. See AddLayersResource for more information on the basic
223 BOOL
_AllocExtLayerInfo(struct Layer_Info
* li
, struct LayersBase
*LayersBase
)
225 if(++li
->fatten_count
!= 0)
228 if(!(li
->LayerInfo_extra
= AllocMem(sizeof(struct LayerInfo_extra
),MEMF_PUBLIC
|MEMF_CLEAR
)))
231 NewList((struct List
*)&((struct LayerInfo_extra
*)li
->LayerInfo_extra
)->lie_ResourceList
);
237 * Free LayerInfo_extra.
239 void _FreeExtLayerInfo(struct Layer_Info
* li
, struct LayersBase
*LayersBase
)
241 if(--li
->fatten_count
>= 0)
244 /* Kill Root Layer */
247 DeleteLayer(0UL, li
->check_lp
);
250 if(li
->LayerInfo_extra
== NULL
)
253 FreeMem(li
->LayerInfo_extra
, sizeof(struct LayerInfo_extra
));
255 li
->LayerInfo_extra
= NULL
;
259 * Dynamically allocate LayerInfo_extra if it isn't already there.
261 BOOL
SafeAllocExtLI(struct Layer_Info
* li
,
262 struct LayersBase
* LayersBase
)
266 /* Check to see if we can ignore the rest of this call. :-) */
267 if(li
->Flags
& NEWLAYERINFO_CALLED
)
270 if(_AllocExtLayerInfo(li
, LayersBase
))
279 * Free LayerInfo_extra if it was dynamically allocated, and unlock the LI.
281 void SafeFreeExtLI(struct Layer_Info
* li
,
282 struct LayersBase
* LayersBase
)
284 if(!(li
->Flags
& NEWLAYERINFO_CALLED
))
285 _FreeExtLayerInfo(li
, LayersBase
);
290 /***************************************************************************/
292 /***************************************************************************/
295 #define MAX(a,b) ((a) > (b) ? (a) : (b))
296 #define MIN(a,b) ((a) < (b) ? (a) : (b))
298 void _TranslateRect(struct Rectangle *rect, WORD dx, WORD dy)
307 /***************************************************************************/
308 /* RESOURCE HANDLING */
309 /***************************************************************************/
312 * Allocate memory for a ClipRect.
315 struct ClipRect
* _AllocClipRect(struct Layer
* L
, struct LayersBase
*LayersBase
)
317 struct ClipRect
* CR
;
319 CR
= L
->SuperSaveClipRects
;
323 /* I want to access the list of free ClipRects alone */
324 L
->SuperSaveClipRects
= CR
->Next
;
325 L
->SuperSaveClipRectCounter
--;
334 return AllocPooled(LayersBase
->lb_ClipRectPool
, sizeof(struct ClipRect
));
338 * Return memory of a ClipRect for later use.
341 void _FreeClipRect(struct ClipRect
* CR
,
343 struct LayersBase
* LayersBase
)
345 if (L
->SuperSaveClipRectCounter
< MAXSUPERSAVECLIPRECTS
)
347 /* Add the ClipRect to the front of the list */
348 CR
-> Next
= L
-> SuperSaveClipRects
;
349 L
-> SuperSaveClipRects
= CR
;
350 L
-> SuperSaveClipRectCounter
++;
354 FreePooled(LayersBase
->lb_ClipRectPool
, CR
, sizeof(struct ClipRect
));
359 * Free a whole list of cliprects including the allocated bitmaps (if any)
362 void _FreeClipRectListBM(struct Layer
* L
,
363 struct ClipRect
* CR
,
364 struct LayersBase
*LayersBase
)
366 struct ClipRect
* _CR
= CR
;
368 if ((L
->Flags
& (LAYERSUPER
|LAYERSMART
)) == LAYERSMART
)
374 * This function is not watching for the upper limit of
375 * pre allocated cliprects.
377 L
->SuperSaveClipRectCounter
++;
381 if (NULL
!= _CR
->BitMap
&& TRUE
== isSmart
)
383 FreeBitMap(_CR
->BitMap
);
386 if (NULL
!= _CR
->Next
)
388 L
->SuperSaveClipRectCounter
++;
394 /* _CR is the last ClipRect in the list. I concatenate the
395 currently preallocated list of ClipRects with that list. */
396 _CR
->Next
= L
->SuperSaveClipRects
;
398 /* CR is the head of the ClipRect list now */
399 L
->SuperSaveClipRects
= CR
;
403 /***************************************************************************/
405 /***************************************************************************/
407 struct ClipRect
* _CreateClipRectsFromRegion(struct Region
*r
,
410 struct Region
* inverter
,
411 struct LayersBase
*LayersBase
)
414 struct ClipRect
* firstcr
= NULL
, * cr
;
415 struct BitMap
* display_bm
= l
->rp
->BitMap
;
418 * From region r create cliprects
422 struct RegionRectangle
* rr
= r
->RegionRectangle
;
425 cr
= _AllocClipRect(l
, LayersBase
);
426 cr
->bounds
.MinX
= rr
->bounds
.MinX
+ r
->bounds
.MinX
;
427 cr
->bounds
.MinY
= rr
->bounds
.MinY
+ r
->bounds
.MinY
;
428 cr
->bounds
.MaxX
= rr
->bounds
.MaxX
+ r
->bounds
.MinX
;
429 cr
->bounds
.MaxY
= rr
->bounds
.MaxY
+ r
->bounds
.MinY
;
430 cr
->lobs
= (struct Layer
*)(IPTR
)invisible
;
433 if (TRUE
== invisible
&& IS_SMARTREFRESH(l
))
435 cr
->BitMap
= AllocBitMap(
436 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1 + 16,
437 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
444 kprintf("\t\t%s: Created cliprect %d/%d-%d/%d invisible: %d\n",
461 * Flip the shape to the opposite part and
462 * limit it to its own shape.
465 XorRegionRegion(inverter
, r
);
467 XorRectRegion(r
,&l
->bounds
);
469 #if !CLIPRECTS_OUTSIDE_OF_SHAPE
470 AndRegionRegion(l
->shape
,r
);
472 AndRectRegion(r
,&l
->bounds
);
474 if (TRUE
== invisible
)
488 int _CopyClipRectsToClipRects(struct Layer
* l
,
489 struct ClipRect
* oldcr
,
490 struct ClipRect
* newcr
,
496 struct LayersBase
*LayersBase
)
498 struct BitMap
* display_bm
= l
->rp
->BitMap
;
500 while (NULL
!= oldcr
)
502 struct ClipRect
* _cr
= newcr
;
503 int area
= RECTAREA(&oldcr
->bounds
);
504 while ((NULL
!= _cr
) && (0 != area
) )
506 struct Rectangle intersect
;
509 * Do the two rectangles overlap?
511 if (AndRectRect(&_cr
->bounds
, &oldcr
->bounds
, &intersect
))
513 LONG xSize
= intersect
.MaxX
- intersect
.MinX
+ 1;
514 LONG ySize
= intersect
.MaxY
- intersect
.MinY
+ 1;
517 * Is this new one supposed to be invisible?
519 if (NULL
!= _cr
->lobs
)
521 struct BitMap
* srcbm
;
523 * The new one is supposed to be invisible.
524 * So for SIMPLEREFRESH layers I don't have to
526 * a) not in backupmode or
527 * b) old cr was invisible
529 if (IS_SIMPLEREFRESH(l
) && FALSE
== backupmode
&& NULL
== _cr
->BitMap
)
531 if (FALSE
== addtodamagelist
)
533 struct Rectangle rect
= intersect
;
535 _TranslateRect(&rect
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
538 * stegerg: Not sure if this is a good idea. What for example if
539 * updating is done in several passes? And CopyClipRectsToClipRects is
540 * used by all kinds of functions including BeginUpdate/EndUpdate/InstallClipRegion/etc.
542 ClearRectRegion(l
->DamageList
, &rect
);
545 kprintf("%s: Removing %d/%d-%d/%d from damagelist!\t",
552 kprintf("%s: Layer: %d/%d-%d/%d!\n",
559 kprintf("%s: oldcr: %d/%d-%d/%d!\t",
566 kprintf("%s: _cr: %d/%d-%d/%d!\n\n",
576 else if (IS_SIMPLEREFRESH(l
) && TRUE
== backupmode
&& NULL
!= oldcr
->lobs
)
578 if (TRUE
== addtodamagelist
)
580 struct Rectangle rect
= intersect
;
581 _TranslateRect(&rect
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
583 // FIXME (if possible)
584 // !!! Also areas where a child disappears beyond the
585 // boundaries of its parent are added here!
586 OrRectRegion(l
->DamageList
, &rect
);
588 kprintf("_cr->BitMap: %p ,_cr->lobs: %d\n",_cr
->BitMap
,_cr
->lobs
);
591 kprintf("%s: Adding %d/%d-%d/%d to damagelist of l=%p!\t",
601 kprintf("%s: Layer: %d/%d-%d/%d!\n",
608 kprintf("%s: oldcr: %d/%d-%d/%d!\t",
615 kprintf("%s: _cr: %d/%d-%d/%d!\n\n",
624 //kprintf("Not adding to damage list for l=%p!\n",l);
631 struct BitMap
* destbm
;
633 if (IS_SUPERREFRESH(l
))
634 destbm
= l
->SuperBitMap
;
636 destbm
= _cr
->BitMap
;
639 * Does the source rect have a bitmap (off screen)
640 * or is it on the screen.
642 if (oldcr
->lobs
&& !IS_SUPERREFRESH(l
))
645 * Copy from hidden bitmap to hidden bitmap
647 xSrc
= (oldcr
->bounds
.MinX
- _cr
->bounds
.MinX
);
651 * oldcr is further to the left
659 * oldcr is further to the right
665 xSrc
+= ALIGN_OFFSET(oldcr
->bounds
.MinX
+ srcdx
);
666 xDest
+= ALIGN_OFFSET(_cr
->bounds
.MinX
+ destdx
);
668 ySrc
= (oldcr
->bounds
.MinY
- _cr
->bounds
.MinY
);
679 //kprintf("Using old cr's BitMap!\n");
680 srcbm
= oldcr
->BitMap
;
687 if (oldcr
->bounds
.MinX
> _cr
->bounds
.MinX
)
689 xSrc
= oldcr
->bounds
.MinX
;
690 if (IS_SUPERREFRESH(l
))
691 xDest
= (oldcr
->bounds
.MinX
- _cr
->bounds
.MinX
) SCROLLSIGN l
->Scroll_X
;
693 xDest
= (oldcr
->bounds
.MinX
- _cr
->bounds
.MinX
) + ALIGN_OFFSET((_cr
->bounds
.MinX
+ destdx
));
697 xSrc
= _cr
->bounds
.MinX
;
698 if (IS_SUPERREFRESH(l
))
699 xDest
= SCROLLSIGN l
->Scroll_X
;
701 xDest
= ALIGN_OFFSET((_cr
->bounds
.MinX
+ destdx
));
704 if (oldcr
->bounds
.MinY
> _cr
->bounds
.MinY
)
706 ySrc
= oldcr
->bounds
.MinY
;
707 yDest
= oldcr
->bounds
.MinY
- _cr
->bounds
.MinY
;
708 if (IS_SUPERREFRESH(l
))
709 yDest
= yDest SCROLLSIGN l
->Scroll_Y
;
713 ySrc
= _cr
->bounds
.MinY
;
715 if (IS_SUPERREFRESH(l
))
716 yDest
= yDest SCROLLSIGN l
->Scroll_Y
;
719 srcbm
= l
->rp
->BitMap
;
720 //kprintf("Using bitmap of screen!\n");
723 if (IS_SIMPLEREFRESH(l
) &&
724 NULL
== _cr
->BitMap
&&
728 * Get a bitmap (if not there) and make a backup
730 _cr
->BitMap
= AllocBitMap(
731 _cr
->bounds
.MaxX
- _cr
->bounds
.MinX
+ 1 + 16 ,
732 _cr
->bounds
.MaxY
- _cr
->bounds
.MinY
+ 1,
736 destbm
= _cr
->BitMap
;
751 kprintf("%s: backing up: from %d/%d to %d/%d width:%d, height: %d\n",
761 area
-= (xSize
* ySize
);
765 else //if (FALSE == backupmode)
768 * The new one is visible. if the old one was not visible
769 * then I have to show it.
770 * If it is a simple refresh layer and it has it
771 * backed up (only when moving!) then I must show
772 * this. If it has nothing backed up then I must
773 * add a part to the damage list.
775 if (IS_SIMPLEREFRESH(l
) &&
776 (NULL
!= oldcr
->lobs
) &&
777 (NULL
== oldcr
->BitMap
))
779 if (NULL
!= oldcr
->lobs
&& NULL
== oldcr
->BitMap
)
781 struct Rectangle rect
= intersect
;
783 _CallLayerHook(l
->BackFill
,
790 _TranslateRect(&rect
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
791 OrRectRegion(l
->DamageList
, &rect
);
793 kprintf("Adding: %d\n",addtodamagelist
);
794 kprintf("%s: Adding %d/%d-%d/%d to damagelist!\t",
801 kprintf("%s: Layer: %d/%d-%d/%d!\n",
808 kprintf("%s: oldcr: %d/%d-%d/%d!\t",
815 kprintf("%s: _cr: %d/%d-%d/%d!\n",
827 //kprintf("%s: Showing a part of a backed up bitmap!\n",__FUNCTION__);
828 if (NULL
!= oldcr
->lobs
)
831 * Copy out of hidden bitmap
835 struct BitMap
* srcbm
;
837 if (IS_SUPERREFRESH(l
))
838 srcbm
= l
->SuperBitMap
;
840 srcbm
= oldcr
->BitMap
;
843 * I have to make the old one visible
844 * two cases left: SMART REFRESH and SUPERBITMAP
847 if (!IS_SUPERREFRESH(l
))
850 * Copy from hidden BitMap to screen!
851 * If a simple refresh layer is moved it might
852 * also have a BitMap!!!
854 xSrc
= (oldcr
->bounds
.MinX
- _cr
->bounds
.MinX
);
858 * old cr is further to the left
860 xSrc
= -xSrc
+ ALIGN_OFFSET(oldcr
->bounds
.MinX
+ srcdx
);
861 xDest
= _cr
->bounds
.MinX
;
866 * oldcr is further to the right
868 xDest
= oldcr
->bounds
.MinX
;
869 xSrc
= ALIGN_OFFSET(oldcr
->bounds
.MinX
+ srcdx
);
872 ySrc
= (oldcr
->bounds
.MinY
- _cr
->bounds
.MinY
);
876 yDest
= _cr
->bounds
.MinY
;
880 yDest
= oldcr
->bounds
.MinY
;
889 xSrc
= (oldcr
->bounds
.MinX
> _cr
->bounds
.MinX
) ?
890 oldcr
->bounds
.MinX
- _cr
->bounds
.MinX SCROLLSIGN l
->Scroll_X
:
891 _cr
->bounds
.MinX
- oldcr
->bounds
.MinX SCROLLSIGN l
->Scroll_X
;
892 xDest
= _cr
->bounds
.MinX
;
894 ySrc
= (oldcr
->bounds
.MinY
> _cr
->bounds
.MinY
) ?
895 oldcr
->bounds
.MinY
- _cr
->bounds
.MinY SCROLLSIGN l
->Scroll_Y
:
896 _cr
->bounds
.MinY
- oldcr
->bounds
.MinY SCROLLSIGN l
->Scroll_Y
;
897 yDest
= _cr
->bounds
.MinY
;
902 kprintf("\t\t%s: Show cliprect: %d/%d-%d/%d; blitting to %d/%d _cr->lobs: %d\n",
913 /* FIXME: Must have oldcr->BitMap also for SuperBitMap layers! */
927 } /* if was hidden cliprect */
928 } /* if is simple else ... */
929 } /* if new cliprect is visible or invisible */
930 } /* if rectangles overlap */
934 if (IS_SMARTREFRESH(l
) && TRUE
== backupmode
&& NULL
== _cr
->BitMap
&& NULL
!= _cr
->lobs
)
936 _cr
->BitMap
= AllocBitMap(_cr
->bounds
.MaxX
- _cr
->bounds
.MinX
+ 1 + 16 ,
937 _cr
->bounds
.MaxY
- _cr
->bounds
.MinY
+ 1,
944 } /* all new cliprects */
946 if (TRUE
== freelist
)
950 FreeBitMap(oldcr
->BitMap
);
951 _FreeClipRect(oldcr
, l
, LayersBase
);
956 } /* for all old cliprects */
958 if (IS_EMPTYREGION(l
->DamageList
))
959 l
->Flags
&= ~LAYERREFRESH
;
961 l
->Flags
|= LAYERREFRESH
;
964 * If this is a simple refresh layer and I am not in
965 * backup mode and I am not adding to the damagelist
966 * then I must call the backfillhook for the
967 * area of the damage list of a simple refresh layer
970 if (IS_SIMPLEREFRESH(l
) &&
971 (l
->Flags
& LAYERREFRESH
) &&
972 FALSE
== backupmode
&&
973 FALSE
== addtodamagelist
)
975 struct Region
* dr
= l
->DamageList
;
976 struct RegionRectangle
* rr
;
978 _TranslateRect(&dr
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
979 AndRectRegion(dr
, &l
->bounds
);
980 AndRegionRegion(l
->VisibleRegion
, dr
);
981 AndRegionRegion(l
->visibleshape
, dr
);
983 _TranslateRect(&dr
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
985 rr
= dr
->RegionRectangle
;
988 _TranslateRect(&rr
->bounds
,
989 dr
->bounds
.MinX
+ l
->bounds
.MinX
,
990 dr
->bounds
.MinY
+ l
->bounds
.MinY
);
992 _CallLayerHook(l
->BackFill
,
1000 _TranslateRect(&rr
->bounds
,
1001 -dr
->bounds
.MinX
-l
->bounds
.MinX
,
1002 -dr
->bounds
.MinY
-l
->bounds
.MinY
);
1012 * Backup any parts of the layer that overlap with the backup_region
1013 * and that are not already backed up. Create the cliprects and
1014 * bitmaps if necessary.
1015 * Assumption: Only visible parts become invisible,
1016 * invisible parts will not become visible.
1018 * This function MUST not manipulate hide_region!!!!
1020 int _BackupPartsOfLayer(struct Layer
* l
,
1021 struct Region
* hide_region
,
1023 int backupsimplerefresh
,
1024 struct LayersBase
* LayersBase
)
1026 struct ClipRect
* newcr
;
1027 struct Region
*r
, * clipregion
;
1030 * Uninstall clipping region. This causes all pixels to
1031 * be copied into the cliprects that cover the complete
1032 * area of the layer.
1035 clipregion
= _InternalInstallClipRegion(l
, NULL
, 0, 0, LayersBase
);
1037 ClearRegionRegion(hide_region
,l
->VisibleRegion
);
1038 r
= AndRegionRegionND(l
->visibleshape
, l
->VisibleRegion
);
1042 newcr
= _CreateClipRectsFromRegion(r
,l
,FALSE
,NULL
,LayersBase
);
1047 _CopyClipRectsToClipRects(l
,
1048 l
->ClipRect
/* source */,
1049 newcr
/* destination */,
1052 backupsimplerefresh
,
1057 l
->ClipRect
= newcr
;
1062 * Reinstall the clipping region. This causes the
1063 * whole visible area of the layer to be copied
1064 * into the clipping regions cliprects. The
1065 * regular list of cliprects is still maintained.
1068 _InternalInstallClipRegion(l
, clipregion
, dx
, dx
, LayersBase
);
1074 * Show any parts of the layer that overlap with the backup_region
1075 * and that are not already show.
1077 * This function MUST not manipulate show_region!!!!
1080 int _ShowPartsOfLayer(struct Layer
* l
,
1081 struct Region
* show_region
,
1082 struct LayersBase
* LayersBase
)
1084 struct ClipRect
* newcr
;
1086 struct Region
* clipregion
;
1088 //kprintf("%s called for %p\n",__FUNCTION__,l);
1091 * If there is a clipping region then the whole
1092 * window is currently backed up in l->ClipRect
1093 * That covers the complete area. I must first
1094 * make these visible, move them back to
1095 * l->_cliprects and recreate the clipping cliprects
1096 * according to the clipregion
1099 if (show_region
== l
->VisibleRegion
)
1100 kprintf("ERROR - same regions!! %s\n",__FUNCTION__
);
1102 clipregion
= InstallClipRegion(l
, NULL
);
1104 OrRegionRegion(show_region
,l
->VisibleRegion
);
1105 r
= AndRegionRegionND(l
->visibleshape
, l
->VisibleRegion
);
1108 newcr
= _CreateClipRectsFromRegion(r
,l
,FALSE
,NULL
,LayersBase
);
1111 _CopyClipRectsToClipRects(l
,
1112 l
->ClipRect
/* source */,
1113 newcr
/* destination */,
1122 l
->ClipRect
= newcr
;
1125 InstallClipRegion(l
, clipregion
);
1130 int _ShowLayer(struct Layer
* l
, struct LayersBase
*LayersBase
)
1133 struct RegionRectangle
* rr
;
1134 struct ClipRect
* prevcr
= NULL
;
1135 struct BitMap
* bm
= l
->rp
->BitMap
;
1136 int invisible
= FALSE
;
1138 r
= AndRegionRegionND(l
->shape
, l
->VisibleRegion
);
1139 AndRegionRegion(l
->parent
->shape
, r
);
1143 rr
= r
->RegionRectangle
;
1147 struct ClipRect
* cr
;
1149 cr
= (struct ClipRect
*)AllocPooled(LayersBase
->lb_ClipRectPool
, sizeof(struct ClipRect
));
1151 //kprintf("\t\tinvisible: %d !!!!!!!!!!!!\n",invisible);
1153 MinX(cr
) = MinX(rr
) + MinX(r
);
1154 MinY(cr
) = MinY(rr
) + MinY(r
);
1155 MaxX(cr
) = MaxX(rr
) + MinX(r
);
1156 MaxY(cr
) = MaxY(rr
) + MinY(r
);
1157 cr
->lobs
= (struct Layer
*)(IPTR
)invisible
;
1159 kprintf("\t\t%s: Created cliprect %d/%d-%d/%d invisible: %d\n",
1174 if (FALSE
== invisible
)
1177 kprintf("\t\tClearing background! %d/%d-%d/%d bitmap: %p\n",
1185 if (IS_SUPERREFRESH(l
))
1187 BltBitMap(l
->SuperBitMap
,
1188 cr
->bounds
.MinX
- l
->bounds
.MinX
,
1189 cr
->bounds
.MinY
- l
->bounds
.MinY
,
1193 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1,
1194 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
1201 _CallLayerHook(l
->BackFill
,
1213 * This part is to be invisible!
1215 if (IS_SMARTREFRESH(l
))
1217 cr
->BitMap
= AllocBitMap(
1218 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1 + 16,
1219 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
1225 * stegerg: the backfill hook should be called for this bitmap!
1226 * But _CallLayerHook always uses rp->BitMap
1234 if (FALSE
== invisible
)
1236 XorRectRegion(r
, &l
->bounds
);
1237 #if !CLIPRECTS_OUTSIDE_OF_SHAPE
1238 AndRegionRegion(l
->shape
, r
);
1252 * It is assumed that the region r is not needed anymore.
1254 void _BackFillRegion(struct Layer
* l
,
1256 int addtodamagelist
,
1257 struct LayersBase
* LayersBase
)
1259 struct RegionRectangle
* RR
;
1261 RR
= r
->RegionRectangle
;
1262 if (NULL
== RR
) return;
1264 if (IS_SIMPLEREFRESH(l
))
1266 /* Only for simple refresh layers, becuase smart refresh layers
1267 may have damage outside of visibleshape, like when being dragged
1270 AndRegionRegion(l
->visibleshape
, r
);
1274 /* Maybe not needed, but to be sure ... */
1276 AndRectRegion(r
, &l
->bounds
);
1280 if (TRUE
== addtodamagelist
)
1282 l
->Flags
|= LAYERREFRESH
;
1285 /* Region coords are screen relative, but damagelist coords are layer relative! */
1287 _TranslateRect(&r
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
1288 OrRegionRegion(r
, l
->DamageList
);
1289 _TranslateRect(&r
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
1294 struct Rectangle rect
= RR
->bounds
;
1296 //kprintf("%s: adding to damagelist!\n",__FUNCTION__);
1298 /* Region coords are screen relative, but damagelist coords are layer relative! */
1300 _TranslateRect(&rect
,
1301 r
->bounds
.MinX
- l
->bounds
.MinX
,
1302 r
->bounds
.MinY
- l
->bounds
.MinY
);
1304 kprintf("%s: Adding %d/%d-%d/%d to damagelist!\n",
1312 OrRectRegion(l
->DamageList
, &rect
);
1314 _TranslateRect(&rect
,
1315 -r
->bounds
.MinX
+ l
->bounds
.MinX
,
1316 -r
->bounds
.MinY
+ l
->bounds
.MinY
);
1320 } /* while (NULL != RR) */
1323 } /* if (TRUE == addtodamagelist) */
1325 AndRegionRegion(l
->VisibleRegion
, r
);
1328 /* shaperegion is layer relative, while r is screen relative */
1330 _TranslateRect(&r
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
1331 AndRegionRegion(l
->shaperegion
, r
);
1332 _TranslateRect(&r
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
1335 RR
= r
->RegionRectangle
;
1336 /* check if a region is empty */
1339 _TranslateRect(&RR
->bounds
, r
->bounds
.MinX
, r
->bounds
.MinY
);
1342 kprintf("\t\t: %s Clearing rect : %d/%d-%d/%d layer: %p, hook: %p, bitmap: %p\n",
1352 _CallLayerHook(l
->BackFill
,
1364 struct Region
*_InternalInstallClipRegion(struct Layer
*l
, struct Region
*region
,
1365 WORD srcdx
, WORD destdx
,
1366 struct LayersBase
*LayersBase
)
1368 struct Region
* OldRegion
;
1369 BOOL updating
= FALSE
;
1370 OldRegion
= l
->ClipRegion
;
1372 if ((OldRegion
!= NULL
) || (region
!= NULL
))
1374 if (l
->Flags
& LAYERUPDATING
)
1376 /* InstallClipRegion does not work if the layer is in update state (BeginUpdate) */
1379 EndUpdate(l
, FALSE
);
1381 OldRegion
= l
->ClipRegion
;
1384 /* is there a clipregion currently installed? */
1385 if (NULL
!= OldRegion
)
1388 * Copy the contents of the region cliprects to the regular
1389 * cliprects if layer is a SMARTLAYER. Also free the list of
1392 if (NULL
!= l
->ClipRect
)
1394 if (IS_SMARTREFRESH(l
))
1395 _CopyClipRectsToClipRects(l
,
1405 _FreeClipRectListBM(l
, l
->ClipRect
, LayersBase
);
1408 /* restore the regular ClipRects */
1409 l
->ClipRect
= l
->_cliprects
;
1413 /* at this point the regular cliprects are in l->ClipRect in any case !*/
1415 /* if there's no new region to install then there's not much to do */
1416 l
->ClipRegion
= region
;
1419 l
->_cliprects
= NULL
;
1424 /* convert the region to a list of ClipRects */
1425 /* backup the old cliprects */
1426 l
->_cliprects
= l
->ClipRect
;
1428 _TranslateRect(®ion
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
1430 r
= AndRegionRegionND(l
->VisibleRegion
, region
);
1431 AndRegionRegion(l
->shape
, r
);
1433 l
->ClipRect
= _CreateClipRectsFromRegion(r
,
1440 _CopyClipRectsToClipRects(l
,
1448 LayersBase
); /* stegerg: should be FALSE. but that does not work??? */
1450 _TranslateRect(®ion
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
1452 /* right now I am assuming that everything went alright */
1458 } /* if ((OldRegion != NULL) || (region != NULL)) */