2 Copyright © 1995-2011, 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_UFC3(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 */
961 * If this is a simple refresh layer and I am not in
962 * backup mode and I am not adding to the damagelist
963 * the I must call the backfillhook for the
964 * area of the damage list of a simple refresh layer
967 if (IS_SIMPLEREFRESH(l
) &&
968 (l
->Flags
& LAYERREFRESH
) &&
969 FALSE
== backupmode
&&
970 FALSE
== addtodamagelist
)
972 struct Region
* dr
= l
->DamageList
;
973 struct RegionRectangle
* rr
;
975 _TranslateRect(&dr
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
976 AndRectRegion(dr
, &l
->bounds
);
977 AndRegionRegion(l
->VisibleRegion
, dr
);
978 AndRegionRegion(l
->visibleshape
, dr
);
980 _TranslateRect(&dr
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
982 rr
= dr
->RegionRectangle
;
985 _TranslateRect(&rr
->bounds
,
986 dr
->bounds
.MinX
+ l
->bounds
.MinX
,
987 dr
->bounds
.MinY
+ l
->bounds
.MinY
);
989 _CallLayerHook(l
->BackFill
,
997 _TranslateRect(&rr
->bounds
,
998 -dr
->bounds
.MinX
-l
->bounds
.MinX
,
999 -dr
->bounds
.MinY
-l
->bounds
.MinY
);
1009 * Backup any parts of the layer that overlap with the backup_region
1010 * and that are not already backed up. Create the cliprects and
1011 * bitmaps if necessary.
1012 * Assumption: Only visible parts become invisible,
1013 * invisible parts will not become visible.
1015 * This function MUST not manipulate hide_region!!!!
1017 int _BackupPartsOfLayer(struct Layer
* l
,
1018 struct Region
* hide_region
,
1020 int backupsimplerefresh
,
1021 struct LayersBase
* LayersBase
)
1023 struct ClipRect
* newcr
;
1024 struct Region
*r
, * clipregion
;
1027 * Uninstall clipping region. This causes all pixels to
1028 * be copied into the cliprects that cover the complete
1029 * area of the layer.
1032 clipregion
= _InternalInstallClipRegion(l
, NULL
, 0, 0, LayersBase
);
1034 ClearRegionRegion(hide_region
,l
->VisibleRegion
);
1035 r
= AndRegionRegionND(l
->visibleshape
, l
->VisibleRegion
);
1039 newcr
= _CreateClipRectsFromRegion(r
,l
,FALSE
,NULL
,LayersBase
);
1044 _CopyClipRectsToClipRects(l
,
1045 l
->ClipRect
/* source */,
1046 newcr
/* destination */,
1049 backupsimplerefresh
,
1054 l
->ClipRect
= newcr
;
1059 * Reinstall the clipping region. This causes the
1060 * whole visible area of the layer to be copied
1061 * into the clipping regions cliprects. The
1062 * regular list of cliprects is still maintained.
1065 _InternalInstallClipRegion(l
, clipregion
, dx
, dx
, LayersBase
);
1071 * Show any parts of the layer that overlap with the backup_region
1072 * and that are not already show.
1074 * This function MUST not manipulate show_region!!!!
1077 int _ShowPartsOfLayer(struct Layer
* l
,
1078 struct Region
* show_region
,
1079 struct LayersBase
* LayersBase
)
1081 struct ClipRect
* newcr
;
1083 struct Region
* clipregion
;
1085 //kprintf("%s called for %p\n",__FUNCTION__,l);
1088 * If there is a clipping region then the whole
1089 * window is currently backed up in l->ClipRect
1090 * That covers the complete area. I must first
1091 * make these visible, move them back to
1092 * l->_cliprects and recreate the clipping cliprects
1093 * according to the clipregion
1096 if (show_region
== l
->VisibleRegion
)
1097 kprintf("ERROR - same regions!! %s\n",__FUNCTION__
);
1099 clipregion
= InstallClipRegion(l
, NULL
);
1101 OrRegionRegion(show_region
,l
->VisibleRegion
);
1102 r
= AndRegionRegionND(l
->visibleshape
, l
->VisibleRegion
);
1105 newcr
= _CreateClipRectsFromRegion(r
,l
,FALSE
,NULL
,LayersBase
);
1108 _CopyClipRectsToClipRects(l
,
1109 l
->ClipRect
/* source */,
1110 newcr
/* destination */,
1119 l
->ClipRect
= newcr
;
1122 InstallClipRegion(l
, clipregion
);
1127 int _ShowLayer(struct Layer
* l
, struct LayersBase
*LayersBase
)
1130 struct RegionRectangle
* rr
;
1131 struct ClipRect
* prevcr
= NULL
;
1132 struct BitMap
* bm
= l
->rp
->BitMap
;
1133 int invisible
= FALSE
;
1135 r
= AndRegionRegionND(l
->shape
, l
->VisibleRegion
);
1136 AndRegionRegion(l
->parent
->shape
, r
);
1140 rr
= r
->RegionRectangle
;
1144 struct ClipRect
* cr
;
1146 cr
= (struct ClipRect
*)AllocPooled(LayersBase
->lb_ClipRectPool
, sizeof(struct ClipRect
));
1148 //kprintf("\t\tinvisible: %d !!!!!!!!!!!!\n",invisible);
1150 MinX(cr
) = MinX(rr
) + MinX(r
);
1151 MinY(cr
) = MinY(rr
) + MinY(r
);
1152 MaxX(cr
) = MaxX(rr
) + MinX(r
);
1153 MaxY(cr
) = MaxY(rr
) + MinY(r
);
1154 cr
->lobs
= (struct Layer
*)(IPTR
)invisible
;
1156 kprintf("\t\t%s: Created cliprect %d/%d-%d/%d invisible: %d\n",
1171 if (FALSE
== invisible
)
1174 kprintf("\t\tClearing background! %d/%d-%d/%d bitmap: %p\n",
1182 if (IS_SUPERREFRESH(l
))
1184 BltBitMap(l
->SuperBitMap
,
1185 cr
->bounds
.MinX
- l
->bounds
.MinX
,
1186 cr
->bounds
.MinY
- l
->bounds
.MinY
,
1190 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1,
1191 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
1198 _CallLayerHook(l
->BackFill
,
1210 * This part is to be invisible!
1212 if (IS_SMARTREFRESH(l
))
1214 cr
->BitMap
= AllocBitMap(
1215 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1 + 16,
1216 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
1222 * stegerg: the backfill hook should be called for this bitmap!
1223 * But _CallLayerHook always uses rp->BitMap
1231 if (FALSE
== invisible
)
1233 XorRectRegion(r
, &l
->bounds
);
1234 #if !CLIPRECTS_OUTSIDE_OF_SHAPE
1235 AndRegionRegion(l
->shape
, r
);
1249 * It is assumed that the region r is not needed anymore.
1251 void _BackFillRegion(struct Layer
* l
,
1253 int addtodamagelist
,
1254 struct LayersBase
* LayersBase
)
1256 struct RegionRectangle
* RR
;
1258 RR
= r
->RegionRectangle
;
1259 if (NULL
== RR
) return;
1261 if (IS_SIMPLEREFRESH(l
))
1263 /* Only for simple refresh layers, becuase smart refresh layers
1264 may have damage outside of visibleshape, like when being dragged
1267 AndRegionRegion(l
->visibleshape
, r
);
1271 /* Maybe not needed, but to be sure ... */
1273 AndRectRegion(r
, &l
->bounds
);
1277 if (TRUE
== addtodamagelist
)
1279 l
->Flags
|= LAYERREFRESH
;
1282 /* Region coords are screen relative, but damagelist coords are layer relative! */
1284 _TranslateRect(&r
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
1285 OrRegionRegion(r
, l
->DamageList
);
1286 _TranslateRect(&r
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
1291 struct Rectangle rect
= RR
->bounds
;
1293 //kprintf("%s: adding to damagelist!\n",__FUNCTION__);
1295 /* Region coords are screen relative, but damagelist coords are layer relative! */
1297 _TranslateRect(&rect
,
1298 r
->bounds
.MinX
- l
->bounds
.MinX
,
1299 r
->bounds
.MinY
- l
->bounds
.MinY
);
1301 kprintf("%s: Adding %d/%d-%d/%d to damagelist!\n",
1309 OrRectRegion(l
->DamageList
, &rect
);
1311 _TranslateRect(&rect
,
1312 -r
->bounds
.MinX
+ l
->bounds
.MinX
,
1313 -r
->bounds
.MinY
+ l
->bounds
.MinY
);
1317 } /* while (NULL != RR) */
1320 } /* if (TRUE == addtodamagelist) */
1322 AndRegionRegion(l
->VisibleRegion
, r
);
1325 /* shaperegion is layer relative, while r is screen relative */
1327 _TranslateRect(&r
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
1328 AndRegionRegion(l
->shaperegion
, r
);
1329 _TranslateRect(&r
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
1332 RR
= r
->RegionRectangle
;
1333 /* check if a region is empty */
1336 _TranslateRect(&RR
->bounds
, r
->bounds
.MinX
, r
->bounds
.MinY
);
1339 kprintf("\t\t: %s Clearing rect : %d/%d-%d/%d layer: %p, hook: %p, bitmap: %p\n",
1349 _CallLayerHook(l
->BackFill
,
1361 struct Region
*_InternalInstallClipRegion(struct Layer
*l
, struct Region
*region
,
1362 WORD srcdx
, WORD destdx
,
1363 struct LayersBase
*LayersBase
)
1365 struct Region
* OldRegion
;
1366 BOOL updating
= FALSE
;
1367 OldRegion
= l
->ClipRegion
;
1369 if ((OldRegion
!= NULL
) || (region
!= NULL
))
1371 if (l
->Flags
& LAYERUPDATING
)
1373 /* InstallClipRegion does not work if the layer is in update state (BeginUpdate) */
1376 EndUpdate(l
, FALSE
);
1378 OldRegion
= l
->ClipRegion
;
1381 /* is there a clipregion currently installed? */
1382 if (NULL
!= OldRegion
)
1385 * Copy the contents of the region cliprects to the regular
1386 * cliprects if layer is a SMARTLAYER. Also free the list of
1389 if (NULL
!= l
->ClipRect
)
1391 if (IS_SMARTREFRESH(l
))
1392 _CopyClipRectsToClipRects(l
,
1402 _FreeClipRectListBM(l
, l
->ClipRect
, LayersBase
);
1405 /* restore the regular ClipRects */
1406 l
->ClipRect
= l
->_cliprects
;
1410 /* at this point the regular cliprects are in l->ClipRect in any case !*/
1412 /* if there's no new region to install then there's not much to do */
1413 l
->ClipRegion
= region
;
1416 l
->_cliprects
= NULL
;
1421 /* convert the region to a list of ClipRects */
1422 /* backup the old cliprects */
1423 l
->_cliprects
= l
->ClipRect
;
1425 _TranslateRect(®ion
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
1427 r
= AndRegionRegionND(l
->VisibleRegion
, region
);
1428 AndRegionRegion(l
->shape
, r
);
1430 l
->ClipRect
= _CreateClipRectsFromRegion(r
,
1437 _CopyClipRectsToClipRects(l
,
1445 LayersBase
); /* stegerg: should be FALSE. but that does not work??? */
1447 _TranslateRect(®ion
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
1449 /* right now I am assuming that everything went alright */
1455 } /* if ((OldRegion != NULL) || (region != NULL)) */