Fixes to comments.
[AROS.git] / workbench / system / Wanderer / iconwindowbackfill.c
blobfeff4a4e4d124a85c0c230a8f480934f5b501cac
1 /*
2 Copyright 2004-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "portable_macros.h"
8 #ifdef __AROS__
9 #define MUIMASTER_YES_INLINE_STDARG
10 #endif
12 #define WANDERER_MODULE_BACKFILL_ENABLED
14 #ifdef __AROS__
15 #define DEBUG 0
16 #include <aros/debug.h>
17 #endif
19 #include <exec/types.h>
20 #include <libraries/mui.h>
22 #ifdef __AROS__
23 #include <zune/customclasses.h>
24 #else
25 #include <zune_AROS/customclasses.h>
26 #endif
29 #include <proto/utility.h>
31 #include <proto/graphics.h>
33 #include <proto/exec.h>
34 #include <proto/datatypes.h>
36 #include <dos/dos.h>
37 #include <proto/dos.h>
39 #include <stdio.h>
40 #include <string.h>
42 #include <intuition/screens.h>
43 #include <datatypes/pictureclass.h>
44 #include <clib/macros.h>
46 #ifdef __AROS__
47 #include <clib/alib_protos.h>
48 #endif
50 #include <graphics/scale.h>
52 #ifdef __AROS__
53 #include <prefs/wanderer.h>
54 #else
55 #include <prefs_AROS/wanderer.h>
56 #endif
58 #if defined(__AMIGA__) && !defined(__PPC__)
59 #define NO_INLINE_STDARG
60 #endif
61 #ifndef _PROTO_INTUITION_H
62 #include <proto/intuition.h>
63 #endif
64 #include <proto/muimaster.h>
66 #include "wanderer.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"
75 #ifndef __AROS__
76 #define DEBUG 1
78 #ifdef DEBUG
79 #define D(x) if (DEBUG) x
80 #ifdef __amigaos4__
81 #define bug DebugPrintF
82 #else
83 #define bug kprintf
84 #endif
85 #else
86 #define D(...)
87 #endif
88 #endif
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;
102 #ifdef __AROS__
103 ForeachNode(&image_backfill_images, source_record)
104 #else
105 Foreach_Node(&image_backfill_images, source_record);
106 #endif
108 if ((strcmp(source_record->bfsir_SourceImage, source_name)==0) && (source_record->bfsir_BackGroundRenderMode == source_mode)) return source_record;
110 return NULL;
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;
119 #ifdef __AROS__
120 ForeachNode(&source_record->bfsir_Buffers, buffer_record)
121 #else
122 Foreach_Node(&source_record->bfsir_Buffers, buffer_record);
123 #endif
125 if ((buffer_record->bfsib_BitMapWidth == buffer_width) && (buffer_record->bfsib_BitMapHeight == buffer_height)) return buffer_record;
127 return NULL;
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));
139 return;
141 else
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));
165 return;
167 else
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,
190 ULONG blit_MODE
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,
223 ULONG blit_MODE
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;
240 #if defined(DEBUG)
241 int xcount;
242 int ycount;
243 #endif
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));
275 BltBitMap(Src,
276 SrcOffsetX, SrcOffsetY,
277 Dst,
278 DstFillBounds->MinX, DstFillBounds->MinY,
279 FirstSizeX, FirstSizeY,
280 0xC0, -1, NULL);
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));
286 BltBitMap(Src,
287 0, SrcOffsetY,
288 Dst,
289 SecondMinX, DstFillBounds->MinY,
290 SecondSizeX, FirstSizeY,
291 0xC0, -1, NULL);
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));
297 BltBitMap(Src,
298 SrcOffsetX, 0,
299 Dst,
300 DstFillBounds->MinX, SecondMinY,
301 FirstSizeX, SecondSizeY,
302 0xC0, -1, NULL);
304 if (SecondSizeX > 0)
306 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: 4th Tile Part @ %d,%d [%d x %d]\n", SecondMinX, SecondMinY, SecondSizeX, SecondSizeY));
307 BltBitMap(Src,
308 0, 0,
309 Dst,
310 SecondMinX, SecondMinY,
311 SecondSizeX, SecondSizeY,
312 0xC0, -1, NULL);
316 #if defined(DEBUG)
317 xcount = 2;
318 #endif
319 //Generates the first row of the tiles ....
320 for (PosX = DstFillBounds->MinX + SrcSizeX, SizeX = MIN(SrcSizeX, (DstFillBounds->MaxX - PosX) + 1);PosX <= DstFillBounds->MaxX;)
322 #if defined(DEBUG)
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))));
324 xcount++;
325 #endif
326 BltBitMap(Dst,
327 DstFillBounds->MinX, DstFillBounds->MinY,
328 Dst,
329 PosX, DstFillBounds->MinY,
330 SizeX, MIN(SrcSizeY, RECTSIZEY(DstFillBounds)),
331 0xC0, -1, NULL);
333 PosX += SizeX;
334 SizeX = MIN(SrcSizeX, (DstFillBounds->MaxX - PosX) + 1);
337 #if defined(DEBUG)
338 ycount = 2;
339 #endif
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;)
343 #if defined(DEBUG)
344 D(bug("[IconWindow.ImageBackFill] ImageBackFill_CopyTiledBitMap: Row %d @ %d,%d [%d x %d]\n", ycount, DstFillBounds->MinX, PosY, MIN(SrcSizeX, RECTSIZEX(DstFillBounds)), SizeY));
345 ycount++;
346 #endif
347 BltBitMap(Dst,
348 DstFillBounds->MinX, DstFillBounds->MinY,
349 Dst,
350 DstFillBounds->MinX, PosY,
351 MIN(SrcSizeX, RECTSIZEX(DstFillBounds)), SizeY,
352 0xC0, -1, NULL);
354 PosY += 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));
366 ClipBlit(SrcRast,
367 SrcX, SrcY,
368 DstRast,
369 PosX, PosY,
370 SizeX, SizeY,
371 0xC0);
373 if (SrcX != 0) SrcX = 0;
375 PosX += SizeX;
376 SizeX = MIN(SrcSizeX, (DstFillBounds->MaxX - PosX) + 1);
379 if (SrcY != 0) SrcY = 0;
381 PosY += SizeY;
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
396 LONG Depth = 0;
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,
406 BackGround_Base = 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;
414 UBYTE *this_bgtype;
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);
432 #if defined(DEBUG)
433 if (prefs_processing)
435 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Wanderer Prefs (re)loading detected\n"));
437 #endif
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)
447 return FALSE;
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;
479 else
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"));
505 return FALSE;
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));
512 return FALSE;
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,
520 PDTA_Remap, TRUE,
521 PDTA_Screen, this_BFI->bfi_Screen,
522 PDTA_FreeSourceBitMap, TRUE,
523 OBP_Precision, PRECISION_IMAGE,
524 PDTA_DitherQuality, 2,
525 TAG_DONE)))
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 if (DoMethod(this_BFI->bfi_Source->bfsir_DTPictureObject, DTM_PROCLAYOUT, NULL, 1))
530 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Caused Datatype Object LAYOUT\n"));
532 GetDTAttrs(this_BFI->bfi_Source->bfsir_DTPictureObject, PDTA_BitMapHeader, &this_BFI->bfi_Source->bfsir_DTBitMapHeader, TAG_DONE);
533 GetDTAttrs(this_BFI->bfi_Source->bfsir_DTPictureObject, PDTA_DestBitMap, &this_BFI->bfi_Source->bfsir_DTBitMap, TAG_DONE);
535 if (!this_BFI->bfi_Source->bfsir_DTBitMap)
536 GetDTAttrs(this_BFI->bfi_Source->bfsir_DTPictureObject, PDTA_BitMap, &this_BFI->bfi_Source->bfsir_DTBitMap, TAG_DONE);
538 if (this_BFI->bfi_Source->bfsir_DTBitMap)
540 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Datatype Object BitMap @ %x\n", this_BFI->bfi_Source->bfsir_DTBitMap));
542 if ((this_BFI->bfi_Source->bfsir_DTRastPort = CreateRastPort()))
544 this_BFI->bfi_Source->bfsir_DTRastPort->BitMap = this_BFI->bfi_Source->bfsir_DTBitMap;
545 this_BFI->bfi_Source->bfsir_BackGroundRenderMode = BackGround_RenderMode;
546 this_BFI->bfi_Source->bfsir_OpenerCount = 0x01;
548 NewList(&this_BFI->bfi_Source->bfsir_Buffers);
550 AddTail(&image_backfill_images, &this_BFI->bfi_Source->bfsir_Node);
551 goto check_imagebuffer;
554 /* Failed to obtain datatype object's BM */
556 /* Failed to Layout datatype object */
558 /* Failed to open datatype object */
559 #if defined(DEBUG)
560 if (!this_BFI->bfi_Source->bfsir_DTRastPort)
562 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource RastPort\n"));
564 #endif
566 if (this_BFI->bfi_Source->bfsir_DTBitMap)
568 FreeBitMap(this_BFI->bfi_Source->bfsir_DTBitMap);
569 this_BFI->bfi_Source->bfsir_DTBitMap = NULL;
571 #if defined(DEBUG)
572 else
574 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource BitMap\n"));
576 #endif
578 if (this_BFI->bfi_Source->bfsir_DTPictureObject)
580 DisposeDTObject(this_BFI->bfi_Source->bfsir_DTPictureObject);
581 this_BFI->bfi_Source->bfsir_DTPictureObject = NULL;
583 #if defined(DEBUG)
584 else
586 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource Datatype Object\n"));
588 #endif
589 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create ImageSource Record\n"));
590 if (this_BFI->bfi_Source->bfsir_SourceImage) FreeVec(this_BFI->bfi_Source->bfsir_SourceImage);
591 FreeMem(this_BFI->bfi_Source, sizeof(struct BackFillSourceImageRecord));
592 this_BFI->bfi_Source = NULL;
593 return FALSE;
595 else
597 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Using existing ImageSource Record\n"));
598 this_BFI->bfi_Source->bfsir_OpenerCount += 1;
601 check_imagebuffer:
603 Depth = GetBitMapAttr(this_BFI->bfi_Source->bfsir_DTBitMap, BMA_DEPTH);
604 this_BFI->bfi_CopyWidth = this_BFI->bfi_Source->bfsir_DTBitMapHeader->bmh_Width;
605 this_BFI->bfi_CopyHeight = this_BFI->bfi_Source->bfsir_DTBitMapHeader->bmh_Height;
607 switch (BackGround_RenderMode)
609 case IconWindowExt_ImageBackFill_RenderMode_Scale:
611 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED mode\n"));
613 this_BFI->bfi_Options.bfo_TileMode = IconWindowExt_ImageBackFill_TileMode_Fixed;
615 SET(_IconWindows_IconListObj, MUIA_IconListview_FixedBackground, TRUE);
616 SET(_IconWindows_IconListObj, MUIA_IconListview_ScaledBackground, TRUE);
618 if ((BOOL)XGET(self, MUIA_IconWindow_IsRoot))
620 struct BackFillSourceImageBuffer *this_Buffer;
621 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Root Window = TRUE!\n"));
622 this_BFI->bfi_CopyWidth = GetBitMapAttr(this_BFI->bfi_Screen->RastPort.BitMap, BMA_WIDTH);
623 this_BFI->bfi_CopyHeight = GetBitMapAttr(this_BFI->bfi_Screen->RastPort.BitMap, BMA_HEIGHT);
625 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Base Dimensions (%d x %d)\n", this_BFI->bfi_CopyWidth, this_BFI->bfi_CopyHeight));
627 if (!((BOOL)XGET(self, MUIA_IconWindow_IsBackdrop)))
629 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Adjusting for window border Dimensions ..\n"));
630 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));
631 this_BFI->bfi_CopyWidth -= (this_BFI->bfi_Screen->WBorLeft + this_BFI->bfi_Screen->WBorRight);
632 this_BFI->bfi_CopyHeight -= (this_BFI->bfi_Screen->WBorTop + this_BFI->bfi_Screen->WBorBottom);;
635 this_BFI->bfi_CopyHeight -= (this_BFI->bfi_Screen->BarHeight + 1);
637 this_Buffer = NULL;
639 if (this_BFI->bfi_Buffer)
641 if ((this_BFI->bfi_Buffer->bfsib_BitMapWidth == this_BFI->bfi_CopyWidth) && (this_BFI->bfi_Buffer->bfsib_BitMapHeight == this_BFI->bfi_CopyHeight))
643 goto pb_backfillsetup_complete;
645 else
647 ImageBackFill_CloseSourceBuffer(this_BFI->bfi_Source, this_BFI->bfi_Buffer);
648 this_BFI->bfi_Buffer = NULL;
652 if (!(this_Buffer = ImageBackFill_FindBufferRecord(this_BFI->bfi_Source, this_BFI->bfi_CopyWidth, this_BFI->bfi_CopyHeight)))
654 this_Buffer = AllocMem(sizeof(struct BackFillSourceImageBuffer), MEMF_CLEAR|MEMF_PUBLIC);
655 this_Buffer->bfsib_BitMapWidth = this_BFI->bfi_CopyWidth;
656 this_Buffer->bfsib_BitMapHeight = this_BFI->bfi_CopyHeight;
658 if (!(this_Buffer->bfsib_BitMapRastPort = CreateRastPort()))
660 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Failed to create RastPort for BackFill BitMap\n"));
661 break;
664 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)))
666 struct Rectangle CopyBounds;
668 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Scale Dimensions (%d x %d)\n", this_BFI->bfi_CopyWidth, this_BFI->bfi_CopyHeight));
671 this_Buffer->bfsib_BitMapRastPort->BitMap = this_Buffer->bfsib_BitMap;
672 this_BFI->bfi_Buffer = this_Buffer;
674 CopyBounds.MinX = 0;
675 CopyBounds.MinY = 0;
676 CopyBounds.MaxX = this_BFI->bfi_CopyWidth - 1;
677 CopyBounds.MaxY = this_BFI->bfi_CopyHeight - 1;
680 ImageBackFill_CopyScaledBitMap(this_BFI->bfi_Source->bfsir_DTRastPort,
681 0, 0,
682 this_BFI->bfi_Source->bfsir_DTBitMapHeader->bmh_Width,
683 this_BFI->bfi_Source->bfsir_DTBitMapHeader->bmh_Height,
684 this_Buffer->bfsib_BitMapRastPort,
685 &CopyBounds, &CopyBounds, blit_MODE_Blit);
687 this_Buffer->bfsib_OpenerCount = 0x01;
689 AddTail(&this_BFI->bfi_Source->bfsir_Buffers, &this_Buffer->bfsib_Node);
691 goto pb_backfillsetup_complete;
693 break;
695 else
697 this_BFI->bfi_Buffer = this_Buffer;
698 this_Buffer->bfsib_OpenerCount += 1;
699 goto pb_backfillsetup_complete;
702 // We aren't the "ROOT" (desktop) window so only tile...
703 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: SCALED - Drawer window scaling unsupported ...\n"));
705 default:
707 struct BackFillSourceImageBuffer *this_Buffer;
708 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: TILED mode\n"));
709 if ((BackGround_TileMode = DoMethod(_IconWindows_PrefsObj, MUIM_WandererPrefs_ViewSettings_GetAttribute,
710 BackGround_Attrib, MUIA_IconWindowExt_ImageBackFill_BGTileMode)) == -1)
711 BackGround_TileMode = IconWindowExt_ImageBackFill_TileMode_Float;
713 if ((BackGround_XOffset = DoMethod(_IconWindows_PrefsObj, MUIM_WandererPrefs_ViewSettings_GetAttribute,
714 BackGround_Attrib, MUIA_IconWindowExt_ImageBackFill_BGXOffset)) == -1)
715 BackGround_XOffset = 0;
717 if ((BackGround_YOffset = DoMethod(_IconWindows_PrefsObj, MUIM_WandererPrefs_ViewSettings_GetAttribute,
718 BackGround_Attrib, MUIA_IconWindowExt_ImageBackFill_BGYOffset)) == -1)
719 this_BFI->bfi_Options.bfo_OffsetY = 0;
721 if (this_BFI->bfi_Options.bfo_TileMode != BackGround_TileMode)
723 this_BFI->bfi_Options.bfo_TileMode = BackGround_TileMode;
724 options_changed = TRUE;
727 if (this_BFI->bfi_Options.bfo_OffsetX != BackGround_XOffset)
729 this_BFI->bfi_Options.bfo_OffsetX = BackGround_XOffset;
730 options_changed = TRUE;
733 if (this_BFI->bfi_Options.bfo_OffsetY != BackGround_YOffset)
735 this_BFI->bfi_Options.bfo_OffsetY = BackGround_YOffset;
736 options_changed = TRUE;
739 if (this_BFI->bfi_Options.bfo_TileMode == IconWindowExt_ImageBackFill_TileMode_Float)
740 SET(_IconWindows_IconListObj, MUIA_IconListview_FixedBackground, FALSE);
741 else
742 SET(_IconWindows_IconListObj, MUIA_IconListview_FixedBackground, TRUE);
744 SET(_IconWindows_IconListObj, MUIA_IconListview_ScaledBackground, FALSE);
746 this_Buffer = NULL;
748 if (this_BFI->bfi_Buffer)
750 if ((this_BFI->bfi_Buffer->bfsib_BitMapWidth == this_BFI->bfi_CopyWidth) && (this_BFI->bfi_Buffer->bfsib_BitMapHeight == this_BFI->bfi_CopyHeight))
752 goto pb_backfillsetup_complete;
754 else
756 ImageBackFill_CloseSourceBuffer(this_BFI->bfi_Source, this_BFI->bfi_Buffer);
757 this_BFI->bfi_Buffer = NULL;
761 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Dimensions Width %d, Height %d\n", this_BFI->bfi_CopyWidth, this_BFI->bfi_CopyHeight));
763 if (!(this_Buffer = ImageBackFill_FindBufferRecord(this_BFI->bfi_Source, this_BFI->bfi_CopyWidth, this_BFI->bfi_CopyHeight)))
765 this_Buffer = AllocMem(sizeof(struct BackFillSourceImageBuffer), MEMF_CLEAR|MEMF_PUBLIC);
766 this_Buffer->bfsib_BitMapWidth = this_BFI->bfi_CopyWidth;
767 this_Buffer->bfsib_BitMapHeight = this_BFI->bfi_CopyHeight;
769 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)))
771 struct Rectangle CopyBounds;
773 if (!(this_Buffer->bfsib_BitMapRastPort = CreateRastPort()))
775 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: TILED - Failed to create RastPort for BackFill BitMap\n"));
776 break;
779 this_Buffer->bfsib_BitMapRastPort->BitMap = this_Buffer->bfsib_BitMap;
780 this_BFI->bfi_Buffer = this_Buffer;
782 CopyBounds.MinX = 0;
783 CopyBounds.MinY = 0;
784 CopyBounds.MaxX = this_BFI->bfi_CopyWidth - 1;
785 CopyBounds.MaxY = this_BFI->bfi_CopyHeight - 1;
787 ImageBackFill_CopyTiledBitMap(this_BFI->bfi_Source->bfsir_DTRastPort,
788 0, 0,
789 this_BFI->bfi_Source->bfsir_DTBitMapHeader->bmh_Width,
790 this_BFI->bfi_Source->bfsir_DTBitMapHeader->bmh_Height,
791 this_BFI->bfi_Buffer->bfsib_BitMapRastPort,
792 &CopyBounds, &CopyBounds, blit_MODE_Blit);
794 this_Buffer->bfsib_OpenerCount = 0x01;
796 AddTail(&this_BFI->bfi_Source->bfsir_Buffers, &this_BFI->bfi_Buffer->bfsib_Node);
798 goto pb_backfillsetup_complete;
800 break;
802 else
804 this_BFI->bfi_Buffer = this_Buffer;
805 this_Buffer->bfsib_OpenerCount += 1;
806 goto pb_backfillsetup_complete;
811 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_ProcessBackground: Failed to create image datatype object\n"));
812 return FALSE;
814 pb_cleanup_buffer:
815 if (this_BFI->bfi_Buffer)
817 ImageBackFill_CloseSourceBuffer(this_BFI->bfi_Source, this_BFI->bfi_Buffer);
818 this_BFI->bfi_Buffer = NULL;
821 if (this_BFI->bfi_Source)
823 ImageBackFill_CloseSourceRecord(this_BFI->bfi_Source);
824 this_BFI->bfi_Source = NULL;
827 return FALSE;
829 pb_backfillsetup_complete:
830 if ((prefs_processing) && (options_changed))
831 SET(self, MUIA_IconWindow_Changed, TRUE);
833 return TRUE;
837 ///ImageBackFill__MUIM_IconWindow_BackFill_Setup()
838 IPTR ImageBackFill__MUIM_IconWindow_BackFill_Setup
840 Class *CLASS, Object *self, struct MUIP_IconWindow_BackFill_Setup *message
843 struct BackFillInfo *this_BFI = NULL;
845 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Setup()\n"));
847 this_BFI = AllocVec(sizeof(struct BackFillInfo), MEMF_CLEAR|MEMF_PUBLIC);
848 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Setup: Allocated BackFillInfo @ %x\n", this_BFI));
850 return (IPTR)this_BFI;
854 ///ImageBackFill__MUIM_IconWindow_BackFill_Cleanup()
855 IPTR ImageBackFill__MUIM_IconWindow_BackFill_Cleanup
857 Class *CLASS, Object *self, struct MUIP_IconWindow_BackFill_Cleanup *message
860 struct BackFillInfo *this_BFI = (struct BackFillInfo *)message->BackFill_Data;
862 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_Cleanup()\n"));
864 if (this_BFI->bfi_Buffer)
866 ImageBackFill_CloseSourceBuffer(this_BFI->bfi_Source, this_BFI->bfi_Buffer);
867 this_BFI->bfi_Buffer = NULL;
869 if (this_BFI->bfi_Source)
871 ImageBackFill_CloseSourceRecord(this_BFI->bfi_Source);
872 this_BFI->bfi_Source = NULL;
875 FreeVec(this_BFI);
876 return TRUE;
880 ///ImageBackFill__MUIM_IconWindow_BackFill_DrawBackground()
881 IPTR ImageBackFill__MUIM_IconWindow_BackFill_DrawBackground
883 Class *CLASS, Object *self, struct MUIP_IconWindow_BackFill_DrawBackground *message
886 struct BackFillInfo *this_BFI = NULL;
888 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground()\n"));
890 if ((this_BFI = (struct BackFillInfo *)message->BackFill_Data) != NULL)
892 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Got BackFill_Data @ %x\n", this_BFI));
893 this_BFI->bfi_RastPort = (struct RastPort *)message->draw_RastPort;
895 if ((this_BFI->bfi_Buffer) && (this_BFI->bfi_RastPort))
898 /* TODO: Make Base Tile Offset preference settable */
899 WORD OffsetX = this_BFI->bfi_Options.bfo_OffsetX; // the offset within the tile in x direction
900 WORD OffsetY = this_BFI->bfi_Options.bfo_OffsetY; // the offset within the tile in y direction
902 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: BackFill_Data has suitable Buffer and RastPort ..\n"));
904 if (this_BFI->bfi_Options.bfo_TileMode == IconWindowExt_ImageBackFill_TileMode_Float)
906 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Rendering using floating backdrop mode\n"));
907 OffsetX += message->draw_BFM->OffsetX;
908 OffsetY += message->draw_BFM->OffsetY;
911 ImageBackFill_CopyTiledBitMap(this_BFI->bfi_Buffer->bfsib_BitMapRastPort,
912 OffsetX, OffsetY,
913 this_BFI->bfi_CopyWidth, this_BFI->bfi_CopyHeight,
914 this_BFI->bfi_RastPort,
915 &message->draw_BFM->AreaBounds,
916 &message->draw_BFM->DrawBounds,
917 blit_MODE_Clip);
919 return (IPTR)TRUE;
922 D(bug("[IconWindow.ImageBackFill] MUIM_IconWindow_BackFill_DrawBackground: Causing parent to render .. \n"));
923 return (IPTR)FALSE;
927 /*** SPECIAL : Early Setup ****************************************************************/
928 ///ImageBackFill__SetupClass()
929 IPTR ImageBackFill__SetupClass()
931 struct MUIP_IconWindow_BackFill_Register message;
933 D(bug("[IconWindow.ImageBackFill] ImageBackFill__SetupClass()\n"));
935 image_backfill_descriptor.bfd_BackFillID = image_backfill_name;
937 image_backfill_descriptor.bfd_MUIM_IconWindow_BackFill_Setup = ImageBackFill__MUIM_IconWindow_BackFill_Setup;
938 image_backfill_descriptor.bfd_MUIM_IconWindow_BackFill_Cleanup = ImageBackFill__MUIM_IconWindow_BackFill_Cleanup;
939 image_backfill_descriptor.bfd_MUIM_IconWindow_BackFill_ProcessBackground = ImageBackFill__MUIM_IconWindow_BackFill_ProcessBackground;
940 image_backfill_descriptor.bfd_MUIM_IconWindow_BackFill_DrawBackground = ImageBackFill__MUIM_IconWindow_BackFill_DrawBackground;
942 message.register_Node = &image_backfill_descriptor;
944 NewList(&image_backfill_images);
946 #if defined(WANDERER_MODULE_BACKFILL_ENABLED)
947 IconWindow__MUIM_IconWindow_BackFill_Register(NULL, NULL, &message);
948 #endif
950 return TRUE;
954 /* Make sure and run _AFTER_ IconWindow__SetupClass() */
955 ADD2INIT(ImageBackFill__SetupClass, 10);