2 Copyright 2004-2006, The AROS Development Team. All rights reserved.
6 #define MUIMASTER_YES_INLINE_STDARG
8 #define WANDERER_MODULE_BACKFILL_ENABLED
11 #include <aros/debug.h>
13 #include <exec/types.h>
14 #include <libraries/mui.h>
15 #include <zune/customclasses.h>
17 #include <proto/utility.h>
18 #include <proto/intuition.h>
19 #include <proto/graphics.h>
20 #include <proto/muimaster.h>
21 #include <proto/exec.h>
22 #include <proto/datatypes.h>
25 #include <proto/dos.h>
30 #include <intuition/screens.h>
31 #include <datatypes/pictureclass.h>
32 #include <clib/macros.h>
33 #include <clib/alib_protos.h>
35 #include <graphics/scale.h>
37 #include <prefs/wanderer.h>
40 #include "wandererprefs.h"
41 #include "iconwindow.h"
42 #include "iconwindowcontents.h"
43 #include "iconwindowbackfill.h"
45 #include <prefs/wanderer.h>
47 /*** Global Data **********************************************************/
49 static struct IconWindow_BackFill_Descriptor image_backfill_descriptor
;
50 static char image_backfill_name
[] = "Default Image BackFill\0";
51 static struct List image_backfill_images
;
53 /*** Internal functions *********************************************************/
56 static struct BackFillSourceImageRecord
*ImageBackFill_FindSourceRecord(char *source_name
, IPTR source_mode
)
58 struct BackFillSourceImageRecord
*source_record
= NULL
;
60 ForeachNode(&image_backfill_images
, source_record
)
62 if ((strcmp(source_record
->bfsir_SourceImage
, source_name
)==0) && (source_record
->bfsir_BackGroundRenderMode
== source_mode
)) return source_record
;
67 static struct BackFillSourceImageBuffer
*ImageBackFill_FindBufferRecord(struct BackFillSourceImageRecord
*source_record
, WORD buffer_width
, WORD buffer_height
)
69 struct BackFillSourceImageBuffer
*buffer_record
= NULL
;
71 ForeachNode(&source_record
->bfsir_Buffers
, buffer_record
)
73 if ((buffer_record
->bfsib_BitMapWidth
== buffer_width
) && (buffer_record
->bfsib_BitMapHeight
== buffer_height
)) return buffer_record
;
78 static void ImageBackFill_CloseSourceRecord(struct BackFillSourceImageRecord
*this_Record
)
80 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceRecord()\n"));
81 if (this_Record
->bfsir_OpenerCount
>= 2)
83 this_Record
->bfsir_OpenerCount
-= 1;
84 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceRecord: %d Openers Remaining for '%s'\n", this_Record
->bfsir_OpenerCount
, this_Record
->bfsir_SourceImage
));
89 Remove((struct Node
*)this_Record
);
90 this_Record
->bfsir_OpenerCount
= 0;
92 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceRecord: Closing Record for '%s'\n", this_Record
->bfsir_SourceImage
));
94 this_Record
->bfsir_DTRastPort
->BitMap
= NULL
;
95 FreeRastPort(this_Record
->bfsir_DTRastPort
);
96 DisposeDTObject(this_Record
->bfsir_DTPictureObject
);
97 FreeVec(this_Record
->bfsir_SourceImage
);
98 FreeMem(this_Record
, sizeof(struct BackFillSourceImageRecord
));
102 static void ImageBackFill_CloseSourceBuffer(struct BackFillSourceImageRecord
*this_Record
, struct BackFillSourceImageBuffer
*this_Buffer
)
104 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceBuffer()\n"));
105 if (this_Buffer
->bfsib_OpenerCount
>= 2)
107 this_Buffer
->bfsib_OpenerCount
-= 1;
108 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceBuffer: %d Openers Remaining\n", this_Buffer
->bfsib_OpenerCount
));
113 Remove((struct Node
*)this_Buffer
);
114 this_Buffer
->bfsib_OpenerCount
= 0;
115 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceBuffer: Closing Buffer [%d x %d] of '%s'\n", this_Buffer
->bfsib_BitMapWidth
, this_Buffer
->bfsib_BitMapHeight
, this_Record
->bfsir_SourceImage
));
117 this_Buffer
->bfsib_BitMapRastPort
->BitMap
= NULL
;
118 FreeRastPort(this_Buffer
->bfsib_BitMapRastPort
);
119 FreeBitMap(this_Buffer
->bfsib_BitMap
);
120 FreeMem(this_Buffer
, sizeof(struct BackFillSourceImageBuffer
));
124 static void ImageBackFill_CopyScaledBitMap
126 struct RastPort
*SrcRast
,
127 WORD SrcOffsetX
, WORD SrcOffsetY
,
128 WORD SrcSizeX
, WORD SrcSizeY
,
129 struct RastPort
*DstRast
,
130 struct Rectangle
*DstAreaBounds
,
131 struct Rectangle
*DstFillBounds
,
135 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyScaledBitMap()\n"));
136 struct BitScaleArgs Scale_Args
;
138 Scale_Args
.bsa_SrcX
= SrcOffsetX
;
139 Scale_Args
.bsa_SrcY
= SrcOffsetY
;
140 Scale_Args
.bsa_SrcWidth
= SrcSizeX
;
141 Scale_Args
.bsa_SrcHeight
= SrcSizeY
;
142 Scale_Args
.bsa_XSrcFactor
= SrcSizeX
;
143 Scale_Args
.bsa_YSrcFactor
= SrcSizeY
;
144 Scale_Args
.bsa_DestX
= DstFillBounds
->MinX
;
145 Scale_Args
.bsa_DestY
= DstFillBounds
->MinY
;
146 Scale_Args
.bsa_XDestFactor
= (DstFillBounds
->MaxX
- DstFillBounds
->MinX
) + 1;
147 Scale_Args
.bsa_YDestFactor
= (DstFillBounds
->MaxY
- DstFillBounds
->MinY
) + 1;
149 Scale_Args
.bsa_SrcBitMap
= SrcRast
->BitMap
;
150 Scale_Args
.bsa_DestBitMap
= DstRast
->BitMap
;
152 BitMapScale(&Scale_Args
);
155 static void ImageBackFill_CopyTiledBitMap
157 struct RastPort
*SrcRast
,
158 WORD SrcOffsetX
, WORD SrcOffsetY
,
159 WORD SrcSizeX
, WORD SrcSizeY
,
160 struct RastPort
*DstRast
,
161 struct Rectangle
*DstAreaBounds
,
162 struct Rectangle
*DstFillBounds
,
167 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap(mode %d)\n", blit_MODE
));
169 WORD FirstSizeX
; // the width of the rectangle to blit as the first column
170 WORD FirstSizeY
; // the height of the rectangle to blit as the first row
171 WORD SecondMinX
; // the left edge of the second column
172 WORD SecondMinY
; // the top edge of the second column
173 WORD SecondSizeX
; // the width of the second column
174 WORD SecondSizeY
; // the height of the second column
175 WORD PosX
, PosY
; // used as starting position in the "exponential" blit
176 WORD SizeX
, SizeY
; // used as bitmap size in the "exponential" blit
177 WORD SrcX
, SrcY
; // used as bitmap size in the "exponential" blit
179 struct BitMap
*Src
= SrcRast
->BitMap
;
180 struct BitMap
*Dst
= DstRast
->BitMap
;
182 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: SrcRast @ %x, DstRast @ %x\n", SrcRast
, DstRast
));
184 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds @ %x, FillBounds @ %x\n", DstAreaBounds
, DstFillBounds
));
186 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MinX %d\n", DstAreaBounds
->MinX
));
187 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MinY %d\n", DstAreaBounds
->MinY
));
188 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MaxX %d\n", DstAreaBounds
->MaxX
));
189 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MaxY %d\n", DstAreaBounds
->MaxY
));
190 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds Width %d Height %d\n", (DstAreaBounds
->MaxX
- DstAreaBounds
->MinX
) + 1, (DstAreaBounds
->MaxY
- DstAreaBounds
->MinY
) + 1));
192 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MinX %d\n", DstFillBounds
->MinX
));
193 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MinY %d\n", DstFillBounds
->MinY
));
194 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MaxX %d\n", DstFillBounds
->MaxX
));
195 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MaxY %d\n", DstFillBounds
->MaxY
));
196 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds Width %d Height %d\n", (DstAreaBounds
->MaxX
- DstAreaBounds
->MinX
) + 1, (DstAreaBounds
->MaxY
- DstAreaBounds
->MinY
) + 1));
198 FirstSizeX
= MIN(SrcSizeX
- SrcOffsetX
, RECTSIZEX(DstFillBounds
)); // the width of the first tile, this is either the rest of the tile right to SrcOffsetX or the width of the dest rect, if the rect is narrow
199 SecondMinX
= DstFillBounds
->MinX
+ FirstSizeX
; // the start for the second tile (if used)
200 SecondSizeX
= MIN(SrcOffsetX
, DstFillBounds
->MaxX
-SecondMinX
+ 1); // the width of the second tile (we want the whole tile to be SrcSizeX pixels wide, if we use SrcSizeX-SrcOffsetX pixels for the left part we'll use SrcOffsetX for the right part)
202 FirstSizeY
= MIN(SrcSizeY
- SrcOffsetY
, RECTSIZEY(DstFillBounds
)); // the same values are calculated for y direction
203 SecondMinY
= DstFillBounds
->MinY
+ FirstSizeY
;
204 SecondSizeY
= MIN(SrcOffsetY
, DstFillBounds
->MaxY
- SecondMinY
+ 1);
206 if (blit_MODE
== blit_MODE_Blit
) // blit the first piece of the tile
208 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 1st Tile Part @ %d,%d [%d x %d]\n", DstFillBounds
->MinX
, DstFillBounds
->MinY
, FirstSizeX
, FirstSizeY
));
210 SrcOffsetX
, SrcOffsetY
,
212 DstFillBounds
->MinX
, DstFillBounds
->MinY
,
213 FirstSizeX
, FirstSizeY
,
217 if (SecondSizeX
> 0) // if SrcOffset was 0 or the dest rect was too narrow, we won't need a second column
219 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 2nd Tile Part @ %d,%d [%d x %d]\n", SecondMinX
, DstFillBounds
->MinY
, SecondSizeX
, FirstSizeY
));
223 SecondMinX
, DstFillBounds
->MinY
,
224 SecondSizeX
, FirstSizeY
,
228 if (SecondSizeY
> 0) // is a second row necessary?
230 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 3rd Tile Part @ %d,%d [%d x %d]\n", DstFillBounds
->MinX
, SecondMinY
, FirstSizeX
, SecondSizeY
));
234 DstFillBounds
->MinX
, SecondMinY
,
235 FirstSizeX
, SecondSizeY
,
240 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 4th Tile Part @ %d,%d [%d x %d]\n", SecondMinX
, SecondMinY
, SecondSizeX
, SecondSizeY
));
244 SecondMinX
, SecondMinY
,
245 SecondSizeX
, SecondSizeY
,
253 //Generates the first row of the tiles ....
254 for (PosX
= DstFillBounds
->MinX
+ SrcSizeX
, SizeX
= MIN(SrcSizeX
, (DstFillBounds
->MaxX
- PosX
) + 1);PosX
<= DstFillBounds
->MaxX
;)
257 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: Row 1 Tile %d @ %d,%d [%d x %d]\n", xcount
, PosX
, DstFillBounds
->MinY
, SizeX
, MIN(SrcSizeY
, RECTSIZEY(DstFillBounds
))));
261 DstFillBounds
->MinX
, DstFillBounds
->MinY
,
263 PosX
, DstFillBounds
->MinY
,
264 SizeX
, MIN(SrcSizeY
, RECTSIZEY(DstFillBounds
)),
268 SizeX
= MIN(SrcSizeX
, (DstFillBounds
->MaxX
- PosX
) + 1);
274 // .. now Blit the first row down several times to fill the whole dest rect
275 for (PosY
= DstFillBounds
->MinY
+ SrcSizeY
, SizeY
= MIN(SrcSizeY
, (DstFillBounds
->MaxY
- PosY
) + 1);PosY
<= DstFillBounds
->MaxY
;)
278 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: Row %d @ %d,%d [%d x %d]\n", ycount
, DstFillBounds
->MinX
, PosY
, MIN(SrcSizeX
, RECTSIZEX(DstFillBounds
)), SizeY
));
282 DstFillBounds
->MinX
, DstFillBounds
->MinY
,
284 DstFillBounds
->MinX
, PosY
,
285 MIN(SrcSizeX
, RECTSIZEX(DstFillBounds
)), SizeY
,
289 SizeY
= MIN(SrcSizeY
, (DstFillBounds
->MaxY
- PosY
) + 1);
292 else if (blit_MODE
== blit_MODE_Clip
)
294 for (SrcY
= MOD(SrcOffsetY
+ MOD((DstFillBounds
->MinY
- DstAreaBounds
->MinY
), SrcSizeY
- 1), SrcSizeY
- 1), PosY
= DstFillBounds
->MinY
, SizeY
= MIN((SrcSizeY
- SrcY
), (DstFillBounds
->MaxY
- DstFillBounds
->MinY
) + 1); PosY
<= DstFillBounds
->MaxY
;)
296 for (SrcX
= MOD(SrcOffsetX
+ MOD((DstFillBounds
->MinX
- DstAreaBounds
->MinX
), SrcSizeY
- 1), SrcSizeX
- 1), PosX
= DstFillBounds
->MinX
, SizeX
= MIN((SrcSizeX
- SrcX
), (DstFillBounds
->MaxX
- DstFillBounds
->MinX
) + 1); PosX
<= DstFillBounds
->MaxX
;)
298 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: ClipBlit @ %d,%d [%d x %d]\n", PosX
, PosY
, SizeX
, SizeY
));
307 if (SrcX
!= 0) SrcX
= 0;
310 SizeX
= MIN(SrcSizeX
, (DstFillBounds
->MaxX
- PosX
) + 1);
313 if (SrcY
!= 0) SrcY
= 0;
316 SizeY
= MIN(SrcSizeY
, (DstFillBounds
->MaxY
- PosY
) + 1);
321 /*** Methods ****************************************************************/
323 IPTR ImageBackFill__MUIM_IconWindow_BackFill_ProcessBackground
325 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_ProcessBackground
*message
330 Object
*_IconWindows_PrefsObj
= NULL
,
331 *_IconWindows_WindowObj
= NULL
;
332 Object
*_IconWindows_IconListObj
= NULL
;
334 BOOL options_changed
= FALSE
;
336 IPTR prefs_processing
= 0;
338 IPTR BackGround_Attrib
= 0,
340 BackGround_RenderMode
= 0,
341 BackGround_TileMode
= 0,
342 BackGround_XOffset
= 0,
343 BackGround_YOffset
= 0;
345 struct BackFillInfo
*this_BFI
= message
->BackFill_Data
;
347 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground()\n"));
349 GET(_app(self
), MUIA_Wanderer_Prefs
, &_IconWindows_PrefsObj
);
351 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: PrefsObj @ %x\n", _IconWindows_PrefsObj
));
353 GET(self
, MUIA_IconWindow_Window
, &_IconWindows_WindowObj
);
354 GET(self
, MUIA_IconWindow_IconList
, &_IconWindows_IconListObj
);
356 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: MUIA_IconWindow_Window = %x\n", _IconWindows_WindowObj
));
358 if ((_IconWindows_PrefsObj
== NULL
) || (_IconWindows_WindowObj
== NULL
) || (_IconWindows_IconListObj
== NULL
)) return FALSE
;
360 GET(_IconWindows_PrefsObj
, MUIA_WandererPrefs_Processing
, &prefs_processing
);
363 if (prefs_processing
)
365 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Wanderer Prefs (re)loading detected\n"));
369 GET(_IconWindows_WindowObj
, MUIA_IconWindow_BackgroundAttrib
, &BackGround_Attrib
);
371 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Background Attrib = '%s'\n", BackGround_Attrib
));
373 if (BackGround_Attrib
== NULL
) return FALSE
;
375 if ((BackGround_Base
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
376 BackGround_Attrib
, MUIA_Background
)) == -1)
379 if ((BackGround_RenderMode
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
380 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGRenderMode
)) == -1)
381 BackGround_RenderMode
= IconWindowExt_ImageBackFill_RenderMode_Tiled
;
383 UBYTE
*this_bgtype
= (UBYTE
*)BackGround_Base
;
384 char *this_ImageName
= (char *)(BackGround_Base
+ 2);
386 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: BackFillInfo @ %x\n", this_BFI
));
387 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Background '%s', mode %d\n", BackGround_Base
, BackGround_RenderMode
));
389 if ((this_bgtype
[0] - 48) != 5)
391 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Background is NOT an image - letting our windoclass handle it ..\n"));
393 goto pb_cleanup_buffer
;
396 GET(self
, MUIA_Window_Screen
, &this_BFI
->bfi_Screen
);
397 this_BFI
->bfi_RastPort
= _rp(message
->BackFill_Root
);
399 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Wanderers Screen @ %x, IconWindow RastPort @ %x\n", this_BFI
->bfi_Screen
, this_BFI
->bfi_RastPort
));
401 if (this_BFI
->bfi_Source
)
403 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: BackFillInfo has existing source record @ %x\n", this_BFI
->bfi_Source
));
404 if ((strcmp(this_BFI
->bfi_Source
->bfsir_SourceImage
, this_ImageName
) == 0) && (this_BFI
->bfi_Source
->bfsir_BackGroundRenderMode
== BackGround_RenderMode
))
406 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: existing BackFillInfo Using the same background / mode\n"));
407 goto check_imagebuffer
;
411 if (this_BFI
->bfi_Buffer
)
413 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
414 this_BFI
->bfi_Buffer
= NULL
;
416 ImageBackFill_CloseSourceRecord(this_BFI
->bfi_Source
);
417 this_BFI
->bfi_Source
= NULL
;
421 if (!(this_BFI
->bfi_Source
)) this_BFI
->bfi_Source
= ImageBackFill_FindSourceRecord(this_ImageName
, BackGround_RenderMode
);
423 if (!(this_BFI
->bfi_Source
))
425 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Creating NEW ImageSource Record\n"));
426 if (!(this_BFI
->bfi_Source
= AllocMem(sizeof(struct BackFillSourceImageRecord
), MEMF_CLEAR
|MEMF_PUBLIC
)))
428 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Couldnt allocate enough mem for source record!\n"));
432 if (!(this_BFI
->bfi_Source
->bfsir_SourceImage
= AllocVec(strlen(this_ImageName
) +1, MEMF_CLEAR
|MEMF_PUBLIC
)))
434 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Couldnt allocate enough mem for source image name store\n"));
435 FreeMem(this_BFI
->bfi_Source
, sizeof(struct BackFillSourceImageRecord
));
438 strcpy(this_BFI
->bfi_Source
->bfsir_SourceImage
, this_ImageName
);
440 if (this_BFI
->bfi_Source
->bfsir_DTPictureObject
= NewDTObject(this_BFI
->bfi_Source
->bfsir_SourceImage
,
441 DTA_SourceType
, DTST_FILE
,
442 DTA_GroupID
, GID_PICTURE
,
443 PDTA_DestMode
, PMODE_V43
,
445 PDTA_Screen
, this_BFI
->bfi_Screen
,
446 PDTA_FreeSourceBitMap
, TRUE
,
447 OBP_Precision
, PRECISION_IMAGE
,
450 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Opened Datatype Object @ %x for image '%s'\n", this_BFI
->bfi_Source
->bfsir_DTPictureObject
, this_BFI
->bfi_Source
->bfsir_SourceImage
));
451 if (DoMethod(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, DTM_PROCLAYOUT
, NULL
, 1))
453 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Caused Datatype Object LAYOUT\n"));
455 GetDTAttrs(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, PDTA_BitMapHeader
, &this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
, TAG_DONE
);
456 GetDTAttrs(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, PDTA_DestBitMap
, &this_BFI
->bfi_Source
->bfsir_DTBitMap
, TAG_DONE
);
458 if (!this_BFI
->bfi_Source
->bfsir_DTBitMap
)
459 GetDTAttrs(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, PDTA_BitMap
, &this_BFI
->bfi_Source
->bfsir_DTBitMap
, TAG_DONE
);
461 if (this_BFI
->bfi_Source
->bfsir_DTBitMap
)
463 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Datatype Object BitMap @ %x\n", this_BFI
->bfi_Source
->bfsir_DTBitMap
));
465 if (this_BFI
->bfi_Source
->bfsir_DTRastPort
= CreateRastPort())
467 this_BFI
->bfi_Source
->bfsir_DTRastPort
->BitMap
= this_BFI
->bfi_Source
->bfsir_DTBitMap
;
468 this_BFI
->bfi_Source
->bfsir_BackGroundRenderMode
= BackGround_RenderMode
;
469 this_BFI
->bfi_Source
->bfsir_OpenerCount
= 0x01;
471 NewList(&this_BFI
->bfi_Source
->bfsir_Buffers
);
473 AddTail(&image_backfill_images
, &this_BFI
->bfi_Source
->bfsir_Node
);
474 goto check_imagebuffer
;
477 /* Failed to obtain datatype object's BM */
479 /* Failed to Layout datatype object */
481 /* Failed to open datatype object */
483 if (!this_BFI
->bfi_Source
->bfsir_DTRastPort
)
485 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource RastPort\n"));
489 if (this_BFI
->bfi_Source
->bfsir_DTBitMap
)
491 FreeBitMap(this_BFI
->bfi_Source
->bfsir_DTBitMap
);
492 this_BFI
->bfi_Source
->bfsir_DTBitMap
= NULL
;
497 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource BitMap\n"));
501 if (this_BFI
->bfi_Source
->bfsir_DTPictureObject
)
503 DisposeDTObject(this_BFI
->bfi_Source
->bfsir_DTPictureObject
);
504 this_BFI
->bfi_Source
->bfsir_DTPictureObject
= NULL
;
509 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource Datatype Object\n"));
512 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource Record\n"));
513 if (this_BFI
->bfi_Source
->bfsir_SourceImage
) FreeVec(this_BFI
->bfi_Source
->bfsir_SourceImage
);
514 FreeMem(this_BFI
->bfi_Source
, sizeof(struct BackFillSourceImageRecord
));
515 this_BFI
->bfi_Source
= NULL
;
520 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Using existing ImageSource Record\n"));
521 this_BFI
->bfi_Source
->bfsir_OpenerCount
+= 1;
526 Depth
= GetBitMapAttr(this_BFI
->bfi_Source
->bfsir_DTBitMap
, BMA_DEPTH
);
527 this_BFI
->bfi_CopyWidth
= this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Width
;
528 this_BFI
->bfi_CopyHeight
= this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Height
;
530 switch (BackGround_RenderMode
)
532 case IconWindowExt_ImageBackFill_RenderMode_Scale
:
534 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED mode\n"));
536 this_BFI
->bfi_Options
.bfo_TileMode
= IconWindowExt_ImageBackFill_TileMode_Fixed
;
538 SET(_IconWindows_IconListObj
, MUIA_IconListview_FixedBackground
, TRUE
);
539 SET(_IconWindows_IconListObj
, MUIA_IconListview_ScaledBackground
, TRUE
);
541 if ((BOOL
)XGET(self
, MUIA_IconWindow_IsRoot
))
543 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Root Window = TRUE!\n"));
544 this_BFI
->bfi_CopyWidth
= GetBitMapAttr(this_BFI
->bfi_Screen
->RastPort
.BitMap
, BMA_WIDTH
);
545 this_BFI
->bfi_CopyHeight
= GetBitMapAttr(this_BFI
->bfi_Screen
->RastPort
.BitMap
, BMA_HEIGHT
);
547 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Base Dimensions (%d x %d)\n", this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
));
549 if (!((BOOL
)XGET(self
, MUIA_IconWindow_IsBackdrop
)))
551 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Adjusting for window border Dimensions ..\n"));
552 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - WBorTop %d, WBorLeft %d, WBorRight %d, WBorBottom %d\n", this_BFI
->bfi_Screen
->WBorTop
, this_BFI
->bfi_Screen
->WBorLeft
, this_BFI
->bfi_Screen
->WBorRight
, this_BFI
->bfi_Screen
->WBorBottom
));
553 this_BFI
->bfi_CopyWidth
-= (this_BFI
->bfi_Screen
->WBorLeft
+ this_BFI
->bfi_Screen
->WBorRight
);
554 this_BFI
->bfi_CopyHeight
-= (this_BFI
->bfi_Screen
->WBorTop
+ this_BFI
->bfi_Screen
->WBorBottom
);;
557 this_BFI
->bfi_CopyHeight
-= (this_BFI
->bfi_Screen
->BarHeight
+ 1);
559 struct BackFillSourceImageBuffer
*this_Buffer
= NULL
;
561 if (this_BFI
->bfi_Buffer
)
563 if ((this_BFI
->bfi_Buffer
->bfsib_BitMapWidth
== this_BFI
->bfi_CopyWidth
) && (this_BFI
->bfi_Buffer
->bfsib_BitMapHeight
== this_BFI
->bfi_CopyHeight
))
565 goto pb_backfillsetup_complete
;
569 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
570 this_BFI
->bfi_Buffer
= NULL
;
574 if (!(this_Buffer
= ImageBackFill_FindBufferRecord(this_BFI
->bfi_Source
, this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
)))
576 this_Buffer
= AllocMem(sizeof(struct BackFillSourceImageBuffer
), MEMF_CLEAR
|MEMF_PUBLIC
);
577 this_Buffer
->bfsib_BitMapWidth
= this_BFI
->bfi_CopyWidth
;
578 this_Buffer
->bfsib_BitMapHeight
= this_BFI
->bfi_CopyHeight
;
580 if (!(this_Buffer
->bfsib_BitMapRastPort
= CreateRastPort()))
582 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Failed to create RastPort for BackFill BitMap\n"));
586 if (this_Buffer
->bfsib_BitMap
= AllocBitMap(this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
, Depth
, Depth
== 8 ? BMF_MINPLANES
: 0L, this_BFI
->bfi_Screen
->RastPort
.BitMap
))
589 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Scale Dimensions (%d x %d)\n", this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
));
591 struct Rectangle CopyBounds
;
593 this_Buffer
->bfsib_BitMapRastPort
->BitMap
= this_Buffer
->bfsib_BitMap
;
594 this_BFI
->bfi_Buffer
= this_Buffer
;
598 CopyBounds
.MaxX
= this_BFI
->bfi_CopyWidth
- 1;
599 CopyBounds
.MaxY
= this_BFI
->bfi_CopyHeight
- 1;
602 ImageBackFill_CopyScaledBitMap(this_BFI
->bfi_Source
->bfsir_DTRastPort
,
604 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Width
,
605 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Height
,
606 this_Buffer
->bfsib_BitMapRastPort
,
607 &CopyBounds
, &CopyBounds
, blit_MODE_Blit
);
609 this_Buffer
->bfsib_OpenerCount
= 0x01;
611 AddTail(&this_BFI
->bfi_Source
->bfsir_Buffers
, &this_Buffer
->bfsib_Node
);
613 goto pb_backfillsetup_complete
;
619 this_BFI
->bfi_Buffer
= this_Buffer
;
620 this_Buffer
->bfsib_OpenerCount
+= 1;
621 goto pb_backfillsetup_complete
;
624 // We arent the "ROOT" (desktop) window so only tile ...
625 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Drawer window scaling unsupported ...\n"));
629 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: TILED mode\n"));
630 if ((BackGround_TileMode
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
631 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGTileMode
)) == -1)
632 BackGround_TileMode
= IconWindowExt_ImageBackFill_TileMode_Float
;
634 if ((BackGround_XOffset
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
635 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGXOffset
)) == -1)
636 BackGround_XOffset
= 0;
638 if ((BackGround_YOffset
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
639 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGYOffset
)) == -1)
640 this_BFI
->bfi_Options
.bfo_OffsetY
= 0;
642 if (this_BFI
->bfi_Options
.bfo_TileMode
!= BackGround_TileMode
)
644 this_BFI
->bfi_Options
.bfo_TileMode
= BackGround_TileMode
;
645 options_changed
= TRUE
;
648 if (this_BFI
->bfi_Options
.bfo_OffsetX
!= BackGround_XOffset
)
650 this_BFI
->bfi_Options
.bfo_OffsetX
= BackGround_XOffset
;
651 options_changed
= TRUE
;
654 if (this_BFI
->bfi_Options
.bfo_OffsetY
!= BackGround_YOffset
)
656 this_BFI
->bfi_Options
.bfo_OffsetY
= BackGround_YOffset
;
657 options_changed
= TRUE
;
660 if (this_BFI
->bfi_Options
.bfo_TileMode
== IconWindowExt_ImageBackFill_TileMode_Float
)
661 SET(_IconWindows_IconListObj
, MUIA_IconListview_FixedBackground
, FALSE
);
663 SET(_IconWindows_IconListObj
, MUIA_IconListview_FixedBackground
, TRUE
);
665 SET(_IconWindows_IconListObj
, MUIA_IconListview_ScaledBackground
, FALSE
);
667 struct BackFillSourceImageBuffer
*this_Buffer
= NULL
;
669 if (this_BFI
->bfi_Buffer
)
671 if ((this_BFI
->bfi_Buffer
->bfsib_BitMapWidth
== this_BFI
->bfi_CopyWidth
) && (this_BFI
->bfi_Buffer
->bfsib_BitMapHeight
== this_BFI
->bfi_CopyHeight
))
673 goto pb_backfillsetup_complete
;
677 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
678 this_BFI
->bfi_Buffer
= NULL
;
682 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Dimensions Width %d, Height %d\n", this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
));
684 if (!(this_Buffer
= ImageBackFill_FindBufferRecord(this_BFI
->bfi_Source
, this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
)))
686 this_Buffer
= AllocMem(sizeof(struct BackFillSourceImageBuffer
), MEMF_CLEAR
|MEMF_PUBLIC
);
687 this_Buffer
->bfsib_BitMapWidth
= this_BFI
->bfi_CopyWidth
;
688 this_Buffer
->bfsib_BitMapHeight
= this_BFI
->bfi_CopyHeight
;
690 if (this_Buffer
->bfsib_BitMap
= AllocBitMap(this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
, Depth
, Depth
== 8 ? BMF_MINPLANES
: 0L, this_BFI
->bfi_Screen
->RastPort
.BitMap
))
692 struct Rectangle CopyBounds
;
694 if (!(this_Buffer
->bfsib_BitMapRastPort
= CreateRastPort()))
696 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: TILED - Failed to create RastPort for BackFill BitMap\n"));
700 this_Buffer
->bfsib_BitMapRastPort
->BitMap
= this_Buffer
->bfsib_BitMap
;
701 this_BFI
->bfi_Buffer
= this_Buffer
;
705 CopyBounds
.MaxX
= this_BFI
->bfi_CopyWidth
- 1;
706 CopyBounds
.MaxY
= this_BFI
->bfi_CopyHeight
- 1;
708 ImageBackFill_CopyTiledBitMap(this_BFI
->bfi_Source
->bfsir_DTRastPort
,
710 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Width
,
711 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Height
,
712 this_BFI
->bfi_Buffer
->bfsib_BitMapRastPort
,
713 &CopyBounds
, &CopyBounds
, blit_MODE_Blit
);
715 this_Buffer
->bfsib_OpenerCount
= 0x01;
717 AddTail(&this_BFI
->bfi_Source
->bfsir_Buffers
, &this_BFI
->bfi_Buffer
->bfsib_Node
);
719 goto pb_backfillsetup_complete
;
725 this_BFI
->bfi_Buffer
= this_Buffer
;
726 this_Buffer
->bfsib_OpenerCount
+= 1;
727 goto pb_backfillsetup_complete
;
732 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create image datatype object\n"));
736 if (this_BFI
->bfi_Buffer
)
738 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
739 this_BFI
->bfi_Buffer
= NULL
;
743 if (this_BFI
->bfi_Source
)
745 ImageBackFill_CloseSourceRecord(this_BFI
->bfi_Source
);
746 this_BFI
->bfi_Source
= NULL
;
751 pb_backfillsetup_complete
:
752 if ((prefs_processing
) && (options_changed
))
753 SET(self
, MUIA_IconWindow_Changed
, TRUE
);
758 IPTR ImageBackFill__MUIM_IconWindow_BackFill_Setup
760 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_Setup
*message
763 struct BackFillInfo
*this_BFI
= NULL
;
765 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Setup()\n"));
767 this_BFI
= AllocVec(sizeof(struct BackFillInfo
), MEMF_CLEAR
|MEMF_PUBLIC
);
768 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Setup: Allocated BackFillInfo @ %x\n", this_BFI
));
773 IPTR ImageBackFill__MUIM_IconWindow_BackFill_Cleanup
775 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_Cleanup
*message
778 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Cleanup()\n"));
779 struct BackFillInfo
*this_BFI
= message
->BackFill_Data
;
781 if (this_BFI
->bfi_Buffer
)
783 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
784 this_BFI
->bfi_Buffer
= NULL
;
786 if (this_BFI
->bfi_Source
)
788 ImageBackFill_CloseSourceRecord(this_BFI
->bfi_Source
);
789 this_BFI
->bfi_Source
= NULL
;
796 IPTR ImageBackFill__MUIM_IconWindow_BackFill_DrawBackground
798 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_DrawBackground
*message
801 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground()\n"));
802 struct BackFillInfo
*this_BFI
= NULL
;
804 if ((this_BFI
= message
->BackFill_Data
) != NULL
)
806 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Got BackFill_Data @ %x\n", this_BFI
));
807 this_BFI
->bfi_RastPort
= message
->draw_RastPort
;
809 if ((this_BFI
->bfi_Buffer
) && (this_BFI
->bfi_RastPort
))
811 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: BackFill_Data has suitable Buffer and RastPort ..\n"));
812 #warning "TODO: Make Base Tile Offset preference settable"
813 WORD OffsetX
= this_BFI
->bfi_Options
.bfo_OffsetX
; // the offset within the tile in x direction
814 WORD OffsetY
= this_BFI
->bfi_Options
.bfo_OffsetY
; // the offset within the tile in y direction
816 if (this_BFI
->bfi_Options
.bfo_TileMode
== IconWindowExt_ImageBackFill_TileMode_Float
)
818 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Rendering using floating backdrop mode\n"));
819 OffsetX
+= message
->draw_BFM
->OffsetX
;
820 OffsetY
+= message
->draw_BFM
->OffsetY
;
823 ImageBackFill_CopyTiledBitMap(this_BFI
->bfi_Buffer
->bfsib_BitMapRastPort
,
825 this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
,
826 this_BFI
->bfi_RastPort
,
827 &message
->draw_BFM
->AreaBounds
,
828 &message
->draw_BFM
->DrawBounds
,
834 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Causing parent to render .. \n"));
838 /*** SPECIAL : Early Setup ****************************************************************/
840 IPTR
ImageBackFill__SetupClass()
842 struct MUIP_IconWindow_BackFill_Register message
;
844 D(bug("[IconWindow.ImageBackFill] ImageBackFill__SetupClass()\n"));
846 image_backfill_descriptor
.bfd_BackFillID
= image_backfill_name
;
848 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_Setup
= ImageBackFill__MUIM_IconWindow_BackFill_Setup
;
849 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_Cleanup
= ImageBackFill__MUIM_IconWindow_BackFill_Cleanup
;
850 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_ProcessBackground
= ImageBackFill__MUIM_IconWindow_BackFill_ProcessBackground
;
851 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_DrawBackground
= ImageBackFill__MUIM_IconWindow_BackFill_DrawBackground
;
853 message
.register_Node
= &image_backfill_descriptor
;
855 NewList(&image_backfill_images
);
857 #if defined(WANDERER_MODULE_BACKFILL_ENABLED)
858 IconWindow__MUIM_IconWindow_BackFill_Register(NULL
, NULL
, &message
);
864 /* Make sure and run _AFTER_ IconWindow__SetupClass() */
865 ADD2INIT(ImageBackFill__SetupClass
, 10);