childs -> children.
[AROS.git] / workbench / libs / icon / dupdiskobject.c
blob75ed1bde20b33464ae5096a7967d9aaaec96498e
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 #include <aros/debug.h>
11 #include <workbench/icon.h>
12 #include <graphics/gfx.h>
13 #include <proto/arossupport.h>
14 #include "icon_intern.h"
16 /*#define OUTPUT_DATA*/
18 STATIC STRPTR StrDupIcon(struct DiskObject *dobj, STRPTR str, APTR IconBase)
20 char *newstr;
21 if (!str) return NULL;
22 newstr = AllocMemIcon(dobj, strlen(str)+1, MEMF_PUBLIC);
23 if (newstr) strcpy(newstr,str);
24 return newstr;
27 STATIC APTR MemDupIcon(struct DiskObject *dobj, CONST_APTR src, ULONG size, APTR IconBase)
29 UBYTE *newmem;
31 newmem = AllocMemIcon(dobj, size, MEMF_PUBLIC);
32 if (newmem) CopyMem(src, newmem, size);
34 return newmem;
37 STATIC struct Image *ImageDupIcon(struct DiskObject *dobj, struct Image *src, BOOL dupImage, BOOL dupImageData, APTR IconBase)
39 struct Image *dest;
41 if (!src) return NULL;
43 if (dupImageData)
44 dupImage = TRUE;
46 if (!dupImage)
47 return src;
49 dest = (struct Image*)AllocMemIcon(dobj, sizeof(struct Image), MEMF_PUBLIC);
50 if (dest)
52 int data_size = 0;
53 int plane_size;
54 int i;
55 int plane_pick = src->PlanePick;
57 *dest = *src;
58 dest->NextImage = NULL;
60 /* Calc the size all used planes */
61 plane_size = RASSIZE(src->Width,src->Height);
62 #if 0
63 for (i=0;i<8;i++)
65 if (plane_pick & 1) data_size += plane_size;
66 plane_pick >>= 1;
68 #else
69 /* It seems planepick must be ignored. See drawer icon in MCC_TheBar-26.7.lha
70 which seems to contain a SelectRender image with planepick == 0, but the image
71 data is still there. */
73 (void)plane_pick;
74 (void)i;
76 data_size = plane_size * src->Depth;
77 #endif
79 if (!dupImageData)
80 return dest;
82 if ((dest->ImageData = AllocMemIcon(dobj, data_size, MEMF_PUBLIC | MEMF_CHIP)))
84 memcpy(dest->ImageData,src->ImageData,data_size);
85 #ifdef OUTPUT_DATA
86 kprintf("plane_pick = %ld\n",src->PlanePick);
87 kprintf("width = %ld\n",src->Width);
88 kprintf("height = %ld\n",src->Height);
90 for (i=0;i<data_size;i++)
92 kprintf("0x%02lx,",((unsigned char*)src->ImageData)[i]);
93 if (i%16 == 15) kprintf("\n");
95 kprintf("\n");
96 #endif
97 return dest;
100 return NULL;
103 /*****************************************************************************
105 NAME */
106 #include <clib/icon_protos.h>
108 AROS_LH2(struct DiskObject *, DupDiskObjectA,
110 /* SYNOPSIS */
111 AROS_LHA(struct DiskObject *, icon, A0),
112 AROS_LHA(struct TagItem *, tags, A1),
114 /* LOCATION */
115 struct IconBase *, IconBase, 25, Icon)
117 /* FUNCTION
119 INPUTS
121 RESULT
123 NOTES
125 EXAMPLE
127 BUGS
129 SEE ALSO
131 INTERNALS
133 HISTORY
135 *****************************************************************************/
137 AROS_LIBFUNC_INIT
139 struct NativeIcon *mem;
140 struct DiskObject *dobj;
141 struct NativeIcon *srcnativeicon;
143 if (!icon) return NULL;
145 dobj = NewDiskObject(icon->do_Type);
146 if (dobj == NULL)
147 return NULL;
149 mem = NATIVEICON(dobj);
150 /* We can't cast this, since it could be a hand-build one */
151 srcnativeicon = GetNativeIcon(icon, IconBase);
153 /* copy the contents */
154 *dobj = *icon;
156 if (srcnativeicon && GetTagData(ICONDUPA_DuplicateImageData, TRUE, tags) == TRUE)
158 int i;
160 mem->ni_IsDefault = srcnativeicon->ni_IsDefault;
161 mem->ni_Frameless = srcnativeicon->ni_Frameless;
162 mem->ni_ScaleBox = srcnativeicon->ni_ScaleBox;
163 mem->ni_Face = srcnativeicon->ni_Face;
165 /* The duplicate will *not* be laid out to a specific screen */
166 mem->ni_Screen = NULL;
167 mem->ni_Width = 0;
168 mem->ni_Height = 0;
170 /* Duplicate any extra data */
171 if (srcnativeicon->ni_Extra.Data && srcnativeicon->ni_Extra.Size > 0) {
172 mem->ni_Extra = srcnativeicon->ni_Extra;
173 mem->ni_Extra.Data = MemDupIcon(dobj, srcnativeicon->ni_Extra.Data, srcnativeicon->ni_Extra.Size,IconBase);
174 if (!mem->ni_Extra.Data) goto fail;
177 for (i = 0; i < 2; i++)
179 struct NativeIconImage *src, *dst;
181 src = &srcnativeicon->ni_Image[i];
182 dst = &mem->ni_Image[i];
184 if (src->ARGB) {
185 dst->ARGB = MemDupIcon(dobj, src->ARGB, srcnativeicon->ni_Face.Width * srcnativeicon->ni_Face.Height * 4, IconBase);
186 if (!dst->ARGB)
187 goto fail;
190 dst->Pens = src->Pens;
191 dst->TransparentColor = src->TransparentColor;
193 /* Clone Palette, if we have pens allocated */
194 if (src->Palette && src->Pens)
196 dst->Palette = MemDupIcon(dobj, src->Palette, src->Pens * sizeof(struct ColorRegister),IconBase);
197 if (!dst->Palette) goto fail;
200 if (src->ImageData) {
201 dst->ImageData = MemDupIcon(dobj, src->ImageData, srcnativeicon->ni_Face.Width * srcnativeicon->ni_Face.Height * sizeof(UBYTE), IconBase);
202 if (!dst->ImageData) goto fail;
205 /* Do *not* clone the screen specific layout */
206 dst->BitMap = NULL;
207 dst->BitMask = NULL;
208 dst->Pen = NULL;
210 } /* if (srcnativeicon && GetTagData(ICONDUPA_DuplicateImageData, TRUE, tags) == TRUE) */
212 #ifdef OUTPUT_DATA
213 kprintf("gadgetwidth = %ld\ngadgetheight = %ld\n",dobj->do_Gadget.Width,dobj->do_Gadget.Height);
214 #endif
216 /* and now the pointers and the rest */
217 /* TODO: check for errors here */
219 if (GetTagData(ICONDUPA_DuplicateDefaultTool, TRUE, tags) &&
220 dobj->do_DefaultTool)
222 dobj->do_DefaultTool = StrDupIcon(dobj,icon->do_DefaultTool,IconBase);
223 if (!dobj->do_DefaultTool) goto fail;
226 if (GetTagData(ICONDUPA_DuplicateToolWindow, TRUE, tags) &&
227 dobj->do_ToolWindow)
229 dobj->do_ToolWindow = StrDupIcon(dobj,icon->do_ToolWindow,IconBase);
230 if (!dobj->do_ToolWindow) goto fail;
233 if (GetTagData(ICONDUPA_DuplicateDrawerData, TRUE, tags) &&
234 icon->do_DrawerData)
236 LONG size;
238 dobj->do_DrawerData = AllocMemIcon(dobj, sizeof(struct DrawerData), MEMF_PUBLIC);
239 if (!dobj->do_DrawerData) goto fail;
241 if (((SIPTR)icon->do_Gadget.UserData > 0) &&
242 ((SIPTR)icon->do_Gadget.UserData <= WB_DISKREVISION))
244 size = sizeof(struct DrawerData);
246 else
248 size = sizeof(struct OldDrawerData);
251 memset(dobj->do_DrawerData, 0, sizeof(struct DrawerData));
252 memcpy(dobj->do_DrawerData, icon->do_DrawerData, size);
255 /* Duplicate the image data */
257 if (icon->do_Gadget.GadgetRender)
259 dobj->do_Gadget.GadgetRender = ImageDupIcon(dobj, (struct Image*)icon->do_Gadget.GadgetRender,
260 GetTagData(ICONDUPA_DuplicateImages, TRUE, tags),
261 GetTagData(ICONDUPA_DuplicateImageData, TRUE, tags),IconBase);
262 if (!dobj->do_Gadget.GadgetRender) goto fail;
265 if (icon->do_Gadget.SelectRender)
267 dobj->do_Gadget.SelectRender = ImageDupIcon(dobj, (struct Image*)icon->do_Gadget.SelectRender,
268 GetTagData(ICONDUPA_DuplicateImages, TRUE, tags),
269 GetTagData(ICONDUPA_DuplicateImageData, TRUE, tags),IconBase);
270 if (!dobj->do_Gadget.SelectRender) goto fail;
273 /* Duplicate the tool types */
274 if (GetTagData(ICONDUPA_DuplicateToolTypes, TRUE, tags) &&
275 icon->do_ToolTypes)
277 int num_tts;
278 /* Get number of tool types */
279 for (num_tts = 0;icon->do_ToolTypes[num_tts];num_tts++);
281 if ((dobj->do_ToolTypes = (STRPTR *)AllocMemIcon(dobj,sizeof(char*)*(num_tts+1), MEMF_PUBLIC)))
283 int i;
284 for (i=0;i<num_tts;i++)
286 dobj->do_ToolTypes[i] = StrDupIcon(dobj,icon->do_ToolTypes[i],IconBase);
287 if (!dobj->do_ToolTypes[i]) goto fail;
289 dobj->do_ToolTypes[i] = NULL;
291 else
293 goto fail;
297 if (GetTagData(ICONDUPA_ActivateImageData, FALSE, tags))
298 LayoutIconA(dobj, LB(IconBase)->ib_Screen, NULL);
300 D(bug("%s: Icon %p => %p\n", __func__, icon, dobj));
302 return dobj;
304 fail:
305 FreeDiskObject(dobj);
306 return NULL;
308 AROS_LIBFUNC_EXIT
309 } /* FreeDiskObject */