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"
44 #include "../../libs/muimaster/classes/iconlist_attributes.h"
46 #include <prefs/wanderer.h>
48 /*** Global Data **********************************************************/
50 static struct IconWindow_BackFill_Descriptor image_backfill_descriptor
;
51 static char image_backfill_name
[] = "Default Image BackFill\0";
52 static struct List image_backfill_images
;
54 /*** Internal functions *********************************************************/
57 static struct BackFillSourceImageRecord
*ImageBackFill_FindSourceRecord(char *source_name
, IPTR source_mode
)
59 struct BackFillSourceImageRecord
*source_record
= NULL
;
61 ForeachNode(&image_backfill_images
, source_record
)
63 if ((strcmp(source_record
->bfsir_SourceImage
, source_name
)==0) && (source_record
->bfsir_BackGroundRenderMode
== source_mode
)) return source_record
;
68 static struct BackFillSourceImageBuffer
*ImageBackFill_FindBufferRecord(struct BackFillSourceImageRecord
*source_record
, WORD buffer_width
, WORD buffer_height
)
70 struct BackFillSourceImageBuffer
*buffer_record
= NULL
;
72 ForeachNode(&source_record
->bfsir_Buffers
, buffer_record
)
74 if ((buffer_record
->bfsib_BitMapWidth
== buffer_width
) && (buffer_record
->bfsib_BitMapHeight
== buffer_height
)) return buffer_record
;
79 static void ImageBackFill_CloseSourceRecord(struct BackFillSourceImageRecord
*this_Record
)
81 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceRecord()\n"));
82 if (this_Record
->bfsir_OpenerCount
>= 2)
84 this_Record
->bfsir_OpenerCount
-= 1;
85 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceRecord: %d Openers Remaining for '%s'\n", this_Record
->bfsir_OpenerCount
, this_Record
->bfsir_SourceImage
));
90 Remove((struct Node
*)this_Record
);
91 this_Record
->bfsir_OpenerCount
= 0;
93 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceRecord: Closing Record for '%s'\n", this_Record
->bfsir_SourceImage
));
95 this_Record
->bfsir_DTRastPort
->BitMap
= NULL
;
96 FreeRastPort(this_Record
->bfsir_DTRastPort
);
97 DisposeDTObject(this_Record
->bfsir_DTPictureObject
);
98 FreeVec(this_Record
->bfsir_SourceImage
);
99 FreeMem(this_Record
, sizeof(struct BackFillSourceImageRecord
));
103 static void ImageBackFill_CloseSourceBuffer(struct BackFillSourceImageRecord
*this_Record
, struct BackFillSourceImageBuffer
*this_Buffer
)
105 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceBuffer()\n"));
106 if (this_Buffer
->bfsib_OpenerCount
>= 2)
108 this_Buffer
->bfsib_OpenerCount
-= 1;
109 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceBuffer: %d Openers Remaining\n", this_Buffer
->bfsib_OpenerCount
));
114 Remove((struct Node
*)this_Buffer
);
115 this_Buffer
->bfsib_OpenerCount
= 0;
116 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
));
118 this_Buffer
->bfsib_BitMapRastPort
->BitMap
= NULL
;
119 FreeRastPort(this_Buffer
->bfsib_BitMapRastPort
);
120 FreeBitMap(this_Buffer
->bfsib_BitMap
);
121 FreeMem(this_Buffer
, sizeof(struct BackFillSourceImageBuffer
));
125 static void ImageBackFill_CopyScaledBitMap
127 struct RastPort
*SrcRast
,
128 WORD SrcOffsetX
, WORD SrcOffsetY
,
129 WORD SrcSizeX
, WORD SrcSizeY
,
130 struct RastPort
*DstRast
,
131 struct Rectangle
*DstAreaBounds
,
132 struct Rectangle
*DstFillBounds
,
136 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyScaledBitMap()\n"));
137 struct BitScaleArgs Scale_Args
;
139 Scale_Args
.bsa_SrcX
= SrcOffsetX
;
140 Scale_Args
.bsa_SrcY
= SrcOffsetY
;
141 Scale_Args
.bsa_SrcWidth
= SrcSizeX
;
142 Scale_Args
.bsa_SrcHeight
= SrcSizeY
;
143 Scale_Args
.bsa_XSrcFactor
= SrcSizeX
;
144 Scale_Args
.bsa_YSrcFactor
= SrcSizeY
;
145 Scale_Args
.bsa_DestX
= DstFillBounds
->MinX
;
146 Scale_Args
.bsa_DestY
= DstFillBounds
->MinY
;
147 Scale_Args
.bsa_XDestFactor
= (DstFillBounds
->MaxX
- DstFillBounds
->MinX
) + 1;
148 Scale_Args
.bsa_YDestFactor
= (DstFillBounds
->MaxY
- DstFillBounds
->MinY
) + 1;
150 Scale_Args
.bsa_SrcBitMap
= SrcRast
->BitMap
;
151 Scale_Args
.bsa_DestBitMap
= DstRast
->BitMap
;
153 BitMapScale(&Scale_Args
);
156 static void ImageBackFill_CopyTiledBitMap
158 struct RastPort
*SrcRast
,
159 WORD SrcOffsetX
, WORD SrcOffsetY
,
160 WORD SrcSizeX
, WORD SrcSizeY
,
161 struct RastPort
*DstRast
,
162 struct Rectangle
*DstAreaBounds
,
163 struct Rectangle
*DstFillBounds
,
168 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap(mode %d)\n", blit_MODE
));
170 WORD FirstSizeX
; // the width of the rectangle to blit as the first column
171 WORD FirstSizeY
; // the height of the rectangle to blit as the first row
172 WORD SecondMinX
; // the left edge of the second column
173 WORD SecondMinY
; // the top edge of the second column
174 WORD SecondSizeX
; // the width of the second column
175 WORD SecondSizeY
; // the height of the second column
176 WORD PosX
, PosY
; // used as starting position in the "exponential" blit
177 WORD SizeX
, SizeY
; // used as bitmap size in the "exponential" blit
178 WORD SrcX
, SrcY
; // used as bitmap size in the "exponential" blit
180 struct BitMap
*Src
= SrcRast
->BitMap
;
181 struct BitMap
*Dst
= DstRast
->BitMap
;
183 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: SrcRast @ %x, DstRast @ %x\n", SrcRast
, DstRast
));
185 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds @ %x, FillBounds @ %x\n", DstAreaBounds
, DstFillBounds
));
187 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MinX %d\n", DstAreaBounds
->MinX
));
188 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MinY %d\n", DstAreaBounds
->MinY
));
189 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MaxX %d\n", DstAreaBounds
->MaxX
));
190 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MaxY %d\n", DstAreaBounds
->MaxY
));
191 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds Width %d Height %d\n", (DstAreaBounds
->MaxX
- DstAreaBounds
->MinX
) + 1, (DstAreaBounds
->MaxY
- DstAreaBounds
->MinY
) + 1));
193 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MinX %d\n", DstFillBounds
->MinX
));
194 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MinY %d\n", DstFillBounds
->MinY
));
195 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MaxX %d\n", DstFillBounds
->MaxX
));
196 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MaxY %d\n", DstFillBounds
->MaxY
));
197 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds Width %d Height %d\n", (DstAreaBounds
->MaxX
- DstAreaBounds
->MinX
) + 1, (DstAreaBounds
->MaxY
- DstAreaBounds
->MinY
) + 1));
199 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
200 SecondMinX
= DstFillBounds
->MinX
+ FirstSizeX
; // the start for the second tile (if used)
201 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)
203 FirstSizeY
= MIN(SrcSizeY
- SrcOffsetY
, RECTSIZEY(DstFillBounds
)); // the same values are calculated for y direction
204 SecondMinY
= DstFillBounds
->MinY
+ FirstSizeY
;
205 SecondSizeY
= MIN(SrcOffsetY
, DstFillBounds
->MaxY
- SecondMinY
+ 1);
207 if (blit_MODE
== blit_MODE_Blit
) // blit the first piece of the tile
209 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 1st Tile Part @ %d,%d [%d x %d]\n", DstFillBounds
->MinX
, DstFillBounds
->MinY
, FirstSizeX
, FirstSizeY
));
211 SrcOffsetX
, SrcOffsetY
,
213 DstFillBounds
->MinX
, DstFillBounds
->MinY
,
214 FirstSizeX
, FirstSizeY
,
218 if (SecondSizeX
> 0) // if SrcOffset was 0 or the dest rect was too narrow, we won't need a second column
220 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 2nd Tile Part @ %d,%d [%d x %d]\n", SecondMinX
, DstFillBounds
->MinY
, SecondSizeX
, FirstSizeY
));
224 SecondMinX
, DstFillBounds
->MinY
,
225 SecondSizeX
, FirstSizeY
,
229 if (SecondSizeY
> 0) // is a second row necessary?
231 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 3rd Tile Part @ %d,%d [%d x %d]\n", DstFillBounds
->MinX
, SecondMinY
, FirstSizeX
, SecondSizeY
));
235 DstFillBounds
->MinX
, SecondMinY
,
236 FirstSizeX
, SecondSizeY
,
241 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 4th Tile Part @ %d,%d [%d x %d]\n", SecondMinX
, SecondMinY
, SecondSizeX
, SecondSizeY
));
245 SecondMinX
, SecondMinY
,
246 SecondSizeX
, SecondSizeY
,
254 //Generates the first row of the tiles ....
255 for (PosX
= DstFillBounds
->MinX
+ SrcSizeX
, SizeX
= MIN(SrcSizeX
, (DstFillBounds
->MaxX
- PosX
) + 1);PosX
<= DstFillBounds
->MaxX
;)
258 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
))));
262 DstFillBounds
->MinX
, DstFillBounds
->MinY
,
264 PosX
, DstFillBounds
->MinY
,
265 SizeX
, MIN(SrcSizeY
, RECTSIZEY(DstFillBounds
)),
269 SizeX
= MIN(SrcSizeX
, (DstFillBounds
->MaxX
- PosX
) + 1);
275 // .. now Blit the first row down several times to fill the whole dest rect
276 for (PosY
= DstFillBounds
->MinY
+ SrcSizeY
, SizeY
= MIN(SrcSizeY
, (DstFillBounds
->MaxY
- PosY
) + 1);PosY
<= DstFillBounds
->MaxY
;)
279 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: Row %d @ %d,%d [%d x %d]\n", ycount
, DstFillBounds
->MinX
, PosY
, MIN(SrcSizeX
, RECTSIZEX(DstFillBounds
)), SizeY
));
283 DstFillBounds
->MinX
, DstFillBounds
->MinY
,
285 DstFillBounds
->MinX
, PosY
,
286 MIN(SrcSizeX
, RECTSIZEX(DstFillBounds
)), SizeY
,
290 SizeY
= MIN(SrcSizeY
, (DstFillBounds
->MaxY
- PosY
) + 1);
293 else if (blit_MODE
== blit_MODE_Clip
)
295 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
;)
297 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
;)
299 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: ClipBlit @ %d,%d [%d x %d]\n", PosX
, PosY
, SizeX
, SizeY
));
308 if (SrcX
!= 0) SrcX
= 0;
311 SizeX
= MIN(SrcSizeX
, (DstFillBounds
->MaxX
- PosX
) + 1);
314 if (SrcY
!= 0) SrcY
= 0;
317 SizeY
= MIN(SrcSizeY
, (DstFillBounds
->MaxY
- PosY
) + 1);
322 /*** Methods ****************************************************************/
324 IPTR ImageBackFill__MUIM_IconWindow_BackFill_ProcessBackground
326 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_ProcessBackground
*message
331 Object
*_IconWindows_PrefsObj
= NULL
,
332 *_IconWindows_WindowObj
= NULL
;
333 Object
*_IconWindows_IconListObj
= NULL
;
335 BOOL options_changed
= FALSE
;
337 IPTR prefs_processing
= 0;
339 IPTR BackGround_Attrib
= 0,
341 BackGround_RenderMode
= 0,
342 BackGround_TileMode
= 0,
343 BackGround_XOffset
= 0,
344 BackGround_YOffset
= 0;
346 struct BackFillInfo
*this_BFI
= message
->BackFill_Data
;
348 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground()\n"));
350 GET(_app(self
), MUIA_Wanderer_Prefs
, &_IconWindows_PrefsObj
);
352 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: PrefsObj @ %x\n", _IconWindows_PrefsObj
));
354 GET(self
, MUIA_IconWindow_Window
, &_IconWindows_WindowObj
);
355 GET(self
, MUIA_IconWindow_IconList
, &_IconWindows_IconListObj
);
357 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: MUIA_IconWindow_Window = %x\n", _IconWindows_WindowObj
));
359 if ((_IconWindows_PrefsObj
== NULL
) || (_IconWindows_WindowObj
== NULL
) || (_IconWindows_IconListObj
== NULL
)) return FALSE
;
361 GET(_IconWindows_PrefsObj
, MUIA_WandererPrefs_Processing
, &prefs_processing
);
364 if (prefs_processing
)
366 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Wanderer Prefs (re)loading detected\n"));
370 GET(_IconWindows_WindowObj
, MUIA_IconWindow_BackgroundAttrib
, &BackGround_Attrib
);
372 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Background Attrib = '%s'\n", BackGround_Attrib
));
374 if (BackGround_Attrib
== NULL
) return FALSE
;
376 if ((BackGround_Base
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
377 BackGround_Attrib
, MUIA_Background
)) == -1)
380 if ((BackGround_RenderMode
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
381 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGRenderMode
)) == -1)
382 BackGround_RenderMode
= IconWindowExt_ImageBackFill_RenderMode_Tiled
;
384 UBYTE
*this_bgtype
= (UBYTE
*)BackGround_Base
;
385 char *this_ImageName
= (char *)(BackGround_Base
+ 2);
387 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: BackFillInfo @ %x\n", this_BFI
));
388 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Background '%s', mode %d\n", BackGround_Base
, BackGround_RenderMode
));
390 if ((this_bgtype
[0] - 48) != 5)
392 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Background is NOT an image - letting our windoclass handle it ..\n"));
394 goto pb_cleanup_buffer
;
397 GET(self
, MUIA_Window_Screen
, &this_BFI
->bfi_Screen
);
398 GET(_IconWindows_IconListObj
, MUIA_IconList_BufferRastport
, &this_BFI
->bfi_RastPort
);
400 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Wanderers Screen @ %x, Using RastPort @ %x\n", this_BFI
->bfi_Screen
, this_BFI
->bfi_RastPort
));
402 if (this_BFI
->bfi_Source
)
404 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: BackFillInfo has existing source record @ %x\n", this_BFI
->bfi_Source
));
405 if ((strcmp(this_BFI
->bfi_Source
->bfsir_SourceImage
, this_ImageName
) == 0) && (this_BFI
->bfi_Source
->bfsir_BackGroundRenderMode
== BackGround_RenderMode
))
407 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: existing BackFillInfo Using the same background / mode\n"));
408 goto check_imagebuffer
;
412 if (this_BFI
->bfi_Buffer
)
414 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
415 this_BFI
->bfi_Buffer
= NULL
;
417 ImageBackFill_CloseSourceRecord(this_BFI
->bfi_Source
);
418 this_BFI
->bfi_Source
= NULL
;
422 if (!(this_BFI
->bfi_Source
)) this_BFI
->bfi_Source
= ImageBackFill_FindSourceRecord(this_ImageName
, BackGround_RenderMode
);
424 if (!(this_BFI
->bfi_Source
))
426 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Creating NEW ImageSource Record\n"));
427 if (!(this_BFI
->bfi_Source
= AllocMem(sizeof(struct BackFillSourceImageRecord
), MEMF_CLEAR
|MEMF_PUBLIC
)))
429 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Couldnt allocate enough mem for source record!\n"));
433 if (!(this_BFI
->bfi_Source
->bfsir_SourceImage
= AllocVec(strlen(this_ImageName
) +1, MEMF_CLEAR
|MEMF_PUBLIC
)))
435 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Couldnt allocate enough mem for source image name store\n"));
436 FreeMem(this_BFI
->bfi_Source
, sizeof(struct BackFillSourceImageRecord
));
439 strcpy(this_BFI
->bfi_Source
->bfsir_SourceImage
, this_ImageName
);
441 if (this_BFI
->bfi_Source
->bfsir_DTPictureObject
= NewDTObject(this_BFI
->bfi_Source
->bfsir_SourceImage
,
442 DTA_SourceType
, DTST_FILE
,
443 DTA_GroupID
, GID_PICTURE
,
444 PDTA_DestMode
, PMODE_V43
,
446 PDTA_Screen
, this_BFI
->bfi_Screen
,
447 PDTA_FreeSourceBitMap
, TRUE
,
448 OBP_Precision
, PRECISION_IMAGE
,
451 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
));
452 if (DoMethod(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, DTM_PROCLAYOUT
, NULL
, 1))
454 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Caused Datatype Object LAYOUT\n"));
456 GetDTAttrs(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, PDTA_BitMapHeader
, &this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
, TAG_DONE
);
457 GetDTAttrs(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, PDTA_DestBitMap
, &this_BFI
->bfi_Source
->bfsir_DTBitMap
, TAG_DONE
);
459 if (!this_BFI
->bfi_Source
->bfsir_DTBitMap
)
460 GetDTAttrs(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, PDTA_BitMap
, &this_BFI
->bfi_Source
->bfsir_DTBitMap
, TAG_DONE
);
462 if (this_BFI
->bfi_Source
->bfsir_DTBitMap
)
464 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Datatype Object BitMap @ %x\n", this_BFI
->bfi_Source
->bfsir_DTBitMap
));
466 if (this_BFI
->bfi_Source
->bfsir_DTRastPort
= CreateRastPort())
468 this_BFI
->bfi_Source
->bfsir_DTRastPort
->BitMap
= this_BFI
->bfi_Source
->bfsir_DTBitMap
;
469 this_BFI
->bfi_Source
->bfsir_BackGroundRenderMode
= BackGround_RenderMode
;
470 this_BFI
->bfi_Source
->bfsir_OpenerCount
= 0x01;
472 NewList(&this_BFI
->bfi_Source
->bfsir_Buffers
);
474 AddTail(&image_backfill_images
, &this_BFI
->bfi_Source
->bfsir_Node
);
475 goto check_imagebuffer
;
478 /* Failed to obtain datatype object's BM */
480 /* Failed to Layout datatype object */
482 /* Failed to open datatype object */
484 if (!this_BFI
->bfi_Source
->bfsir_DTRastPort
)
486 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource RastPort\n"));
490 if (this_BFI
->bfi_Source
->bfsir_DTBitMap
)
492 FreeBitMap(this_BFI
->bfi_Source
->bfsir_DTBitMap
);
493 this_BFI
->bfi_Source
->bfsir_DTBitMap
= NULL
;
498 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource BitMap\n"));
502 if (this_BFI
->bfi_Source
->bfsir_DTPictureObject
)
504 DisposeDTObject(this_BFI
->bfi_Source
->bfsir_DTPictureObject
);
505 this_BFI
->bfi_Source
->bfsir_DTPictureObject
= NULL
;
510 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource Datatype Object\n"));
513 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource Record\n"));
514 if (this_BFI
->bfi_Source
->bfsir_SourceImage
) FreeVec(this_BFI
->bfi_Source
->bfsir_SourceImage
);
515 FreeMem(this_BFI
->bfi_Source
, sizeof(struct BackFillSourceImageRecord
));
516 this_BFI
->bfi_Source
= NULL
;
521 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Using existing ImageSource Record\n"));
522 this_BFI
->bfi_Source
->bfsir_OpenerCount
+= 1;
527 Depth
= GetBitMapAttr(this_BFI
->bfi_Source
->bfsir_DTBitMap
, BMA_DEPTH
);
528 this_BFI
->bfi_CopyWidth
= this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Width
;
529 this_BFI
->bfi_CopyHeight
= this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Height
;
531 switch (BackGround_RenderMode
)
533 case IconWindowExt_ImageBackFill_RenderMode_Scale
:
535 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED mode\n"));
537 this_BFI
->bfi_Options
.bfo_TileMode
= IconWindowExt_ImageBackFill_TileMode_Fixed
;
539 SET(_IconWindows_IconListObj
, MUIA_IconListview_FixedBackground
, TRUE
);
540 SET(_IconWindows_IconListObj
, MUIA_IconListview_ScaledBackground
, TRUE
);
542 if ((BOOL
)XGET(self
, MUIA_IconWindow_IsRoot
))
544 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Root Window = TRUE!\n"));
545 this_BFI
->bfi_CopyWidth
= GetBitMapAttr(this_BFI
->bfi_Screen
->RastPort
.BitMap
, BMA_WIDTH
);
546 this_BFI
->bfi_CopyHeight
= GetBitMapAttr(this_BFI
->bfi_Screen
->RastPort
.BitMap
, BMA_HEIGHT
);
548 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Base Dimensions (%d x %d)\n", this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
));
550 if (!((BOOL
)XGET(self
, MUIA_IconWindow_IsBackdrop
)))
552 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Adjusting for window border Dimensions ..\n"));
553 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
));
554 this_BFI
->bfi_CopyWidth
-= (this_BFI
->bfi_Screen
->WBorLeft
+ this_BFI
->bfi_Screen
->WBorRight
);
555 this_BFI
->bfi_CopyHeight
-= (this_BFI
->bfi_Screen
->WBorTop
+ this_BFI
->bfi_Screen
->WBorBottom
);;
558 this_BFI
->bfi_CopyHeight
-= (this_BFI
->bfi_Screen
->BarHeight
+ 1);
560 struct BackFillSourceImageBuffer
*this_Buffer
= NULL
;
562 if (this_BFI
->bfi_Buffer
)
564 if ((this_BFI
->bfi_Buffer
->bfsib_BitMapWidth
== this_BFI
->bfi_CopyWidth
) && (this_BFI
->bfi_Buffer
->bfsib_BitMapHeight
== this_BFI
->bfi_CopyHeight
))
566 goto pb_backfillsetup_complete
;
570 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
571 this_BFI
->bfi_Buffer
= NULL
;
575 if (!(this_Buffer
= ImageBackFill_FindBufferRecord(this_BFI
->bfi_Source
, this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
)))
577 this_Buffer
= AllocMem(sizeof(struct BackFillSourceImageBuffer
), MEMF_CLEAR
|MEMF_PUBLIC
);
578 this_Buffer
->bfsib_BitMapWidth
= this_BFI
->bfi_CopyWidth
;
579 this_Buffer
->bfsib_BitMapHeight
= this_BFI
->bfi_CopyHeight
;
581 if (!(this_Buffer
->bfsib_BitMapRastPort
= CreateRastPort()))
583 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Failed to create RastPort for BackFill BitMap\n"));
587 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
))
590 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Scale Dimensions (%d x %d)\n", this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
));
592 struct Rectangle CopyBounds
;
594 this_Buffer
->bfsib_BitMapRastPort
->BitMap
= this_Buffer
->bfsib_BitMap
;
595 this_BFI
->bfi_Buffer
= this_Buffer
;
599 CopyBounds
.MaxX
= this_BFI
->bfi_CopyWidth
- 1;
600 CopyBounds
.MaxY
= this_BFI
->bfi_CopyHeight
- 1;
603 ImageBackFill_CopyScaledBitMap(this_BFI
->bfi_Source
->bfsir_DTRastPort
,
605 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Width
,
606 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Height
,
607 this_Buffer
->bfsib_BitMapRastPort
,
608 &CopyBounds
, &CopyBounds
, blit_MODE_Blit
);
610 this_Buffer
->bfsib_OpenerCount
= 0x01;
612 AddTail(&this_BFI
->bfi_Source
->bfsir_Buffers
, &this_Buffer
->bfsib_Node
);
614 goto pb_backfillsetup_complete
;
620 this_BFI
->bfi_Buffer
= this_Buffer
;
621 this_Buffer
->bfsib_OpenerCount
+= 1;
622 goto pb_backfillsetup_complete
;
625 // We arent the "ROOT" (desktop) window so only tile ...
626 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Drawer window scaling unsupported ...\n"));
630 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: TILED mode\n"));
631 if ((BackGround_TileMode
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
632 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGTileMode
)) == -1)
633 BackGround_TileMode
= IconWindowExt_ImageBackFill_TileMode_Float
;
635 if ((BackGround_XOffset
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
636 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGXOffset
)) == -1)
637 BackGround_XOffset
= 0;
639 if ((BackGround_YOffset
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
640 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGYOffset
)) == -1)
641 this_BFI
->bfi_Options
.bfo_OffsetY
= 0;
643 if (this_BFI
->bfi_Options
.bfo_TileMode
!= BackGround_TileMode
)
645 this_BFI
->bfi_Options
.bfo_TileMode
= BackGround_TileMode
;
646 options_changed
= TRUE
;
649 if (this_BFI
->bfi_Options
.bfo_OffsetX
!= BackGround_XOffset
)
651 this_BFI
->bfi_Options
.bfo_OffsetX
= BackGround_XOffset
;
652 options_changed
= TRUE
;
655 if (this_BFI
->bfi_Options
.bfo_OffsetY
!= BackGround_YOffset
)
657 this_BFI
->bfi_Options
.bfo_OffsetY
= BackGround_YOffset
;
658 options_changed
= TRUE
;
661 if (this_BFI
->bfi_Options
.bfo_TileMode
== IconWindowExt_ImageBackFill_TileMode_Float
)
662 SET(_IconWindows_IconListObj
, MUIA_IconListview_FixedBackground
, FALSE
);
664 SET(_IconWindows_IconListObj
, MUIA_IconListview_FixedBackground
, TRUE
);
666 SET(_IconWindows_IconListObj
, MUIA_IconListview_ScaledBackground
, FALSE
);
668 struct BackFillSourceImageBuffer
*this_Buffer
= NULL
;
670 if (this_BFI
->bfi_Buffer
)
672 if ((this_BFI
->bfi_Buffer
->bfsib_BitMapWidth
== this_BFI
->bfi_CopyWidth
) && (this_BFI
->bfi_Buffer
->bfsib_BitMapHeight
== this_BFI
->bfi_CopyHeight
))
674 goto pb_backfillsetup_complete
;
678 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
679 this_BFI
->bfi_Buffer
= NULL
;
683 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Dimensions Width %d, Height %d\n", this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
));
685 if (!(this_Buffer
= ImageBackFill_FindBufferRecord(this_BFI
->bfi_Source
, this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
)))
687 this_Buffer
= AllocMem(sizeof(struct BackFillSourceImageBuffer
), MEMF_CLEAR
|MEMF_PUBLIC
);
688 this_Buffer
->bfsib_BitMapWidth
= this_BFI
->bfi_CopyWidth
;
689 this_Buffer
->bfsib_BitMapHeight
= this_BFI
->bfi_CopyHeight
;
691 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
))
693 struct Rectangle CopyBounds
;
695 if (!(this_Buffer
->bfsib_BitMapRastPort
= CreateRastPort()))
697 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: TILED - Failed to create RastPort for BackFill BitMap\n"));
701 this_Buffer
->bfsib_BitMapRastPort
->BitMap
= this_Buffer
->bfsib_BitMap
;
702 this_BFI
->bfi_Buffer
= this_Buffer
;
706 CopyBounds
.MaxX
= this_BFI
->bfi_CopyWidth
- 1;
707 CopyBounds
.MaxY
= this_BFI
->bfi_CopyHeight
- 1;
709 ImageBackFill_CopyTiledBitMap(this_BFI
->bfi_Source
->bfsir_DTRastPort
,
711 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Width
,
712 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Height
,
713 this_BFI
->bfi_Buffer
->bfsib_BitMapRastPort
,
714 &CopyBounds
, &CopyBounds
, blit_MODE_Blit
);
716 this_Buffer
->bfsib_OpenerCount
= 0x01;
718 AddTail(&this_BFI
->bfi_Source
->bfsir_Buffers
, &this_BFI
->bfi_Buffer
->bfsib_Node
);
720 goto pb_backfillsetup_complete
;
726 this_BFI
->bfi_Buffer
= this_Buffer
;
727 this_Buffer
->bfsib_OpenerCount
+= 1;
728 goto pb_backfillsetup_complete
;
733 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create image datatype object\n"));
737 if (this_BFI
->bfi_Buffer
)
739 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
740 this_BFI
->bfi_Buffer
= NULL
;
744 if (this_BFI
->bfi_Source
)
746 ImageBackFill_CloseSourceRecord(this_BFI
->bfi_Source
);
747 this_BFI
->bfi_Source
= NULL
;
752 pb_backfillsetup_complete
:
753 if ((prefs_processing
) && (options_changed
))
754 SET(self
, MUIA_IconWindow_Changed
, TRUE
);
759 IPTR ImageBackFill__MUIM_IconWindow_BackFill_Setup
761 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_Setup
*message
764 struct BackFillInfo
*this_BFI
= NULL
;
766 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Setup()\n"));
768 this_BFI
= AllocVec(sizeof(struct BackFillInfo
), MEMF_CLEAR
|MEMF_PUBLIC
);
769 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Setup: Allocated BackFillInfo @ %x\n", this_BFI
));
774 IPTR ImageBackFill__MUIM_IconWindow_BackFill_Cleanup
776 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_Cleanup
*message
779 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Cleanup()\n"));
780 struct BackFillInfo
*this_BFI
= message
->BackFill_Data
;
782 if (this_BFI
->bfi_Buffer
)
784 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
785 this_BFI
->bfi_Buffer
= NULL
;
787 if (this_BFI
->bfi_Source
)
789 ImageBackFill_CloseSourceRecord(this_BFI
->bfi_Source
);
790 this_BFI
->bfi_Source
= NULL
;
797 IPTR ImageBackFill__MUIM_IconWindow_BackFill_DrawBackground
799 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_DrawBackground
*message
802 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground()\n"));
803 struct BackFillInfo
*this_BFI
= NULL
;
805 if ((this_BFI
= message
->BackFill_Data
) != NULL
)
807 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Got BackFill_Data @ %x\n", this_BFI
));
808 this_BFI
->bfi_RastPort
= message
->draw_RastPort
;
810 if ((this_BFI
->bfi_Buffer
) && (this_BFI
->bfi_RastPort
))
812 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: BackFill_Data has suitable Buffer and RastPort ..\n"));
813 #warning "TODO: Make Base Tile Offset preference settable"
814 WORD OffsetX
= this_BFI
->bfi_Options
.bfo_OffsetX
; // the offset within the tile in x direction
815 WORD OffsetY
= this_BFI
->bfi_Options
.bfo_OffsetY
; // the offset within the tile in y direction
817 if (this_BFI
->bfi_Options
.bfo_TileMode
== IconWindowExt_ImageBackFill_TileMode_Float
)
819 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Rendering using floating backdrop mode\n"));
820 OffsetX
+= message
->draw_BFM
->OffsetX
;
821 OffsetY
+= message
->draw_BFM
->OffsetY
;
824 ImageBackFill_CopyTiledBitMap(this_BFI
->bfi_Buffer
->bfsib_BitMapRastPort
,
826 this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
,
827 this_BFI
->bfi_RastPort
,
828 &message
->draw_BFM
->AreaBounds
,
829 &message
->draw_BFM
->DrawBounds
,
835 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Causing parent to render .. \n"));
839 /*** SPECIAL : Early Setup ****************************************************************/
841 IPTR
ImageBackFill__SetupClass()
843 struct MUIP_IconWindow_BackFill_Register message
;
845 D(bug("[IconWindow.ImageBackFill] ImageBackFill__SetupClass()\n"));
847 image_backfill_descriptor
.bfd_BackFillID
= image_backfill_name
;
849 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_Setup
= ImageBackFill__MUIM_IconWindow_BackFill_Setup
;
850 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_Cleanup
= ImageBackFill__MUIM_IconWindow_BackFill_Cleanup
;
851 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_ProcessBackground
= ImageBackFill__MUIM_IconWindow_BackFill_ProcessBackground
;
852 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_DrawBackground
= ImageBackFill__MUIM_IconWindow_BackFill_DrawBackground
;
854 message
.register_Node
= &image_backfill_descriptor
;
856 NewList(&image_backfill_images
);
858 #if defined(WANDERER_MODULE_BACKFILL_ENABLED)
859 IconWindow__MUIM_IconWindow_BackFill_Register(NULL
, NULL
, &message
);
865 /* Make sure and run _AFTER_ IconWindow__SetupClass() */
866 ADD2INIT(ImageBackFill__SetupClass
, 10);