Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / icon / dupdiskobject.c
blobb9dd98ee59e4405db4ec481a987fe154886740f0
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
8 #include <workbench/icon.h>
9 #include <graphics/gfx.h>
10 #include <proto/arossupport.h>
11 #include "icon_intern.h"
13 /*#define OUTPUT_DATA*/
15 struct OldDrawerData
17 struct NewWindow dd_NewWindow;
18 LONG dd_CurrentX;
19 LONG dd_CurrentY;
23 STATIC STRPTR StrDupPooled(APTR pool, STRPTR str)
25 char *newstr;
26 if (!str) return NULL;
27 newstr = AllocPooled(pool,strlen(str)+1);
28 if (newstr) strcpy(newstr,str);
29 return newstr;
32 STATIC UBYTE *MemDupPooled(APTR pool, UBYTE *src, ULONG size)
34 UBYTE *newmem;
36 newmem = AllocPooled(pool, size);
37 if (newmem) memcpy(newmem, src, size);
39 return newmem;
42 STATIC struct Image *ImageDupPooled(APTR pool, struct Image *src)
44 struct Image *dest;
46 if (!src) return NULL;
48 dest = (struct Image*)AllocPooled(pool,sizeof(struct Image));
49 if (dest)
51 int data_size = 0;
52 int plane_size;
53 int i;
54 int plane_pick = src->PlanePick;
56 *dest = *src;
57 dest->NextImage = NULL;
59 /* Calc the size all used planes */
60 plane_size = RASSIZE(src->Width,src->Height);
61 for (i=0;i<8;i++)
63 if (plane_pick & 1) data_size += plane_size;
64 plane_pick >>= 1;
67 if ((dest->ImageData = AllocPooled(pool,data_size)))
69 memcpy(dest->ImageData,src->ImageData,data_size);
70 #ifdef OUTPUT_DATA
71 kprintf("plane_pick = %ld\n",src->PlanePick);
72 kprintf("width = %ld\n",src->Width);
73 kprintf("height = %ld\n",src->Height);
75 for (i=0;i<data_size;i++)
77 kprintf("0x%02lx,",((unsigned char*)src->ImageData)[i]);
78 if (i%16 == 15) kprintf("\n");
80 kprintf("\n");
81 #endif
82 return dest;
85 /* Something failed so we fail also */
86 FreePooled(pool,dest,sizeof(struct Image));
88 return NULL;
91 /*****************************************************************************
93 NAME */
94 #include <clib/icon_protos.h>
96 AROS_LH2(struct DiskObject *, DupDiskObjectA,
98 /* SYNOPSIS */
99 AROS_LHA(struct DiskObject *, icon, A0),
100 AROS_LHA(struct TagItem *, tags, A1),
102 /* LOCATION */
103 struct Library *, IconBase, 25, Icon)
105 /* FUNCTION
107 INPUTS
109 RESULT
111 NOTES
113 EXAMPLE
115 BUGS
117 SEE ALSO
119 INTERNALS
121 HISTORY
123 *****************************************************************************/
125 AROS_LIBFUNC_INIT
127 APTR pool;
128 struct NativeIcon *mem;
129 struct DiskObject *dobj;
131 if (!icon) return NULL;
133 pool = CreatePool(0,1024,1024);
134 if (!pool) return NULL;
136 /* AROS doesn't need the gfx to be placed in chip memory, so we can use pools */
137 mem = (struct NativeIcon *)AllocPooled(pool, sizeof(struct NativeIcon));
138 if (!mem) goto fail;
140 memset(mem, 0, sizeof(*mem));
142 mem->pool = pool;
143 dobj = &mem->dobj;
145 /* copy the contents */
146 *dobj = *icon;
148 if (GetTagData(ICONDUPA_JustLoadedFromDisk, FALSE, tags) != FALSE)
150 struct NativeIcon *srcnativeicon;
152 srcnativeicon = NATIVEICON(icon);
154 mem->icon35 = srcnativeicon->icon35;
156 /* Clone image data */
158 if (srcnativeicon->icon35.img1.imagedata)
160 mem->icon35.img1.imagedata = MemDupPooled(pool,
161 srcnativeicon->icon35.img1.imagedata,
162 srcnativeicon->icon35.width * srcnativeicon->icon35.height);
164 if (!mem->icon35.img1.imagedata) goto fail;
167 if (srcnativeicon->icon35.img2.imagedata)
169 mem->icon35.img2.imagedata = MemDupPooled(pool,
170 srcnativeicon->icon35.img2.imagedata,
171 srcnativeicon->icon35.width * srcnativeicon->icon35.height);
173 if (!mem->icon35.img2.imagedata) goto fail;
176 /* Clone Image Mask */
178 if (srcnativeicon->icon35.img1.mask)
180 mem->icon35.img1.mask = MemDupPooled(pool,
181 srcnativeicon->icon35.img1.mask,
182 RASSIZE(srcnativeicon->icon35.width, srcnativeicon->icon35.height));
185 if (srcnativeicon->icon35.img2.mask)
187 mem->icon35.img2.mask = MemDupPooled(pool,
188 srcnativeicon->icon35.img2.mask,
189 RASSIZE(srcnativeicon->icon35.width, srcnativeicon->icon35.height));
192 /* Clone Palette */
194 if (srcnativeicon->icon35.img1.palette)
196 mem->icon35.img1.palette = MemDupPooled(pool,
197 srcnativeicon->icon35.img1.palette,
198 srcnativeicon->icon35.img1.numcolors * sizeof(struct ColorRegister));
199 if (!mem->icon35.img1.palette) goto fail;
202 if (srcnativeicon->icon35.img2.palette && (srcnativeicon->icon35.img2.flags & IMAGE35F_HASPALETTE))
204 mem->icon35.img2.palette = MemDupPooled(pool,
205 srcnativeicon->icon35.img2.palette,
206 srcnativeicon->icon35.img2.numcolors * sizeof(struct ColorRegister));
207 if (!mem->icon35.img2.palette) goto fail;
209 else if (srcnativeicon->icon35.img1.palette)
211 /* Both images use same palette which is kept in memory only once */
212 mem->icon35.img2.palette = mem->icon35.img1.palette;
215 /* Clone PNGIcon data */
217 mem->iconPNG = srcnativeicon->iconPNG;
219 if (srcnativeicon->iconPNG.filebuffer)
221 mem->iconPNG.filebuffer = MemDupPooled(pool,
222 srcnativeicon->iconPNG.filebuffer,
223 srcnativeicon->iconPNG.filebuffersize);
225 if (!mem->iconPNG.filebuffer) goto fail;
228 if (srcnativeicon->iconPNG.img1)
230 mem->iconPNG.img1 = MemDupPooled(pool,
231 srcnativeicon->iconPNG.img1,
232 srcnativeicon->iconPNG.width * srcnativeicon->iconPNG.height * sizeof(ULONG));
234 if (!mem->iconPNG.img1) goto fail;
237 if (srcnativeicon->iconPNG.img2)
239 mem->iconPNG.img2 = MemDupPooled(pool,
240 srcnativeicon->iconPNG.img2,
241 srcnativeicon->iconPNG.width * srcnativeicon->iconPNG.height * sizeof(ULONG));
243 if (!mem->iconPNG.img2) goto fail;
246 } /* if (GetTagData(ICONDUPA_JustLoadedFromDisk, FALSE, tags) != FALSE) */
248 #ifdef OUTPUT_DATA
249 kprintf("gadgetwidth = %ld\ngadgetheight = %ld\n",dobj->do_Gadget.Width,dobj->do_Gadget.Height);
250 #endif
252 /* and now the pointers and the rest */
253 #warning TODO: check for errors here
255 if (dobj->do_DefaultTool)
257 dobj->do_DefaultTool = StrDupPooled(pool,icon->do_DefaultTool);
258 if (!dobj->do_DefaultTool) goto fail;
261 if (dobj->do_ToolWindow)
263 dobj->do_ToolWindow = StrDupPooled(pool,icon->do_ToolWindow);
264 if (!dobj->do_ToolWindow) goto fail;
267 if (icon->do_DrawerData)
269 LONG size;
271 dobj->do_DrawerData = AllocPooled(pool, sizeof(struct DrawerData));
272 if (!dobj->do_DrawerData) goto fail;
274 if (((LONG)icon->do_Gadget.UserData > 0) &&
275 ((LONG)icon->do_Gadget.UserData <= WB_DISKREVISION))
277 size = sizeof(struct DrawerData);
279 else
281 size = sizeof(struct OldDrawerData);
284 memset(dobj->do_DrawerData, 0, sizeof(struct DrawerData));
285 memcpy(dobj->do_DrawerData, icon->do_DrawerData, size);
288 /* Duplicate the image data */
290 if (icon->do_Gadget.GadgetRender)
292 dobj->do_Gadget.GadgetRender = ImageDupPooled(pool, (struct Image*)icon->do_Gadget.GadgetRender);
293 if (!dobj->do_Gadget.GadgetRender) goto fail;
296 if (icon->do_Gadget.SelectRender)
298 dobj->do_Gadget.SelectRender = ImageDupPooled(pool, (struct Image*)icon->do_Gadget.SelectRender);
299 if (!dobj->do_Gadget.SelectRender) goto fail;
302 /* Duplicate the tool types */
303 if (icon->do_ToolTypes)
305 int num_tts;
306 /* Get number of tool types */
307 for (num_tts = 0;icon->do_ToolTypes[num_tts];num_tts++);
309 if ((dobj->do_ToolTypes = (STRPTR *)AllocPooled(pool,sizeof(char*)*(num_tts+1))))
311 int i;
312 for (i=0;i<num_tts;i++)
314 dobj->do_ToolTypes[i] = StrDupPooled(pool,icon->do_ToolTypes[i]);
315 if (!dobj->do_ToolTypes[i]) goto fail;
317 dobj->do_ToolTypes[i] = NULL;
319 else
321 goto fail;
325 AddIconToList(mem, LB(IconBase));
327 return dobj;
329 fail:
330 DeletePool(pool);
331 return NULL;
333 AROS_LIBFUNC_EXIT
334 } /* FreeDiskObject */