2 Copyright © 1995-2001, 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 "../graphics/intregions.h"
27 #include "layers_intern.h"
28 #include "basicfuncs.h"
30 #define CLIPRECTS_OUTSIDE_OF_SHAPE 1
49 /***************************************************************************/
51 /***************************************************************************/
53 #define CR2NR_NOBITMAP 0
54 #define CR2NR_BITMAP 1
56 #if !(AROS_FLAVOUR & AROS_FLAVOUR_NATIVE)
58 * These functions cause the infamous "fixed or forbidden register was spilled"
59 * bug/feature in m68k gcc, so these were written straight in asm. They can be
60 * found in config/m68k-native/layers, for the m68k AROSfA target. Other targets,
61 * that use stack passing, can use these versions.
64 void BltRPtoCR(struct RastPort
* rp
,
67 struct LayersBase
* LayersBase
)
73 ALIGN_OFFSET(cr
->bounds
.MinX
), 0,
74 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1,
75 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
82 void BltCRtoRP(struct RastPort
* rp
,
85 struct LayersBase
* LayersBase
)
88 ALIGN_OFFSET(cr
->bounds
.MinX
),
93 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1,
94 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
101 #endif /* if !native */
103 /***************************************************************************/
105 /***************************************************************************/
110 /* struct Rectangle rect; (replaced by the next line!) */
111 WORD MinX
, MinY
, MaxX
, MaxY
;
112 LONG OffsetX
, OffsetY
;
115 void _CallLayerHook(struct Hook
* h
,
116 struct RastPort
* rp
,
118 struct Rectangle
* R
,
121 struct LayersBase
* LayersBase
)
123 struct BitMap
* bm
= rp
->BitMap
;
127 if (IL(L
)->intflags
& INTFLAG_AVOID_BACKFILL
) return;
130 if (h
== LAYERS_BACKFILL
)
132 /* Use default backfill, which means that I will clear the area */
139 R
->MaxX
- R
->MinX
+ 1,
140 R
->MaxY
- R
->MinY
+ 1,
148 if (h
!= LAYERS_NOBACKFILL
)
150 struct layerhookmsg msg
;
156 msg
.OffsetX
= offsetX
;
157 msg
.OffsetY
= offsetY
;
159 AROS_UFC3(void, h
->h_Entry
,
160 AROS_UFCA(struct Hook
*, h
,A0
),
161 AROS_UFCA(struct RastPort
*, rp
,A2
),
162 AROS_UFCA(struct layerhookmsg
*, &msg
,A1
)
169 /***************************************************************************/
171 /***************************************************************************/
174 * Free a layer and all its associated structures
176 void _FreeLayer(struct Layer
* l
, struct LayersBase
*LayersBase
)
178 struct ClipRect
* cr
= l
->ClipRect
, * _cr
;
183 FreeBitMap(cr
->BitMap
);
186 ObtainSemaphore(&LayersBase
->lb_MemLock
);
187 FreePooled(LayersBase
->lb_ClipRectPool
, cr
, sizeof(struct ClipRect
));
188 ReleaseSemaphore(&LayersBase
->lb_MemLock
);
190 FreeMem(cr
, sizeof(struct ClipRect
));
196 * also free all backed up cliprects.
198 cr
= l
->SuperSaveClipRects
;
204 ObtainSemaphore(&LayersBase
->lb_MemLock
);
205 FreePooled(LayersBase
->lb_ClipRectPool
, cr
, sizeof(struct ClipRect
));
206 ReleaseSemaphore(&LayersBase
->lb_MemLock
);
208 FreeMem(cr
, sizeof(struct ClipRect
));
214 DisposeRegion(l
->DamageList
);
215 DisposeRegion(l
->VisibleRegion
);
216 DisposeRegion(l
->shape
);
217 DisposeRegion(l
->visibleshape
);
219 FreeMem(l
, sizeof(struct IntLayer
));
224 /***************************************************************************/
226 /***************************************************************************/
228 /*-------------------------------------------------------------------------*/
230 * Allocate LayerInfo_extra and initialize its resource list. Layers uses
231 * this resource list to keep track of various memory allocations it makes
232 * for the layers. See ResourceNode and ResData in layers_intern.h for the
233 * node structure. See AddLayersResource for more information on the basic
236 BOOL
_AllocExtLayerInfo(struct Layer_Info
* li
, struct LayersBase
*LayersBase
)
238 if(++li
->fatten_count
!= 0)
241 if(!(li
->LayerInfo_extra
= AllocMem(sizeof(struct LayerInfo_extra
),MEMF_PUBLIC
|MEMF_CLEAR
)))
244 NewList((struct List
*)&((struct LayerInfo_extra
*)li
->LayerInfo_extra
)->lie_ResourceList
);
250 * Free LayerInfo_extra.
252 void _FreeExtLayerInfo(struct Layer_Info
* li
, struct LayersBase
*LayersBase
)
254 if(--li
->fatten_count
>= 0)
257 /* Kill Root Layer */
260 DeleteLayer(0UL, li
->check_lp
);
263 if(li
->LayerInfo_extra
== NULL
)
266 FreeMem(li
->LayerInfo_extra
, sizeof(struct LayerInfo_extra
));
268 li
->LayerInfo_extra
= NULL
;
272 * Dynamically allocate LayerInfo_extra if it isn't already there.
274 BOOL
SafeAllocExtLI(struct Layer_Info
* li
,
275 struct LayersBase
* LayersBase
)
279 /* Check to see if we can ignore the rest of this call. :-) */
280 if(li
->Flags
& NEWLAYERINFO_CALLED
)
283 if(_AllocExtLayerInfo(li
, LayersBase
))
292 * Free LayerInfo_extra if it was dynamically allocated, and unlock the LI.
294 void SafeFreeExtLI(struct Layer_Info
* li
,
295 struct LayersBase
* LayersBase
)
297 if(!(li
->Flags
& NEWLAYERINFO_CALLED
))
298 _FreeExtLayerInfo(li
, LayersBase
);
303 /***************************************************************************/
305 /***************************************************************************/
308 #define MAX(a,b) ((a) > (b) ? (a) : (b))
309 #define MIN(a,b) ((a) < (b) ? (a) : (b))
311 void _TranslateRect(struct Rectangle *rect, WORD dx, WORD dy)
320 /***************************************************************************/
321 /* RESOURCE HANDLING */
322 /***************************************************************************/
325 * Allocate memory for a ClipRect.
328 struct ClipRect
* _AllocClipRect(struct Layer
* L
, struct LayersBase
*LayersBase
)
330 struct ClipRect
* CR
;
332 CR
= L
->SuperSaveClipRects
;
336 /* I want to access the list of free ClipRects alone */
337 L
->SuperSaveClipRects
= CR
->Next
;
338 L
->SuperSaveClipRectCounter
--;
348 ObtainSemaphore(&LayersBase
->lb_MemLock
);
349 CR
= (struct ClipRect
*)AllocPooled(LayersBase
->lb_ClipRectPool
, sizeof(struct ClipRect
));
350 ReleaseSemaphore(&LayersBase
->lb_MemLock
);
352 CR
= (struct ClipRect
*) AllocMem(sizeof(struct ClipRect
), MEMF_PUBLIC
|MEMF_CLEAR
);
358 * Return memory of a ClipRect for later use.
361 void _FreeClipRect(struct ClipRect
* CR
,
363 struct LayersBase
* LayersBase
)
365 if (L
->SuperSaveClipRectCounter
< MAXSUPERSAVECLIPRECTS
)
367 /* Add the ClipRect to the front of the list */
368 CR
-> Next
= L
-> SuperSaveClipRects
;
369 L
-> SuperSaveClipRects
= CR
;
370 L
-> SuperSaveClipRectCounter
++;
375 ObtainSemaphore(&LayersBase
->lb_MemLock
);
376 FreePooled(LayersBase
->lb_ClipRectPool
, CR
, sizeof(struct ClipRect
));
377 ReleaseSemaphore(&LayersBase
->lb_MemLock
);
379 FreeMem(CR
, sizeof(struct ClipRect
));
385 * Free a whole list of cliprects including the allocated bitmaps (if any)
388 void _FreeClipRectListBM(struct Layer
* L
,
389 struct ClipRect
* CR
,
390 struct LayersBase
*LayersBase
)
392 struct ClipRect
* _CR
= CR
;
394 if ((L
->Flags
& (LAYERSUPER
|LAYERSMART
)) == LAYERSMART
)
400 * This function is not watching for the upper limit of
401 * pre allocated cliprects.
403 L
->SuperSaveClipRectCounter
++;
407 if (NULL
!= _CR
->BitMap
&& TRUE
== isSmart
)
409 FreeBitMap(_CR
->BitMap
);
412 if (NULL
!= _CR
->Next
)
414 L
->SuperSaveClipRectCounter
++;
420 /* _CR is the last ClipRect in the list. I concatenate the
421 currently preallocated list of ClipRects with that list. */
422 _CR
->Next
= L
->SuperSaveClipRects
;
424 /* CR is the head of the ClipRect list now */
425 L
->SuperSaveClipRects
= CR
;
429 /***************************************************************************/
431 /***************************************************************************/
433 struct ClipRect
* _CreateClipRectsFromRegion(struct Region
*r
,
436 struct Region
* inverter
,
437 struct LayersBase
*LayersBase
)
440 struct ClipRect
* firstcr
= NULL
, * cr
;
441 struct BitMap
* display_bm
= l
->rp
->BitMap
;
444 * From region r create cliprects
448 struct RegionRectangle
* rr
= r
->RegionRectangle
;
451 cr
= _AllocClipRect(l
, LayersBase
);
452 cr
->bounds
.MinX
= rr
->bounds
.MinX
+ r
->bounds
.MinX
;
453 cr
->bounds
.MinY
= rr
->bounds
.MinY
+ r
->bounds
.MinY
;
454 cr
->bounds
.MaxX
= rr
->bounds
.MaxX
+ r
->bounds
.MinX
;
455 cr
->bounds
.MaxY
= rr
->bounds
.MaxY
+ r
->bounds
.MinY
;
456 cr
->lobs
= (struct Layer
*)invisible
;
459 if (TRUE
== invisible
&& IS_SMARTREFRESH(l
))
461 cr
->BitMap
= AllocBitMap(
462 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1 + 16,
463 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
470 kprintf("\t\t%s: Created cliprect %d/%d-%d/%d invisible: %d\n",
487 * Flip the shape to the opposite part and
488 * limit it to its own shape.
491 XorRegionRegion(inverter
, r
);
493 XorRectRegion(r
,&l
->bounds
);
495 #if !CLIPRECTS_OUTSIDE_OF_SHAPE
496 AndRegionRegion(l
->shape
,r
);
498 AndRectRegion(r
,&l
->bounds
);
500 if (TRUE
== invisible
)
514 int _CopyClipRectsToClipRects(struct Layer
* l
,
515 struct ClipRect
* oldcr
,
516 struct ClipRect
* newcr
,
522 struct LayersBase
*LayersBase
)
524 struct BitMap
* display_bm
= l
->rp
->BitMap
;
526 while (NULL
!= oldcr
)
528 struct ClipRect
* _cr
= newcr
;
529 int area
= RECTAREA(&oldcr
->bounds
);
530 while ((NULL
!= _cr
) && (0 != area
) )
532 struct Rectangle intersect
;
535 * Do the two rectangles overlap?
537 if (_AndRectRect(&_cr
->bounds
, &oldcr
->bounds
, &intersect
))
539 LONG xSize
= intersect
.MaxX
- intersect
.MinX
+ 1;
540 LONG ySize
= intersect
.MaxY
- intersect
.MinY
+ 1;
543 * Is this new one supposed to be invisible?
545 if (NULL
!= _cr
->lobs
)
547 struct BitMap
* srcbm
;
549 * The new one is supposed to be invisible.
550 * So for SIMPLEREFRESH layers I don't have to
552 * a) not in backupmode or
553 * b) old cr was invisible
555 if (IS_SIMPLEREFRESH(l
) && FALSE
== backupmode
&& NULL
== _cr
->BitMap
)
557 if (FALSE
== addtodamagelist
)
559 struct Rectangle rect
= intersect
;
561 _TranslateRect(&rect
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
563 #warning: stegerg: Not sure if this is a good idea. What for example if updating is done in several passes? And CopyClipRectsToClipRects is used by all kinds of functions including BeginUpdate/EndUpdate/InstallClipRegion/etc.
564 ClearRectRegion(l
->DamageList
, &rect
);
567 kprintf("%s: Removing %d/%d-%d/%d from damagelist!\t",
574 kprintf("%s: Layer: %d/%d-%d/%d!\n",
581 kprintf("%s: oldcr: %d/%d-%d/%d!\t",
588 kprintf("%s: _cr: %d/%d-%d/%d!\n\n",
598 else if (IS_SIMPLEREFRESH(l
) && TRUE
== backupmode
&& NULL
!= oldcr
->lobs
)
600 if (TRUE
== addtodamagelist
)
602 struct Rectangle rect
= intersect
;
603 _TranslateRect(&rect
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
605 // FIXME (if possible)
606 // !!! Also areas where a child disappears beyond the
607 // boundaries of its parent are added here!
608 OrRectRegion(l
->DamageList
, &rect
);
610 kprintf("_cr->BitMap: %p ,_cr->lobs: %d\n",_cr
->BitMap
,_cr
->lobs
);
613 kprintf("%s: Adding %d/%d-%d/%d to damagelist of l=%p!\t",
623 kprintf("%s: Layer: %d/%d-%d/%d!\n",
630 kprintf("%s: oldcr: %d/%d-%d/%d!\t",
637 kprintf("%s: _cr: %d/%d-%d/%d!\n\n",
646 //kprintf("Not adding to damage list for l=%p!\n",l);
653 struct BitMap
* destbm
;
655 if (IS_SUPERREFRESH(l
))
656 destbm
= l
->SuperBitMap
;
658 destbm
= _cr
->BitMap
;
661 * Does the source rect have a bitmap (off screen)
662 * or is it on the screen.
664 if (oldcr
->lobs
&& !IS_SUPERREFRESH(l
))
667 * Copy from hidden bitmap to hidden bitmap
669 xSrc
= (oldcr
->bounds
.MinX
- _cr
->bounds
.MinX
);
673 * oldcr is further to the left
681 * oldcr is further to the right
687 xSrc
+= ALIGN_OFFSET(oldcr
->bounds
.MinX
+ srcdx
);
688 xDest
+= ALIGN_OFFSET(_cr
->bounds
.MinX
+ destdx
);
690 ySrc
= (oldcr
->bounds
.MinY
- _cr
->bounds
.MinY
);
701 //kprintf("Using old cr's BitMap!\n");
702 srcbm
= oldcr
->BitMap
;
709 if (oldcr
->bounds
.MinX
> _cr
->bounds
.MinX
)
711 xSrc
= oldcr
->bounds
.MinX
;
712 if (IS_SUPERREFRESH(l
))
713 xDest
= (oldcr
->bounds
.MinX
- _cr
->bounds
.MinX
) SCROLLSIGN l
->Scroll_X
;
715 xDest
= (oldcr
->bounds
.MinX
- _cr
->bounds
.MinX
) + ALIGN_OFFSET((_cr
->bounds
.MinX
+ destdx
));
719 xSrc
= _cr
->bounds
.MinX
;
720 if (IS_SUPERREFRESH(l
))
721 xDest
= SCROLLSIGN l
->Scroll_X
;
723 xDest
= ALIGN_OFFSET((_cr
->bounds
.MinX
+ destdx
));
726 if (oldcr
->bounds
.MinY
> _cr
->bounds
.MinY
)
728 ySrc
= oldcr
->bounds
.MinY
;
729 yDest
= oldcr
->bounds
.MinY
- _cr
->bounds
.MinY
;
730 if (IS_SUPERREFRESH(l
))
731 yDest
= yDest SCROLLSIGN l
->Scroll_Y
;
735 ySrc
= _cr
->bounds
.MinY
;
737 if (IS_SUPERREFRESH(l
))
738 yDest
= yDest SCROLLSIGN l
->Scroll_Y
;
741 srcbm
= l
->rp
->BitMap
;
742 //kprintf("Using bitmap of screen!\n");
745 if (IS_SIMPLEREFRESH(l
) &&
746 NULL
== _cr
->BitMap
&&
750 * Get a bitmap (if not there) and make a backup
752 _cr
->BitMap
= AllocBitMap(
753 _cr
->bounds
.MaxX
- _cr
->bounds
.MinX
+ 1 + 16 ,
754 _cr
->bounds
.MaxY
- _cr
->bounds
.MinY
+ 1,
758 destbm
= _cr
->BitMap
;
773 kprintf("%s: backing up: from %d/%d to %d/%d width:%d, height: %d\n",
783 area
-= (xSize
* ySize
);
787 else //if (FALSE == backupmode)
790 * The new one is visible. if the old one was not visible
791 * then I have to show it.
792 * If it is a simple refresh layer and it has it
793 * backed up (only when moving!) then I must show
794 * this. If it has nothing backed up then I must
795 * add a part to the damage list.
797 if (IS_SIMPLEREFRESH(l
) &&
798 (NULL
!= oldcr
->lobs
) &&
799 (NULL
== oldcr
->BitMap
))
801 if (NULL
!= oldcr
->lobs
&& NULL
== oldcr
->BitMap
)
803 struct Rectangle rect
= intersect
;
805 _CallLayerHook(l
->BackFill
,
812 _TranslateRect(&rect
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
813 OrRectRegion(l
->DamageList
, &rect
);
815 kprintf("Adding: %d\n",addtodamagelist
);
816 kprintf("%s: Adding %d/%d-%d/%d to damagelist!\t",
823 kprintf("%s: Layer: %d/%d-%d/%d!\n",
830 kprintf("%s: oldcr: %d/%d-%d/%d!\t",
837 kprintf("%s: _cr: %d/%d-%d/%d!\n",
849 //kprintf("%s: Showing a part of a backed up bitmap!\n",__FUNCTION__);
850 if (NULL
!= oldcr
->lobs
)
853 * Copy out of hidden bitmap
857 struct BitMap
* srcbm
;
859 if (IS_SUPERREFRESH(l
))
860 srcbm
= l
->SuperBitMap
;
862 srcbm
= oldcr
->BitMap
;
865 * I have to make the old one visible
866 * two cases left: SMART REFRESH and SUPERBITMAP
869 if (!IS_SUPERREFRESH(l
))
872 * Copy from hidden BitMap to screen!
873 * If a simple refresh layer is moved it might
874 * also have a BitMap!!!
876 xSrc
= (oldcr
->bounds
.MinX
- _cr
->bounds
.MinX
);
880 * old cr is further to the left
882 xSrc
= -xSrc
+ ALIGN_OFFSET(oldcr
->bounds
.MinX
+ srcdx
);
883 xDest
= _cr
->bounds
.MinX
;
888 * oldcr is further to the right
890 xDest
= oldcr
->bounds
.MinX
;
891 xSrc
= ALIGN_OFFSET(oldcr
->bounds
.MinX
+ srcdx
);
894 ySrc
= (oldcr
->bounds
.MinY
- _cr
->bounds
.MinY
);
898 yDest
= _cr
->bounds
.MinY
;
902 yDest
= oldcr
->bounds
.MinY
;
911 xSrc
= (oldcr
->bounds
.MinX
> _cr
->bounds
.MinX
) ?
912 oldcr
->bounds
.MinX
- _cr
->bounds
.MinX SCROLLSIGN l
->Scroll_X
:
913 _cr
->bounds
.MinX
- oldcr
->bounds
.MinX SCROLLSIGN l
->Scroll_X
;
914 xDest
= _cr
->bounds
.MinX
;
916 ySrc
= (oldcr
->bounds
.MinY
> _cr
->bounds
.MinY
) ?
917 oldcr
->bounds
.MinY
- _cr
->bounds
.MinY SCROLLSIGN l
->Scroll_Y
:
918 _cr
->bounds
.MinY
- oldcr
->bounds
.MinY SCROLLSIGN l
->Scroll_Y
;
919 yDest
= _cr
->bounds
.MinY
;
924 kprintf("\t\t%s: Show cliprect: %d/%d-%d/%d; blitting to %d/%d _cr->lobs: %d\n",
935 #warning Must have oldcr->BitMap also for SuperBitMap layers!
949 } /* if was hidden cliprect */
950 } /* if is simple else ... */
951 } /* if new cliprect is visible or invisible */
952 } /* if rectangles overlap */
956 if (IS_SMARTREFRESH(l
) && TRUE
== backupmode
&& NULL
== _cr
->BitMap
&& NULL
!= _cr
->lobs
)
958 _cr
->BitMap
= AllocBitMap(_cr
->bounds
.MaxX
- _cr
->bounds
.MinX
+ 1 + 16 ,
959 _cr
->bounds
.MaxY
- _cr
->bounds
.MinY
+ 1,
966 } /* all new cliprects */
968 if (TRUE
== freelist
)
972 FreeBitMap(oldcr
->BitMap
);
973 _FreeClipRect(oldcr
, l
, LayersBase
);
978 } /* for all old cliprects */
983 * If this is a simple refresh layer and I am not in
984 * backup mode and I am not adding to the damagelist
985 * the I must call the backfillhook for the
986 * area of the damage list of a simple refresh layer
989 if (IS_SIMPLEREFRESH(l
) &&
990 (l
->Flags
& LAYERREFRESH
) &&
991 FALSE
== backupmode
&&
992 FALSE
== addtodamagelist
)
994 struct Region
* dr
= l
->DamageList
;
995 struct RegionRectangle
* rr
;
997 _TranslateRect(&dr
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
998 AndRectRegion(dr
, &l
->bounds
);
999 AndRegionRegion(l
->VisibleRegion
, dr
);
1000 AndRegionRegion(l
->visibleshape
, dr
);
1002 _TranslateRect(&dr
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
1004 rr
= dr
->RegionRectangle
;
1007 _TranslateRect(&rr
->bounds
,
1008 dr
->bounds
.MinX
+ l
->bounds
.MinX
,
1009 dr
->bounds
.MinY
+ l
->bounds
.MinY
);
1011 _CallLayerHook(l
->BackFill
,
1019 _TranslateRect(&rr
->bounds
,
1020 -dr
->bounds
.MinX
-l
->bounds
.MinX
,
1021 -dr
->bounds
.MinY
-l
->bounds
.MinY
);
1031 * Backup any parts of the layer that overlap with the backup_region
1032 * and that are not already backed up. Create the cliprects and
1033 * bitmaps if necessary.
1034 * Assumption: Only visible parts become invisible,
1035 * invisible parts will not become visible.
1037 * This function MUST not manipulate hide_region!!!!
1039 int _BackupPartsOfLayer(struct Layer
* l
,
1040 struct Region
* hide_region
,
1042 int backupsimplerefresh
,
1043 struct LayersBase
* LayersBase
)
1045 struct ClipRect
* newcr
;
1046 struct Region
*r
, * clipregion
;
1049 * Uninstall clipping region. This causes all pixels to
1050 * be copied into the cliprects that cover the complete
1051 * area of the layer.
1054 clipregion
= _InternalInstallClipRegion(l
, NULL
, 0, 0, LayersBase
);
1056 ClearRegionRegion(hide_region
,l
->VisibleRegion
);
1057 r
= AndRegionRegionND(l
->visibleshape
, l
->VisibleRegion
);
1061 newcr
= _CreateClipRectsFromRegion(r
,l
,FALSE
,NULL
,LayersBase
);
1066 _CopyClipRectsToClipRects(l
,
1067 l
->ClipRect
/* source */,
1068 newcr
/* destination */,
1071 backupsimplerefresh
,
1076 l
->ClipRect
= newcr
;
1081 * Reinstall the clipping region. This causes the
1082 * whole visible area of the layer to be copied
1083 * into the clipping regions cliprects. The
1084 * regular list of cliprects is still maintained.
1087 _InternalInstallClipRegion(l
, clipregion
, dx
, dx
, LayersBase
);
1093 * Show any parts of the layer that overlap with the backup_region
1094 * and that are not already show.
1096 * This function MUST not manipulate show_region!!!!
1099 int _ShowPartsOfLayer(struct Layer
* l
,
1100 struct Region
* show_region
,
1101 struct LayersBase
* LayersBase
)
1103 struct ClipRect
* newcr
;
1105 struct Region
* clipregion
;
1107 //kprintf("%s called for %p\n",__FUNCTION__,l);
1110 * If there is a clipping region then the whole
1111 * window is currently backed up in l->ClipRect
1112 * That covers the complete area. I must first
1113 * make these visible, move them back to
1114 * l->_cliprects and recreate the clipping cliprects
1115 * according to the clipregion
1118 if (show_region
== l
->VisibleRegion
)
1119 kprintf("ERROR - same regions!! %s\n",__FUNCTION__
);
1121 clipregion
= InstallClipRegion(l
, NULL
);
1123 OrRegionRegion(show_region
,l
->VisibleRegion
);
1124 r
= AndRegionRegionND(l
->visibleshape
, l
->VisibleRegion
);
1127 newcr
= _CreateClipRectsFromRegion(r
,l
,FALSE
,NULL
,LayersBase
);
1130 _CopyClipRectsToClipRects(l
,
1131 l
->ClipRect
/* source */,
1132 newcr
/* destination */,
1141 l
->ClipRect
= newcr
;
1144 InstallClipRegion(l
, clipregion
);
1149 int _ShowLayer(struct Layer
* l
, struct LayersBase
*LayersBase
)
1152 struct RegionRectangle
* rr
;
1153 struct ClipRect
* prevcr
= NULL
;
1154 struct BitMap
* bm
= l
->rp
->BitMap
;
1155 int invisible
= FALSE
;
1157 r
= AndRegionRegionND(l
->shape
, l
->VisibleRegion
);
1158 AndRegionRegion(l
->parent
->shape
, r
);
1162 rr
= r
->RegionRectangle
;
1166 struct ClipRect
* cr
;
1169 ObtainSemaphore(&LayersBase
->lb_MemLock
);
1170 cr
= (struct ClipRect
*)AllocPooled(LayersBase
->lb_ClipRectPool
, sizeof(struct ClipRect
));
1171 ReleaseSemaphore(&LayersBase
->lb_MemLock
);
1173 cr
= AllocMem(sizeof(struct ClipRect
), MEMF_CLEAR
);
1176 //kprintf("\t\tinvisible: %d !!!!!!!!!!!!\n",invisible);
1178 MinX(cr
) = MinX(rr
) + MinX(r
);
1179 MinY(cr
) = MinY(rr
) + MinY(r
);
1180 MaxX(cr
) = MaxX(rr
) + MinX(r
);
1181 MaxY(cr
) = MaxY(rr
) + MinY(r
);
1182 cr
->lobs
= (struct Layer
*)invisible
;
1184 kprintf("\t\t%s: Created cliprect %d/%d-%d/%d invisible: %d\n",
1199 if (FALSE
== invisible
)
1202 kprintf("\t\tClearing background! %d/%d-%d/%d bitmap: %p\n",
1210 if (IS_SUPERREFRESH(l
))
1212 BltBitMap(l
->SuperBitMap
,
1213 cr
->bounds
.MinX
- l
->bounds
.MinX
,
1214 cr
->bounds
.MinY
- l
->bounds
.MinY
,
1218 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1,
1219 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
1226 _CallLayerHook(l
->BackFill
,
1238 * This part is to be invisible!
1240 if (IS_SMARTREFRESH(l
))
1242 cr
->BitMap
= AllocBitMap(
1243 cr
->bounds
.MaxX
- cr
->bounds
.MinX
+ 1 + 16,
1244 cr
->bounds
.MaxY
- cr
->bounds
.MinY
+ 1,
1249 #warning stegerg: the backfill hook should be called for this bitmap! But _CallLayerHook always uses rp->BitMap
1256 if (FALSE
== invisible
)
1258 XorRectRegion(r
, &l
->bounds
);
1259 #if !CLIPRECTS_OUTSIDE_OF_SHAPE
1260 AndRegionRegion(l
->shape
, r
);
1274 * It is assumed that the region r is not needed anymore.
1276 void _BackFillRegion(struct Layer
* l
,
1278 int addtodamagelist
,
1279 struct LayersBase
* LayersBase
)
1281 struct RegionRectangle
* RR
;
1283 RR
= r
->RegionRectangle
;
1284 if (NULL
== RR
) return;
1286 if (IS_SIMPLEREFRESH(l
))
1288 /* Only for simple refresh layers, becuase smart refresh layers
1289 may have damage outside of visibleshape, like when being dragged
1292 AndRegionRegion(l
->visibleshape
, r
);
1296 /* Maybe not needed, but to be sure ... */
1298 AndRectRegion(r
, &l
->bounds
);
1302 if (TRUE
== addtodamagelist
)
1304 l
->Flags
|= LAYERREFRESH
;
1307 /* Region coords are screen relative, but damagelist coords are layer relative! */
1309 _TranslateRect(&r
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
1310 OrRegionRegion(r
, l
->DamageList
);
1311 _TranslateRect(&r
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
1316 struct Rectangle rect
= RR
->bounds
;
1318 //kprintf("%s: adding to damagelist!\n",__FUNCTION__);
1320 /* Region coords are screen relative, but damagelist coords are layer relative! */
1322 _TranslateRect(&rect
,
1323 r
->bounds
.MinX
- l
->bounds
.MinX
,
1324 r
->bounds
.MinY
- l
->bounds
.MinY
);
1326 kprintf("%s: Adding %d/%d-%d/%d to damagelist!\n",
1334 OrRectRegion(l
->DamageList
, &rect
);
1336 _TranslateRect(&rect
,
1337 -r
->bounds
.MinX
+ l
->bounds
.MinX
,
1338 -r
->bounds
.MinY
+ l
->bounds
.MinY
);
1342 } /* while (NULL != RR) */
1345 } /* if (TRUE == addtodamagelist) */
1347 AndRegionRegion(l
->VisibleRegion
, r
);
1350 /* shaperegion is layer relative, while r is screen relative */
1352 _TranslateRect(&r
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
1353 AndRegionRegion(l
->shaperegion
, r
);
1354 _TranslateRect(&r
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
1357 RR
= r
->RegionRectangle
;
1358 /* check if a region is empty */
1361 _TranslateRect(&RR
->bounds
, r
->bounds
.MinX
, r
->bounds
.MinY
);
1364 kprintf("\t\t: %s Clearing rect : %d/%d-%d/%d layer: %p, hook: %p, bitmap: %p\n",
1374 _CallLayerHook(l
->BackFill
,
1386 struct Region
*_InternalInstallClipRegion(struct Layer
*l
, struct Region
*region
,
1387 WORD srcdx
, WORD destdx
,
1388 struct LayersBase
*LayersBase
)
1390 struct Region
* OldRegion
;
1391 BOOL updating
= FALSE
;
1392 OldRegion
= l
->ClipRegion
;
1394 if ((OldRegion
!= NULL
) || (region
!= NULL
))
1396 if (l
->Flags
& LAYERUPDATING
)
1398 /* InstallClipRegion does not work if the layer is in update state (BeginUpdate) */
1401 EndUpdate(l
, FALSE
);
1403 OldRegion
= l
->ClipRegion
;
1406 /* is there a clipregion currently installed? */
1407 if (NULL
!= OldRegion
)
1410 * Copy the contents of the region cliprects to the regular
1411 * cliprects if layer is a SMARTLAYER. Also free the list of
1414 if (NULL
!= l
->ClipRect
)
1416 if (IS_SMARTREFRESH(l
))
1417 _CopyClipRectsToClipRects(l
,
1427 _FreeClipRectListBM(l
, l
->ClipRect
, LayersBase
);
1430 /* restore the regular ClipRects */
1431 l
->ClipRect
= l
->_cliprects
;
1435 /* at this point the regular cliprects are in l->ClipRect in any case !*/
1437 /* if there's no new region to install then there's not much to do */
1438 l
->ClipRegion
= region
;
1441 l
->_cliprects
= NULL
;
1446 /* convert the region to a list of ClipRects */
1447 /* backup the old cliprects */
1448 l
->_cliprects
= l
->ClipRect
;
1450 _TranslateRect(®ion
->bounds
, l
->bounds
.MinX
, l
->bounds
.MinY
);
1452 r
= AndRegionRegionND(l
->VisibleRegion
, region
);
1453 AndRegionRegion(l
->shape
, r
);
1455 l
->ClipRect
= _CreateClipRectsFromRegion(r
,
1462 _CopyClipRectsToClipRects(l
,
1470 LayersBase
); /* stegerg: should be FALSE. but that does not work??? */
1472 _TranslateRect(®ion
->bounds
, -l
->bounds
.MinX
, -l
->bounds
.MinY
);
1474 /* right now I am assuming that everything went alright */
1480 } /* if ((OldRegion != NULL) || (region != NULL)) */