2 Copyright 2004-2013, The AROS Development Team. All rights reserved.
6 #include "portable_macros.h"
9 #define MUIMASTER_YES_INLINE_STDARG
12 #define WANDERER_MODULE_BACKFILL_ENABLED
16 #include <aros/debug.h>
19 #include <exec/types.h>
20 #include <libraries/mui.h>
23 #include <zune/customclasses.h>
25 #include <zune_AROS/customclasses.h>
29 #include <proto/utility.h>
31 #include <proto/graphics.h>
33 #include <proto/exec.h>
34 #include <proto/datatypes.h>
37 #include <proto/dos.h>
42 #include <intuition/screens.h>
43 #include <datatypes/pictureclass.h>
44 #include <clib/macros.h>
47 #include <clib/alib_protos.h>
50 #include <graphics/scale.h>
53 #include <prefs/wanderer.h>
55 #include <prefs_AROS/wanderer.h>
58 #if defined(__AMIGA__) && !defined(__PPC__)
59 #define NO_INLINE_STDARG
61 #ifndef _PROTO_INTUITION_H
62 #include <proto/intuition.h>
64 #include <proto/muimaster.h>
67 #include "wandererprefs.h"
68 #include "iconwindow.h"
69 #include "iconwindow_iconlist.h"
70 #include "iconwindowbackfill.h"
71 #include "Classes/iconlistview.h"
72 #include "Classes/iconlist_attributes.h"
79 #define D(x) if (DEBUG) x
81 #define bug DebugPrintF
90 /*** Global Data **********************************************************/
92 static struct IconWindow_BackFill_Descriptor image_backfill_descriptor
;
93 static char image_backfill_name
[] = "Default Image BackFill\0";
94 static struct List image_backfill_images
;
96 /*** Internal functions *********************************************************/
98 ///ImageBackFill_FindSourceRecord()
99 static struct BackFillSourceImageRecord
*ImageBackFill_FindSourceRecord(char *source_name
, IPTR source_mode
)
101 struct BackFillSourceImageRecord
*source_record
= NULL
;
103 ForeachNode(&image_backfill_images
, source_record
)
105 Foreach_Node(&image_backfill_images
, source_record
);
108 if ((strcmp(source_record
->bfsir_SourceImage
, source_name
)==0) && (source_record
->bfsir_BackGroundRenderMode
== source_mode
)) return source_record
;
114 ///ImageBackFill_FindBufferRecord()
115 static struct BackFillSourceImageBuffer
*ImageBackFill_FindBufferRecord(struct BackFillSourceImageRecord
*source_record
, WORD buffer_width
, WORD buffer_height
)
117 struct BackFillSourceImageBuffer
*buffer_record
= NULL
;
120 ForeachNode(&source_record
->bfsir_Buffers
, buffer_record
)
122 Foreach_Node(&source_record
->bfsir_Buffers
, buffer_record
);
125 if ((buffer_record
->bfsib_BitMapWidth
== buffer_width
) && (buffer_record
->bfsib_BitMapHeight
== buffer_height
)) return buffer_record
;
131 ///ImageBackFill_CloseSourceRecord()
132 static void ImageBackFill_CloseSourceRecord(struct BackFillSourceImageRecord
*this_Record
)
134 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceRecord()\n"));
135 if (this_Record
->bfsir_OpenerCount
>= 2)
137 this_Record
->bfsir_OpenerCount
-= 1;
138 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceRecord: %d Openers Remaining for '%s'\n", this_Record
->bfsir_OpenerCount
, this_Record
->bfsir_SourceImage
));
143 Remove((struct Node
*)this_Record
);
144 this_Record
->bfsir_OpenerCount
= 0;
146 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceRecord: Closing Record for '%s'\n", this_Record
->bfsir_SourceImage
));
148 this_Record
->bfsir_DTRastPort
->BitMap
= NULL
;
149 FreeRastPort(this_Record
->bfsir_DTRastPort
);
150 DisposeDTObject(this_Record
->bfsir_DTPictureObject
);
151 FreeVec(this_Record
->bfsir_SourceImage
);
152 FreeMem(this_Record
, sizeof(struct BackFillSourceImageRecord
));
157 ///ImageBackFill_CloseSourceBuffer()
158 static void ImageBackFill_CloseSourceBuffer(struct BackFillSourceImageRecord
*this_Record
, struct BackFillSourceImageBuffer
*this_Buffer
)
160 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceBuffer()\n"));
161 if (this_Buffer
->bfsib_OpenerCount
>= 2)
163 this_Buffer
->bfsib_OpenerCount
-= 1;
164 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CloseSourceBuffer: %d Openers Remaining\n", this_Buffer
->bfsib_OpenerCount
));
169 Remove((struct Node
*)this_Buffer
);
170 this_Buffer
->bfsib_OpenerCount
= 0;
171 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
));
173 this_Buffer
->bfsib_BitMapRastPort
->BitMap
= NULL
;
174 FreeRastPort(this_Buffer
->bfsib_BitMapRastPort
);
175 FreeBitMap(this_Buffer
->bfsib_BitMap
);
176 FreeMem(this_Buffer
, sizeof(struct BackFillSourceImageBuffer
));
181 ///ImageBackFill_CopyScaledBitMap()
182 static void ImageBackFill_CopyScaledBitMap
184 struct RastPort
*SrcRast
,
185 WORD SrcOffsetX
, WORD SrcOffsetY
,
186 WORD SrcSizeX
, WORD SrcSizeY
,
187 struct RastPort
*DstRast
,
188 struct Rectangle
*DstAreaBounds
,
189 struct Rectangle
*DstFillBounds
,
193 struct BitScaleArgs Scale_Args
;
194 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyScaledBitMap()\n"));
196 Scale_Args
.bsa_SrcX
= SrcOffsetX
;
197 Scale_Args
.bsa_SrcY
= SrcOffsetY
;
198 Scale_Args
.bsa_SrcWidth
= SrcSizeX
;
199 Scale_Args
.bsa_SrcHeight
= SrcSizeY
;
200 Scale_Args
.bsa_XSrcFactor
= SrcSizeX
;
201 Scale_Args
.bsa_YSrcFactor
= SrcSizeY
;
202 Scale_Args
.bsa_DestX
= DstFillBounds
->MinX
;
203 Scale_Args
.bsa_DestY
= DstFillBounds
->MinY
;
204 Scale_Args
.bsa_XDestFactor
= (DstFillBounds
->MaxX
- DstFillBounds
->MinX
) + 1;
205 Scale_Args
.bsa_YDestFactor
= (DstFillBounds
->MaxY
- DstFillBounds
->MinY
) + 1;
207 Scale_Args
.bsa_SrcBitMap
= SrcRast
->BitMap
;
208 Scale_Args
.bsa_DestBitMap
= DstRast
->BitMap
;
210 BitMapScale(&Scale_Args
);
214 ///ImageBackFill_CopyTiledBitMap()
215 static void ImageBackFill_CopyTiledBitMap
217 struct RastPort
*SrcRast
,
218 WORD SrcOffsetX
, WORD SrcOffsetY
,
219 WORD SrcSizeX
, WORD SrcSizeY
,
220 struct RastPort
*DstRast
,
221 struct Rectangle
*DstAreaBounds
,
222 struct Rectangle
*DstFillBounds
,
227 WORD FirstSizeX
; // the width of the rectangle to blit as the first column
228 WORD FirstSizeY
; // the height of the rectangle to blit as the first row
229 WORD SecondMinX
; // the left edge of the second column
230 WORD SecondMinY
; // the top edge of the second column
231 WORD SecondSizeX
; // the width of the second column
232 WORD SecondSizeY
; // the height of the second column
233 WORD PosX
, PosY
; // used as starting position in the "exponential" blit
234 WORD SizeX
, SizeY
; // used as bitmap size in the "exponential" blit
235 WORD SrcX
, SrcY
; // used as bitmap size in the "exponential" blit
237 struct BitMap
*Src
= SrcRast
->BitMap
;
238 struct BitMap
*Dst
= DstRast
->BitMap
;
246 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap(mode %d)\n", blit_MODE
));
248 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: SrcRast @ %x, DstRast @ %x\n", SrcRast
, DstRast
));
250 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds @ %x, FillBounds @ %x\n", DstAreaBounds
, DstFillBounds
));
252 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MinX %d\n", DstAreaBounds
->MinX
));
253 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MinY %d\n", DstAreaBounds
->MinY
));
254 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MaxX %d\n", DstAreaBounds
->MaxX
));
255 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds.MaxY %d\n", DstAreaBounds
->MaxY
));
256 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: AreaBounds Width %d Height %d\n", (DstAreaBounds
->MaxX
- DstAreaBounds
->MinX
) + 1, (DstAreaBounds
->MaxY
- DstAreaBounds
->MinY
) + 1));
258 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MinX %d\n", DstFillBounds
->MinX
));
259 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MinY %d\n", DstFillBounds
->MinY
));
260 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MaxX %d\n", DstFillBounds
->MaxX
));
261 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds.MaxY %d\n", DstFillBounds
->MaxY
));
262 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: FillBounds Width %d Height %d\n", (DstAreaBounds
->MaxX
- DstAreaBounds
->MinX
) + 1, (DstAreaBounds
->MaxY
- DstAreaBounds
->MinY
) + 1));
264 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
265 SecondMinX
= DstFillBounds
->MinX
+ FirstSizeX
; // the start for the second tile (if used)
266 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)
268 FirstSizeY
= MIN(SrcSizeY
- SrcOffsetY
, RECTSIZEY(DstFillBounds
)); // the same values are calculated for y direction
269 SecondMinY
= DstFillBounds
->MinY
+ FirstSizeY
;
270 SecondSizeY
= MIN(SrcOffsetY
, DstFillBounds
->MaxY
- SecondMinY
+ 1);
272 if (blit_MODE
== blit_MODE_Blit
) // blit the first piece of the tile
274 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 1st Tile Part @ %d,%d [%d x %d]\n", DstFillBounds
->MinX
, DstFillBounds
->MinY
, FirstSizeX
, FirstSizeY
));
276 SrcOffsetX
, SrcOffsetY
,
278 DstFillBounds
->MinX
, DstFillBounds
->MinY
,
279 FirstSizeX
, FirstSizeY
,
283 if (SecondSizeX
> 0) // if SrcOffset was 0 or the dest rect was too narrow, we won't need a second column
285 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 2nd Tile Part @ %d,%d [%d x %d]\n", SecondMinX
, DstFillBounds
->MinY
, SecondSizeX
, FirstSizeY
));
289 SecondMinX
, DstFillBounds
->MinY
,
290 SecondSizeX
, FirstSizeY
,
294 if (SecondSizeY
> 0) // is a second row necessary?
296 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 3rd Tile Part @ %d,%d [%d x %d]\n", DstFillBounds
->MinX
, SecondMinY
, FirstSizeX
, SecondSizeY
));
300 DstFillBounds
->MinX
, SecondMinY
,
301 FirstSizeX
, SecondSizeY
,
306 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 4th Tile Part @ %d,%d [%d x %d]\n", SecondMinX
, SecondMinY
, SecondSizeX
, SecondSizeY
));
310 SecondMinX
, SecondMinY
,
311 SecondSizeX
, SecondSizeY
,
319 //Generates the first row of the tiles ....
320 for (PosX
= DstFillBounds
->MinX
+ SrcSizeX
, SizeX
= MIN(SrcSizeX
, (DstFillBounds
->MaxX
- PosX
) + 1);PosX
<= DstFillBounds
->MaxX
;)
323 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
))));
327 DstFillBounds
->MinX
, DstFillBounds
->MinY
,
329 PosX
, DstFillBounds
->MinY
,
330 SizeX
, MIN(SrcSizeY
, RECTSIZEY(DstFillBounds
)),
334 SizeX
= MIN(SrcSizeX
, (DstFillBounds
->MaxX
- PosX
) + 1);
340 // .. now Blit the first row down several times to fill the whole dest rect
341 for (PosY
= DstFillBounds
->MinY
+ SrcSizeY
, SizeY
= MIN(SrcSizeY
, (DstFillBounds
->MaxY
- PosY
) + 1);PosY
<= DstFillBounds
->MaxY
;)
344 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: Row %d @ %d,%d [%d x %d]\n", ycount
, DstFillBounds
->MinX
, PosY
, MIN(SrcSizeX
, RECTSIZEX(DstFillBounds
)), SizeY
));
348 DstFillBounds
->MinX
, DstFillBounds
->MinY
,
350 DstFillBounds
->MinX
, PosY
,
351 MIN(SrcSizeX
, RECTSIZEX(DstFillBounds
)), SizeY
,
355 SizeY
= MIN(SrcSizeY
, (DstFillBounds
->MaxY
- PosY
) + 1);
358 else if (blit_MODE
== blit_MODE_Clip
)
360 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
;)
362 for (SrcX
= MOD(SrcOffsetX
+ MOD((DstFillBounds
->MinX
- DstAreaBounds
->MinX
), SrcSizeX
- 1), SrcSizeX
- 1), PosX
= DstFillBounds
->MinX
, SizeX
= MIN((SrcSizeX
- SrcX
), (DstFillBounds
->MaxX
- DstFillBounds
->MinX
) + 1); PosX
<= DstFillBounds
->MaxX
;)
364 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: ClipBlit %d, %d -> %d,%d [%d x %d]\n", SrcX
, SrcY
, PosX
, PosY
, SizeX
, SizeY
));
373 if (SrcX
!= 0) SrcX
= 0;
376 SizeX
= MIN(SrcSizeX
, (DstFillBounds
->MaxX
- PosX
) + 1);
379 if (SrcY
!= 0) SrcY
= 0;
382 SizeY
= MIN(SrcSizeY
, (DstFillBounds
->MaxY
- PosY
) + 1);
388 /*** Methods ****************************************************************/
389 ///ImageBackFill__MUIM_IconWindow_BackFill_ProcessBackground()
390 IPTR ImageBackFill__MUIM_IconWindow_BackFill_ProcessBackground
392 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_ProcessBackground
*message
397 Object
*_IconWindows_PrefsObj
= NULL
,
398 *_IconWindows_WindowObj
= NULL
;
399 Object
*_IconWindows_IconListObj
= NULL
;
401 BOOL options_changed
= FALSE
;
403 IPTR prefs_processing
= 0;
405 IPTR BackGround_Attrib
= 0,
407 BackGround_RenderMode
= 0,
408 BackGround_TileMode
= 0,
409 BackGround_XOffset
= 0,
410 BackGround_YOffset
= 0;
412 struct BackFillInfo
*this_BFI
=(struct BackFillInfo
*) message
->BackFill_Data
;
415 char *this_ImageName
;
417 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground()\n"));
419 GET(_app(self
), MUIA_Wanderer_Prefs
, &_IconWindows_PrefsObj
);
421 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: PrefsObj @ %x\n", _IconWindows_PrefsObj
));
423 GET(self
, MUIA_IconWindow_Window
, &_IconWindows_WindowObj
);
424 GET(self
, MUIA_IconWindow_IconList
, &_IconWindows_IconListObj
);
426 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: MUIA_IconWindow_Window = %x\n", _IconWindows_WindowObj
));
428 if ((_IconWindows_PrefsObj
== NULL
) || (_IconWindows_WindowObj
== NULL
) || (_IconWindows_IconListObj
== NULL
)) return FALSE
;
430 GET(_IconWindows_PrefsObj
, MUIA_WandererPrefs_Processing
, &prefs_processing
);
433 if (prefs_processing
)
435 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Wanderer Prefs (re)loading detected\n"));
439 GET(_IconWindows_WindowObj
, MUIA_IconWindow_BackgroundAttrib
, &BackGround_Attrib
);
441 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Background Attrib = '%s'\n", BackGround_Attrib
));
443 if (BackGround_Attrib
== (IPTR
) NULL
) return FALSE
;
445 if ((BackGround_Base
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
446 BackGround_Attrib
, MUIA_Background
)) == -1)
449 if ((BackGround_RenderMode
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
450 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGRenderMode
)) == -1)
451 BackGround_RenderMode
= IconWindowExt_ImageBackFill_RenderMode_Tiled
;
453 this_bgtype
= (UBYTE
*)BackGround_Base
;
454 this_ImageName
= (char *)(BackGround_Base
+ 2);
456 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: BackFillInfo @ %x\n", this_BFI
));
457 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Background '%s', mode %d\n", BackGround_Base
, BackGround_RenderMode
));
459 if ((this_bgtype
[0] - 48) != 5)
461 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Background is NOT an image - letting our windowclass handle it...\n"));
463 goto pb_cleanup_buffer
;
466 GET(self
, MUIA_Window_Screen
, &this_BFI
->bfi_Screen
);
467 GET(_IconWindows_IconListObj
, MUIA_IconList_BufferRastport
, &this_BFI
->bfi_RastPort
);
469 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Wanderers Screen @ %x, Using RastPort @ %x\n", this_BFI
->bfi_Screen
, this_BFI
->bfi_RastPort
));
471 if (this_BFI
->bfi_Source
)
473 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: BackFillInfo has existing source record @ %x\n", this_BFI
->bfi_Source
));
474 if ((strcmp(this_BFI
->bfi_Source
->bfsir_SourceImage
, this_ImageName
) == 0) && (this_BFI
->bfi_Source
->bfsir_BackGroundRenderMode
== BackGround_RenderMode
))
476 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: existing BackFillInfo Using the same background / mode\n"));
477 goto check_imagebuffer
;
481 if (this_BFI
->bfi_Buffer
)
483 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
484 this_BFI
->bfi_Buffer
= NULL
;
486 ImageBackFill_CloseSourceRecord(this_BFI
->bfi_Source
);
487 this_BFI
->bfi_Source
= NULL
;
491 if (!(this_BFI
->bfi_Source
))
493 /* If the previous source is not existing, it means there was a change with the buffer */
494 options_changed
= TRUE
;
497 if (!(this_BFI
->bfi_Source
)) this_BFI
->bfi_Source
= ImageBackFill_FindSourceRecord(this_ImageName
, BackGround_RenderMode
);
499 if (!(this_BFI
->bfi_Source
))
501 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Creating NEW ImageSource Record\n"));
502 if (!(this_BFI
->bfi_Source
= AllocMem(sizeof(struct BackFillSourceImageRecord
), MEMF_CLEAR
|MEMF_PUBLIC
)))
504 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Couldnt allocate enough mem for source record!\n"));
508 if (!(this_BFI
->bfi_Source
->bfsir_SourceImage
= AllocVec(strlen(this_ImageName
) +1, MEMF_CLEAR
|MEMF_PUBLIC
)))
510 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Couldnt allocate enough mem for source image name store\n"));
511 FreeMem(this_BFI
->bfi_Source
, sizeof(struct BackFillSourceImageRecord
));
514 strcpy(this_BFI
->bfi_Source
->bfsir_SourceImage
, this_ImageName
);
516 if ((this_BFI
->bfi_Source
->bfsir_DTPictureObject
= NewDTObject(this_BFI
->bfi_Source
->bfsir_SourceImage
,
517 DTA_SourceType
, DTST_FILE
,
518 DTA_GroupID
, GID_PICTURE
,
519 PDTA_DestMode
, PMODE_V43
,
521 PDTA_Screen
, this_BFI
->bfi_Screen
,
522 PDTA_FreeSourceBitMap
, TRUE
,
523 OBP_Precision
, PRECISION_IMAGE
,
524 PDTA_DitherQuality
, 2,
527 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
));
528 /* Scale to fit the background */
529 DoMethod(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, PDTM_SCALE
, this_BFI
->bfi_Screen
->Width
, this_BFI
->bfi_Screen
->Height
, 0);
530 if (DoMethod(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, DTM_PROCLAYOUT
, NULL
, 1))
532 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Caused Datatype Object LAYOUT\n"));
534 GetDTAttrs(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, PDTA_BitMapHeader
, &this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
, TAG_DONE
);
535 GetDTAttrs(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, PDTA_DestBitMap
, &this_BFI
->bfi_Source
->bfsir_DTBitMap
, TAG_DONE
);
537 if (!this_BFI
->bfi_Source
->bfsir_DTBitMap
)
538 GetDTAttrs(this_BFI
->bfi_Source
->bfsir_DTPictureObject
, PDTA_BitMap
, &this_BFI
->bfi_Source
->bfsir_DTBitMap
, TAG_DONE
);
540 if (this_BFI
->bfi_Source
->bfsir_DTBitMap
)
542 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Datatype Object BitMap @ %x\n", this_BFI
->bfi_Source
->bfsir_DTBitMap
));
544 if ((this_BFI
->bfi_Source
->bfsir_DTRastPort
= CreateRastPort()))
546 this_BFI
->bfi_Source
->bfsir_DTRastPort
->BitMap
= this_BFI
->bfi_Source
->bfsir_DTBitMap
;
547 this_BFI
->bfi_Source
->bfsir_BackGroundRenderMode
= BackGround_RenderMode
;
548 this_BFI
->bfi_Source
->bfsir_OpenerCount
= 0x01;
550 NewList(&this_BFI
->bfi_Source
->bfsir_Buffers
);
552 AddTail(&image_backfill_images
, &this_BFI
->bfi_Source
->bfsir_Node
);
553 goto check_imagebuffer
;
556 /* Failed to obtain datatype object's BM */
558 /* Failed to Layout datatype object */
560 /* Failed to open datatype object */
562 if (!this_BFI
->bfi_Source
->bfsir_DTRastPort
)
564 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource RastPort\n"));
568 if (this_BFI
->bfi_Source
->bfsir_DTBitMap
)
570 FreeBitMap(this_BFI
->bfi_Source
->bfsir_DTBitMap
);
571 this_BFI
->bfi_Source
->bfsir_DTBitMap
= NULL
;
576 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource BitMap\n"));
580 if (this_BFI
->bfi_Source
->bfsir_DTPictureObject
)
582 DisposeDTObject(this_BFI
->bfi_Source
->bfsir_DTPictureObject
);
583 this_BFI
->bfi_Source
->bfsir_DTPictureObject
= NULL
;
588 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource Datatype Object\n"));
591 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource Record\n"));
592 FreeVec(this_BFI
->bfi_Source
->bfsir_SourceImage
);
593 FreeMem(this_BFI
->bfi_Source
, sizeof(struct BackFillSourceImageRecord
));
594 this_BFI
->bfi_Source
= NULL
;
599 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Using existing ImageSource Record\n"));
600 this_BFI
->bfi_Source
->bfsir_OpenerCount
+= 1;
605 Depth
= GetBitMapAttr(this_BFI
->bfi_Source
->bfsir_DTBitMap
, BMA_DEPTH
);
606 this_BFI
->bfi_CopyWidth
= this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Width
;
607 this_BFI
->bfi_CopyHeight
= this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Height
;
609 switch (BackGround_RenderMode
)
611 case IconWindowExt_ImageBackFill_RenderMode_Scale
:
613 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED mode\n"));
615 this_BFI
->bfi_Options
.bfo_TileMode
= IconWindowExt_ImageBackFill_TileMode_Fixed
;
617 SET(_IconWindows_IconListObj
, MUIA_IconListview_FixedBackground
, TRUE
);
618 SET(_IconWindows_IconListObj
, MUIA_IconListview_ScaledBackground
, TRUE
);
620 if ((BOOL
)XGET(self
, MUIA_IconWindow_IsRoot
))
622 struct BackFillSourceImageBuffer
*this_Buffer
;
623 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Root Window = TRUE!\n"));
624 this_BFI
->bfi_CopyWidth
= GetBitMapAttr(this_BFI
->bfi_Screen
->RastPort
.BitMap
, BMA_WIDTH
);
625 this_BFI
->bfi_CopyHeight
= GetBitMapAttr(this_BFI
->bfi_Screen
->RastPort
.BitMap
, BMA_HEIGHT
);
627 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Base Dimensions (%d x %d)\n", this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
));
629 if (!((BOOL
)XGET(self
, MUIA_IconWindow_IsBackdrop
)))
631 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Adjusting for window border Dimensions ..\n"));
632 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
));
633 this_BFI
->bfi_CopyWidth
-= (this_BFI
->bfi_Screen
->WBorLeft
+ this_BFI
->bfi_Screen
->WBorRight
);
634 this_BFI
->bfi_CopyHeight
-= (this_BFI
->bfi_Screen
->WBorTop
+ this_BFI
->bfi_Screen
->WBorBottom
);;
637 this_BFI
->bfi_CopyHeight
-= (this_BFI
->bfi_Screen
->BarHeight
+ 1);
641 if (this_BFI
->bfi_Buffer
)
643 if ((this_BFI
->bfi_Buffer
->bfsib_BitMapWidth
== this_BFI
->bfi_CopyWidth
) && (this_BFI
->bfi_Buffer
->bfsib_BitMapHeight
== this_BFI
->bfi_CopyHeight
))
645 goto pb_backfillsetup_complete
;
649 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
650 this_BFI
->bfi_Buffer
= NULL
;
654 if (!(this_Buffer
= ImageBackFill_FindBufferRecord(this_BFI
->bfi_Source
, this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
)))
656 this_Buffer
= AllocMem(sizeof(struct BackFillSourceImageBuffer
), MEMF_CLEAR
|MEMF_PUBLIC
);
657 this_Buffer
->bfsib_BitMapWidth
= this_BFI
->bfi_CopyWidth
;
658 this_Buffer
->bfsib_BitMapHeight
= this_BFI
->bfi_CopyHeight
;
660 if (!(this_Buffer
->bfsib_BitMapRastPort
= CreateRastPort()))
662 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Failed to create RastPort for BackFill BitMap\n"));
666 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
)))
668 struct Rectangle CopyBounds
;
670 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Scale Dimensions (%d x %d)\n", this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
));
673 this_Buffer
->bfsib_BitMapRastPort
->BitMap
= this_Buffer
->bfsib_BitMap
;
674 this_BFI
->bfi_Buffer
= this_Buffer
;
678 CopyBounds
.MaxX
= this_BFI
->bfi_CopyWidth
- 1;
679 CopyBounds
.MaxY
= this_BFI
->bfi_CopyHeight
- 1;
682 ImageBackFill_CopyScaledBitMap(this_BFI
->bfi_Source
->bfsir_DTRastPort
,
684 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Width
,
685 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Height
,
686 this_Buffer
->bfsib_BitMapRastPort
,
687 &CopyBounds
, &CopyBounds
, blit_MODE_Blit
);
689 this_Buffer
->bfsib_OpenerCount
= 0x01;
691 AddTail(&this_BFI
->bfi_Source
->bfsir_Buffers
, &this_Buffer
->bfsib_Node
);
693 goto pb_backfillsetup_complete
;
699 this_BFI
->bfi_Buffer
= this_Buffer
;
700 this_Buffer
->bfsib_OpenerCount
+= 1;
701 goto pb_backfillsetup_complete
;
704 // We aren't the "ROOT" (desktop) window so only tile...
705 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Drawer window scaling unsupported ...\n"));
709 struct BackFillSourceImageBuffer
*this_Buffer
;
710 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: TILED mode\n"));
711 if ((BackGround_TileMode
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
712 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGTileMode
)) == -1)
713 BackGround_TileMode
= IconWindowExt_ImageBackFill_TileMode_Float
;
715 if ((BackGround_XOffset
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
716 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGXOffset
)) == -1)
717 BackGround_XOffset
= 0;
719 if ((BackGround_YOffset
= DoMethod(_IconWindows_PrefsObj
, MUIM_WandererPrefs_ViewSettings_GetAttribute
,
720 BackGround_Attrib
, MUIA_IconWindowExt_ImageBackFill_BGYOffset
)) == -1)
721 this_BFI
->bfi_Options
.bfo_OffsetY
= 0;
723 if (this_BFI
->bfi_Options
.bfo_TileMode
!= BackGround_TileMode
)
725 this_BFI
->bfi_Options
.bfo_TileMode
= BackGround_TileMode
;
726 options_changed
= TRUE
;
729 if (this_BFI
->bfi_Options
.bfo_OffsetX
!= BackGround_XOffset
)
731 this_BFI
->bfi_Options
.bfo_OffsetX
= BackGround_XOffset
;
732 options_changed
= TRUE
;
735 if (this_BFI
->bfi_Options
.bfo_OffsetY
!= BackGround_YOffset
)
737 this_BFI
->bfi_Options
.bfo_OffsetY
= BackGround_YOffset
;
738 options_changed
= TRUE
;
741 if (this_BFI
->bfi_Options
.bfo_TileMode
== IconWindowExt_ImageBackFill_TileMode_Float
)
742 SET(_IconWindows_IconListObj
, MUIA_IconListview_FixedBackground
, FALSE
);
744 SET(_IconWindows_IconListObj
, MUIA_IconListview_FixedBackground
, TRUE
);
746 SET(_IconWindows_IconListObj
, MUIA_IconListview_ScaledBackground
, FALSE
);
750 if (this_BFI
->bfi_Buffer
)
752 if ((this_BFI
->bfi_Buffer
->bfsib_BitMapWidth
== this_BFI
->bfi_CopyWidth
) && (this_BFI
->bfi_Buffer
->bfsib_BitMapHeight
== this_BFI
->bfi_CopyHeight
))
754 goto pb_backfillsetup_complete
;
758 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
759 this_BFI
->bfi_Buffer
= NULL
;
763 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Dimensions Width %d, Height %d\n", this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
));
765 if (!(this_Buffer
= ImageBackFill_FindBufferRecord(this_BFI
->bfi_Source
, this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
)))
767 this_Buffer
= AllocMem(sizeof(struct BackFillSourceImageBuffer
), MEMF_CLEAR
|MEMF_PUBLIC
);
768 this_Buffer
->bfsib_BitMapWidth
= this_BFI
->bfi_CopyWidth
;
769 this_Buffer
->bfsib_BitMapHeight
= this_BFI
->bfi_CopyHeight
;
771 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
)))
773 struct Rectangle CopyBounds
;
775 if (!(this_Buffer
->bfsib_BitMapRastPort
= CreateRastPort()))
777 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: TILED - Failed to create RastPort for BackFill BitMap\n"));
781 this_Buffer
->bfsib_BitMapRastPort
->BitMap
= this_Buffer
->bfsib_BitMap
;
782 this_BFI
->bfi_Buffer
= this_Buffer
;
786 CopyBounds
.MaxX
= this_BFI
->bfi_CopyWidth
- 1;
787 CopyBounds
.MaxY
= this_BFI
->bfi_CopyHeight
- 1;
789 ImageBackFill_CopyTiledBitMap(this_BFI
->bfi_Source
->bfsir_DTRastPort
,
791 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Width
,
792 this_BFI
->bfi_Source
->bfsir_DTBitMapHeader
->bmh_Height
,
793 this_BFI
->bfi_Buffer
->bfsib_BitMapRastPort
,
794 &CopyBounds
, &CopyBounds
, blit_MODE_Blit
);
796 this_Buffer
->bfsib_OpenerCount
= 0x01;
798 AddTail(&this_BFI
->bfi_Source
->bfsir_Buffers
, &this_BFI
->bfi_Buffer
->bfsib_Node
);
800 goto pb_backfillsetup_complete
;
806 this_BFI
->bfi_Buffer
= this_Buffer
;
807 this_Buffer
->bfsib_OpenerCount
+= 1;
808 goto pb_backfillsetup_complete
;
813 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create image datatype object\n"));
817 if (this_BFI
->bfi_Buffer
)
819 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
820 this_BFI
->bfi_Buffer
= NULL
;
823 if (this_BFI
->bfi_Source
)
825 ImageBackFill_CloseSourceRecord(this_BFI
->bfi_Source
);
826 this_BFI
->bfi_Source
= NULL
;
831 pb_backfillsetup_complete
:
832 if ((prefs_processing
) && (options_changed
))
833 SET(self
, MUIA_IconWindow_Changed
, TRUE
);
839 ///ImageBackFill__MUIM_IconWindow_BackFill_Setup()
840 IPTR ImageBackFill__MUIM_IconWindow_BackFill_Setup
842 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_Setup
*message
845 struct BackFillInfo
*this_BFI
= NULL
;
847 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Setup()\n"));
849 this_BFI
= AllocVec(sizeof(struct BackFillInfo
), MEMF_CLEAR
|MEMF_PUBLIC
);
850 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Setup: Allocated BackFillInfo @ %x\n", this_BFI
));
852 return (IPTR
)this_BFI
;
856 ///ImageBackFill__MUIM_IconWindow_BackFill_Cleanup()
857 IPTR ImageBackFill__MUIM_IconWindow_BackFill_Cleanup
859 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_Cleanup
*message
862 struct BackFillInfo
*this_BFI
= (struct BackFillInfo
*)message
->BackFill_Data
;
864 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Cleanup()\n"));
866 if (this_BFI
->bfi_Buffer
)
868 ImageBackFill_CloseSourceBuffer(this_BFI
->bfi_Source
, this_BFI
->bfi_Buffer
);
869 this_BFI
->bfi_Buffer
= NULL
;
871 if (this_BFI
->bfi_Source
)
873 ImageBackFill_CloseSourceRecord(this_BFI
->bfi_Source
);
874 this_BFI
->bfi_Source
= NULL
;
882 ///ImageBackFill__MUIM_IconWindow_BackFill_DrawBackground()
883 IPTR ImageBackFill__MUIM_IconWindow_BackFill_DrawBackground
885 Class
*CLASS
, Object
*self
, struct MUIP_IconWindow_BackFill_DrawBackground
*message
888 struct BackFillInfo
*this_BFI
= NULL
;
890 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground()\n"));
892 if ((this_BFI
= (struct BackFillInfo
*)message
->BackFill_Data
) != NULL
)
894 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Got BackFill_Data @ %x\n", this_BFI
));
895 this_BFI
->bfi_RastPort
= (struct RastPort
*)message
->draw_RastPort
;
897 if ((this_BFI
->bfi_Buffer
) && (this_BFI
->bfi_RastPort
))
900 /* TODO: Make Base Tile Offset preference settable */
901 WORD OffsetX
= this_BFI
->bfi_Options
.bfo_OffsetX
; // the offset within the tile in x direction
902 WORD OffsetY
= this_BFI
->bfi_Options
.bfo_OffsetY
; // the offset within the tile in y direction
904 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: BackFill_Data has suitable Buffer and RastPort ..\n"));
906 if (this_BFI
->bfi_Options
.bfo_TileMode
== IconWindowExt_ImageBackFill_TileMode_Float
)
908 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Rendering using floating backdrop mode\n"));
909 OffsetX
+= message
->draw_BFM
->OffsetX
;
910 OffsetY
+= message
->draw_BFM
->OffsetY
;
913 ImageBackFill_CopyTiledBitMap(this_BFI
->bfi_Buffer
->bfsib_BitMapRastPort
,
915 this_BFI
->bfi_CopyWidth
, this_BFI
->bfi_CopyHeight
,
916 this_BFI
->bfi_RastPort
,
917 &message
->draw_BFM
->AreaBounds
,
918 &message
->draw_BFM
->DrawBounds
,
924 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Causing parent to render .. \n"));
929 /*** SPECIAL : Early Setup ****************************************************************/
930 ///ImageBackFill__SetupClass()
931 IPTR
ImageBackFill__SetupClass()
933 struct MUIP_IconWindow_BackFill_Register message
;
935 D(bug("[IconWindow.ImageBackFill] ImageBackFill__SetupClass()\n"));
937 image_backfill_descriptor
.bfd_BackFillID
= image_backfill_name
;
939 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_Setup
= ImageBackFill__MUIM_IconWindow_BackFill_Setup
;
940 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_Cleanup
= ImageBackFill__MUIM_IconWindow_BackFill_Cleanup
;
941 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_ProcessBackground
= ImageBackFill__MUIM_IconWindow_BackFill_ProcessBackground
;
942 image_backfill_descriptor
.bfd_MUIM_IconWindow_BackFill_DrawBackground
= ImageBackFill__MUIM_IconWindow_BackFill_DrawBackground
;
944 message
.register_Node
= &image_backfill_descriptor
;
946 NewList(&image_backfill_images
);
948 #if defined(WANDERER_MODULE_BACKFILL_ENABLED)
949 IconWindow__MUIM_IconWindow_BackFill_Register(NULL
, NULL
, &message
);
956 /* Make sure and run _AFTER_ IconWindow__SetupClass() */
957 ADD2INIT(ImageBackFill__SetupClass
, 10);