Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / system / Wanderer / Classes / iconvolumelist.c
blobf9133168c91a236762250606259c09be28e0234d
1 /*
2 Copyright 2002-2009, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #ifndef __AROS__
7 #include "../portable_macros.h"
8 #define WANDERER_BUILTIN_ICONVOLUMELIST 1
9 #else
10 #define DEBUG 0
11 #include <aros/debug.h>
12 #endif
14 #define DEBUG_ILC_EVENTS
15 #define DEBUG_ILC_KEYEVENTS
16 #define DEBUG_ILC_ICONRENDERING
17 #define DEBUG_ILC_ICONSORTING
18 #define DEBUG_ILC_ICONSORTING_DUMP
19 #define DEBUG_ILC_ICONPOSITIONING
20 #define DEBUG_ILC_LASSO
21 #define DEBUG_ILC_MEMALLOC
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <math.h>
29 #include <dos/dos.h>
30 #include <dos/datetime.h>
31 #include <dos/filehandler.h>
32 #include <dos/filesystem.h>
34 #include <exec/memory.h>
35 #include <graphics/gfx.h>
36 #include <graphics/view.h>
37 #include <graphics/rpattr.h>
38 #include <workbench/icon.h>
39 #include <workbench/workbench.h>
41 #ifdef __AROS__
42 #include <devices/rawkeycodes.h>
43 #include <clib/alib_protos.h>
44 #endif
46 #include <proto/exec.h>
47 #include <proto/graphics.h>
48 #include <proto/utility.h>
49 #include <proto/dos.h>
50 #include <proto/icon.h>
51 #include <proto/layers.h>
52 #include <proto/dos.h>
53 #include <proto/iffparse.h>
55 #ifdef __AROS__
56 #include <prefs/prefhdr.h>
57 #include <prefs/wanderer.h>
58 #else
59 #include <prefs_AROS/prefhdr.h>
60 #include <prefs_AROS/wanderer.h>
61 #endif
63 #include <proto/cybergraphics.h>
65 #ifdef __AROS__
66 #include <cybergraphx/cybergraphics.h>
67 #else
68 #include <cybergraphx_AROS/cybergraphics.h>
69 #endif
72 #if defined(__AMIGA__) && !defined(__PPC__)
73 #define NO_INLINE_STDARG
74 #endif
75 #include <proto/intuition.h>
76 #include <proto/muimaster.h>
77 #include <libraries/mui.h>
78 //#include "muimaster_intern.h"
79 //#include "support.h"
80 //#include "imspec.h"
81 #include "iconlist_attributes.h"
82 #include "icon_attributes.h"
83 #include "iconlist.h"
84 #include "iconvolumelist_private.h"
86 #ifndef __AROS__
87 #define DEBUG 1
89 #ifdef DEBUG
90 #define D(x) if (DEBUG) x
91 #ifdef __amigaos4__
92 #define bug DebugPrintF
93 #else
94 #define bug kprintf
95 #endif
96 #else
97 #define D(...)
98 #endif
99 #endif
101 #define __DL_UNIT dl->dol_Ext.dol_AROS.dol_Unit
102 #define __DL_DEVICE dl->dol_Ext.dol_AROS.dol_Device
104 extern struct Library *MUIMasterBase;
106 struct DOSVolumeList
108 struct List dvl_List;
109 APTR dvl_Pool;
112 struct DOSVolumeNode
114 struct Node dvn_Node;
115 STRPTR dvn_VolName;
116 STRPTR dvn_DevName;
117 ULONG dvn_FLags;
118 struct Device *dvn_Device;
119 struct Unit *dvn_Unit;
120 struct MsgPort *dvn_Port;
123 ///IconVolumeList__CreateDOSList()
124 static struct DOSVolumeList *IconVolumeList__CreateDOSList(void)
126 APTR pool = NULL;
127 struct DosList *dl = NULL;
128 struct DOSVolumeNode *newdvn = NULL;
129 struct DOSVolumeList *newdvl = NULL;
131 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
133 if ((pool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, 4096, 4096)) != NULL)
135 if ((newdvl = (struct DOSVolumeList*)AllocPooled(pool, sizeof(struct DOSVolumeList))) != NULL)
137 NewList((struct List*)&newdvl->dvl_List);
138 newdvl->dvl_Pool = pool;
140 dl = LockDosList(LDF_VOLUMES|LDF_READ);
141 while(( dl = NextDosEntry(dl, LDF_VOLUMES)))
143 STRPTR vn_VolName;
145 UBYTE *dosname = (UBYTE*)AROS_BSTR_ADDR(dl->dol_Name);
146 LONG len = AROS_BSTR_strlen(dl->dol_Name);
148 if ((vn_VolName = (STRPTR)AllocPooled(newdvl->dvl_Pool, len + 2)))
150 newdvn = NULL;
152 vn_VolName[len] = ':';
153 vn_VolName[len + 1] = 0;
154 strncpy(vn_VolName, dosname, len);
156 if ((newdvn = (struct DOSVolumeNode*)AllocPooled(newdvl->dvl_Pool, sizeof(struct DOSVolumeNode))))
158 newdvn->dvn_VolName = vn_VolName;
159 newdvn->dvn_Device = __DL_DEVICE;
160 if ((newdvn->dvn_Unit = __DL_UNIT) == NULL)
162 D(bug("[IconVolumeList] %s: Volume '%s' is OFFLINE\n", __PRETTY_FUNCTION__, newdvn->dvn_VolName));
163 newdvn->dvn_FLags |= (ICONENTRY_VOL_OFFLINE|ICONENTRY_VOL_DISABLED);
166 D(bug("[IconVolumeList] %s: Registering Volume '%s' @ %p (Device '%s' @ 0x%p, Unit @ 0x%p) Type: %d\n", __PRETTY_FUNCTION__, newdvn->dvn_VolName, dl, dl->dol_Ext.dol_AROS.dol_Device->dd_Library.lib_Node.ln_Name, dl->dol_Ext.dol_AROS.dol_Device, newdvn->dvn_Unit, dl->dol_Type));
167 if (dl->dol_misc.dol_handler.dol_Startup)
169 struct FileSysStartupMsg *thisfs_SM = dl->dol_misc.dol_handler.dol_Startup;
170 D(bug("[IconVolumeList] %s: Startup msg @ 0x%p\n", __PRETTY_FUNCTION__, thisfs_SM));
171 D(bug("[IconVolumeList] %s: Startup Device @ %p, Unit %d\n", __PRETTY_FUNCTION__, thisfs_SM->fssm_Device, thisfs_SM->fssm_Unit));
174 if (dl->dol_Task != NULL)
176 D(bug("[IconVolumeList] %s: Packet Style device\n", __PRETTY_FUNCTION__));
177 newdvn->dvn_Port = dl->dol_Task;
179 #if defined(__AROS__)
180 else if (dl->dol_Ext.dol_AROS.dol_Device != NULL)
182 D(bug("[IconVolumeList] %s: IOFS Style device\n", __PRETTY_FUNCTION__));
183 newdvn->dvn_Port = dl->dol_Ext.dol_AROS.dol_Device;
185 #endif
186 else
188 D(bug("[IconVolumeList] %s: Unknown device type\n", __PRETTY_FUNCTION__));
190 AddTail((struct List*)&newdvl->dvl_List, (struct Node*)&newdvn->dvn_Node);
194 D(bug("[IconVolumeList] Finished registering volumes\n"));
195 UnLockDosList(LDF_VOLUMES|LDF_READ);
197 dl = LockDosList(LDF_DEVICES|LDF_READ);
198 while(( dl = NextDosEntry(dl, LDF_DEVICES)))
200 struct DOSVolumeNode *dvn = NULL;
201 char *nd_nambuf = NULL;
202 struct InfoData *nd_paramblock = NULL;
204 UBYTE *dosname = (UBYTE*)AROS_BSTR_ADDR(dl->dol_Name);
205 LONG len = AROS_BSTR_strlen(dl->dol_Name);
207 D(bug("[IconVolumeList] %s: Checking Device '%s' @ %p (Device ", __PRETTY_FUNCTION__, dosname, dl));
208 D(if (dl->dol_Ext.dol_AROS.dol_Device) bug("'%s' ", dl->dol_Ext.dol_AROS.dol_Device->dd_Library.lib_Node.ln_Name));
209 D(bug("@ 0x%p, Unit @ 0x%p) Type: %d\n", dl->dol_Ext.dol_AROS.dol_Device, __DL_UNIT, dl->dol_Type));
210 #if defined(__AROS__)
211 if (dl->dol_Ext.dol_AROS.dol_Device == NULL)
212 #else
213 if (dl->dol_Task == NULL)
214 #endif
216 D(bug("[IconVolumeList] %s: '%s' : handler inactive!\n", __PRETTY_FUNCTION__, dosname));
217 continue;
220 if ((nd_nambuf = AllocPooled(newdvl->dvl_Pool, len + 2)) != NULL)
222 strncpy(nd_nambuf, dosname, len);
223 nd_nambuf[len] = ':';
224 nd_nambuf[len + 1] = 0;
226 if ((nd_paramblock = AllocMem(sizeof(struct InfoData), MEMF_CLEAR|MEMF_PUBLIC)) != NULL)
228 struct IOFileSys *_iofs = NULL;
229 if ((_iofs = AllocMem(sizeof(struct IOFileSys), MEMF_CLEAR|MEMF_PUBLIC)) != NULL)
231 struct Process *me = (struct Process *)FindTask(NULL);
233 D(bug("[IconVolumeList] %s: Getting Info for '%s'\n", __PRETTY_FUNCTION__, nd_nambuf));
235 _iofs->IOFS.io_Message.mn_Node.ln_Type = 0;
236 _iofs->IOFS.io_Message.mn_ReplyPort = &me->pr_MsgPort;
237 _iofs->IOFS.io_Message.mn_Length = sizeof(struct IOFileSys);
238 _iofs->IOFS.io_Command = FSA_DISK_INFO;
240 _iofs->IOFS.io_Flags = IOF_QUICK;
242 _iofs->IOFS.io_Device = __DL_DEVICE;
243 _iofs->IOFS.io_Unit = __DL_UNIT;
245 _iofs->io_Union.io_INFO.io_Info = nd_paramblock;
247 DoIO(&_iofs->IOFS);
249 if (_iofs->io_DosError != 0)
251 D(bug("[IconVolumeList] %s: FSA_DISK_INFO returns error %08x\n", __PRETTY_FUNCTION__, _iofs->io_DosError));
252 FreeMem(nd_paramblock, sizeof(struct InfoData));
253 nd_paramblock = NULL;
255 FreeMem(_iofs, sizeof(struct IOFileSys));
257 else
259 D(bug("[IconVolumeList] %s: Failed to allocate IOFileSys storage\n", __PRETTY_FUNCTION__));
261 FreeMem(nd_paramblock, sizeof(struct InfoData));
262 nd_paramblock = NULL;
265 else
267 D(bug("[IconVolumeList] %s: Failed to allocate InfoData storage\n", __PRETTY_FUNCTION__, nd_nambuf));
270 D(bug("[IconVolumeList] %s: '%s' : Checking for Attached Volumes ... \n", __PRETTY_FUNCTION__, dosname));
271 /* Find the Volume attached to this device */
272 BOOL found = FALSE;
273 dvn = (struct DOSVolumeNode*)GetHead((struct List*)&newdvl->dvl_List);
274 while ((dvn))
276 if ((dvn->dvn_Port != NULL) &&
278 (dvn->dvn_Port == dl->dol_Task)
279 #if defined(__AROS__)
280 || (dvn->dvn_Port == dl->dol_Ext.dol_AROS.dol_Device)
281 #endif
284 if ((dvn->dvn_Unit) && ~(newdvn->dvn_FLags & ICONENTRY_VOL_OFFLINE))
286 if (dvn->dvn_Unit == __DL_UNIT)
288 if ((nd_paramblock) && (nd_paramblock->id_DiskType != ID_NO_DISK_PRESENT))
290 D(bug("[IconVolumeList] %s: '%s' : Device unit %d, state = %x, Vol node @ %p\n", __PRETTY_FUNCTION__, nd_nambuf, nd_paramblock->id_UnitNumber, nd_paramblock->id_DiskState, BADDR(nd_paramblock->id_VolumeNode)));
292 STRPTR nd_namext;
293 int nd_namext_len = 0;
295 found = TRUE;
296 dvn->dvn_FLags &= ~(ICONENTRY_VOL_OFFLINE|ICONENTRY_VOL_DISABLED);
298 if (nd_paramblock->id_DiskState == ID_VALIDATING)
300 D(bug("[IconVolumeList] %s: '%s' : Validating\n", __PRETTY_FUNCTION__, nd_nambuf));
301 nd_namext = "BUSY";
302 nd_namext_len = 4;
304 else
306 if (nd_paramblock->id_DiskState == ID_WRITE_PROTECTED)
308 D(bug("[IconVolumeList] %s: '%s' : Volume is WRITE-PROTECTED\n", __PRETTY_FUNCTION__, nd_nambuf));
309 dvn->dvn_FLags |= ICONENTRY_VOL_READONLY;
313 if (nd_namext_len > 0)
315 char *newVolName = NULL;
316 if ((newVolName = AllocPooled(newdvl->dvl_Pool, strlen(dvn->dvn_VolName) + nd_namext_len + 2)) != NULL)
318 sprintf(newVolName, "%s%s", dvn->dvn_VolName, nd_namext);
319 dvn->dvn_VolName = newVolName;
323 else
325 D(bug("[IconVolumeList] %s: '%s' : No Media Inserted (error state?)\n", __PRETTY_FUNCTION__, nd_nambuf));
327 dvn->dvn_DevName = nd_nambuf;
328 D(bug("[IconVolumeList] %s: DeviceName set to '%s' for '%s'\n", __PRETTY_FUNCTION__, dvn->dvn_DevName, dvn->dvn_VolName));
330 else
332 D(bug("[IconVolumeList] %s: '%s' : Volume not attached to this device .. skipping\n", __PRETTY_FUNCTION__, nd_nambuf));
336 dvn = (struct DOSVolumeNode*)GetSucc(dvn);
337 } /* dvn */
339 if (!(found))
341 D(bug("[IconVolumeList] %s: '%s' : Couldnt find an associated Volume\n", __PRETTY_FUNCTION__, nd_nambuf));
342 if ((nd_paramblock) && (nd_paramblock->id_DiskType != ID_NO_DISK_PRESENT))
344 if ((newdvn = (struct DOSVolumeNode *)AllocPooled(newdvl->dvl_Pool, sizeof(struct DOSVolumeNode))))
346 STRPTR nd_namext;
347 int nd_namext_len = 0;
349 newdvn->dvn_Unit = __DL_UNIT;
350 newdvn->dvn_Device = __DL_DEVICE;
352 switch (nd_paramblock->id_DiskType)
354 /*case ID_BUSY_DISK:
355 nd_namext = "BUSY";
356 nd_namext_len = 4;
357 break;*/
358 case ID_UNREADABLE_DISK:
359 nd_namext = "BAD";
360 nd_namext_len = 3;
361 break;
362 case ID_NOT_REALLY_DOS:
363 nd_namext = "NDOS";
364 nd_namext_len = 4;
365 break;
366 case ID_KICKSTART_DISK:
367 nd_namext = "KICK";
368 nd_namext_len = 4;
369 break;
371 if (nd_namext_len > 0)
373 if ((newdvn->dvn_VolName = AllocPooled(newdvl->dvl_Pool, strlen(nd_nambuf) + nd_namext_len + 2)) != NULL)
375 sprintf(newdvn->dvn_VolName, "%s%s", nd_nambuf, nd_namext);
376 newdvn->dvn_DevName = nd_nambuf;
377 newdvn->dvn_FLags |= ICONENTRY_VOL_DISABLED;
378 AddTail((struct List*)&newdvl->dvl_List, (struct Node*)&newdvn->dvn_Node);
381 else
383 D(bug("[IconVolumeList] %s: '%s' : Unknown Condition?\n", __PRETTY_FUNCTION__, nd_nambuf));
389 if (nd_paramblock)
390 FreeMem(nd_paramblock, sizeof(struct InfoData));
393 UnLockDosList(LDF_DEVICES|LDF_READ);
395 return newdvl;
397 DeletePool(pool);
399 return NULL;
403 ///IconVolumeList__DestroyDOSList()
404 static void IconVolumeList__DestroyDOSList(struct DOSVolumeList *dvl)
406 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
407 if (dvl && dvl->dvl_Pool) DeletePool(dvl->dvl_Pool);
410 /* sba: End SimpleFind3 */
412 ///OM_NEW()
413 /**************************************************************************
414 OM_NEW
415 **************************************************************************/
416 IPTR IconVolumeList__OM_NEW(struct IClass *CLASS, Object *obj, struct opSet *message)
418 struct IconDrawerList_DATA *data = NULL;
419 // struct TagItem *tag = NULL,
420 // *tags = NULL;
422 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
424 obj = (Object *)DoSuperNewTags(CLASS, obj, NULL,
425 TAG_MORE, (IPTR) message->ops_AttrList);
427 if (!obj)
428 return FALSE;
430 data = INST_DATA(CLASS, obj);
432 SET(obj, MUIA_IconList_DisplayFlags, ICONLIST_DISP_VERTICAL);
433 SET(obj, MUIA_IconList_SortFlags, ICONLIST_SORT_MASK);
435 D(bug("[IconVolumeList] obj @ %p\n", obj));
436 return (IPTR)obj;
440 struct IconEntry *FindIconlistIcon(struct List *iconlist, char *icondevname)
442 struct IconEntry *foundEntry = NULL;
444 ForeachNode(iconlist, foundEntry)
446 if (((strcasecmp(foundEntry->ie_IconNode.ln_Name, icondevname)) == 0) ||
447 ((strcasecmp(foundEntry->ie_IconListEntry.label, icondevname)) == 0))
448 return foundEntry;
450 return NULL;
453 ///MUIM_IconList_Update()
454 /**************************************************************************
455 MUIM_IconList_Update
456 **************************************************************************/
457 IPTR IconVolumeList__MUIM_IconList_Update(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Update *message)
459 //struct IconVolumeList_DATA *data = INST_DATA(CLASS, obj);
460 struct IconEntry *this_Icon = NULL;
461 struct DOSVolumeList *dvl = NULL;
462 struct DOSVolumeNode *dvn = NULL;
463 char *devname = NULL;
464 struct List *iconlist = NULL;
465 struct List newiconlist;
466 struct Node *tmpNode = NULL;
468 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
470 GET(obj, MUIA_Family_List, &iconlist);
472 if (iconlist != NULL)
474 NewList(&newiconlist);
476 if ((dvl = IconVolumeList__CreateDOSList()) != NULL)
478 D(bug("[IconVolumeList] %s: DOSVolumeList @ %p\n", __PRETTY_FUNCTION__, dvl));
480 #ifdef __AROS__
481 ForeachNode(dvl, dvn)
482 #else
483 Foreach_Node(dvl, dvn);
484 #endif
486 D(bug("[IconVolumeList] %s: DOSVolumeNode @ %p\n", __PRETTY_FUNCTION__, dvn));
487 if (dvn->dvn_VolName)
489 D(bug("[IconVolumeList] %s: DOSList Entry '%s'\n", __PRETTY_FUNCTION__, dvn->dvn_VolName));
490 struct DiskObject *volDOB = NULL;
492 if (dvn->dvn_FLags & ICONENTRY_VOL_OFFLINE)
493 devname = dvn->dvn_VolName;
494 else
495 devname = dvn->dvn_DevName;
497 D(bug("[IconVolumeList] %s: Processing '%s'\n", __PRETTY_FUNCTION__, devname));
499 if ((this_Icon = FindIconlistIcon(iconlist, devname)) != NULL)
501 BOOL entrychanged = FALSE;
502 volDOB = this_Icon->ie_DiskObj;
504 Remove((struct Node*)&this_Icon->ie_IconNode);
506 D(bug("[IconVolumeList] %s: Found existing IconEntry for '%s' @ %p\n", __PRETTY_FUNCTION__, this_Icon->ie_IconListEntry.label, this_Icon));
508 /* Compare the Icon and update as needed ... */
509 if (strcmp(this_Icon->ie_IconListEntry.label, dvn->dvn_VolName) != 0)
510 entrychanged = TRUE;
512 if ((this_Icon->ie_IconListEntry.udata) &&
513 (dvn->dvn_FLags != ((struct VolumeIcon_Private *)this_Icon->ie_IconListEntry.udata)->vip_FLags))
514 entrychanged = TRUE;
516 if ((dvn->dvn_FLags & ICONENTRY_VOL_DISABLED) && !(volDOB))
518 volDOB = GetIconTags
520 dvn->dvn_DevName,
521 ICONGETA_FailIfUnavailable, FALSE,
522 ICONGETA_GenerateImageMasks, TRUE,
523 TAG_DONE
527 if (entrychanged)
529 D(bug("[IconVolumeList] %s: IconEntry changed - updating..\n", __PRETTY_FUNCTION__));
530 this_Icon = (struct IconEntry *)DoMethod(obj, MUIM_IconList_UpdateEntry, this_Icon, (IPTR)devname, (IPTR)dvn->dvn_VolName, (IPTR)NULL, volDOB, ST_ROOT);
532 if (this_Icon)
533 AddTail(&newiconlist, (struct Node*)&this_Icon->ie_IconNode);
535 else
537 if (dvn->dvn_FLags & ICONENTRY_VOL_DISABLED)
539 volDOB = GetIconTags
541 dvn->dvn_DevName,
542 ICONGETA_FailIfUnavailable, FALSE,
543 ICONGETA_GenerateImageMasks, TRUE,
544 TAG_DONE
548 if ((this_Icon = (struct IconEntry *)DoMethod(obj, MUIM_IconList_CreateEntry, (IPTR)devname, (IPTR)dvn->dvn_VolName, (IPTR)NULL, volDOB, ST_ROOT)) != NULL)
550 struct VolumeIcon_Private *volPrivate = this_Icon->ie_IconListEntry.udata;
552 volPrivate->vip_FLags = dvn->dvn_FLags;
554 D(bug("[IconVolumeList] %s: Created IconEntry for '%s' @ %p\n", __PRETTY_FUNCTION__, this_Icon->ie_IconListEntry.label, this_Icon));
555 if (!(this_Icon->ie_Flags & ICONENTRY_FLAG_HASICON))
556 this_Icon->ie_Flags |= ICONENTRY_FLAG_HASICON;
558 if ((strcasecmp(dvn->dvn_VolName, "Ram Disk:")) == 0)
560 D(bug("[IconVolumeList] %s: Setting '%s' icon node priority to 5\n", __PRETTY_FUNCTION__, this_Icon->ie_IconListEntry.label));
561 this_Icon->ie_IconNode.ln_Pri = 5; // Special dirs get Priority 5
563 else
565 this_Icon->ie_IconNode.ln_Pri = 1; // Fixed Media get Priority 1
567 AddTail(&newiconlist, (struct Node*)&this_Icon->ie_IconNode);
569 else
571 D(bug("[IconVolumeList] %s: Failed to Add IconEntry for '%s'\n", __PRETTY_FUNCTION__, dvn->dvn_VolName));
574 } /* (dvn->dvn_VolName) */
576 IconVolumeList__DestroyDOSList(dvl);
577 ForeachNodeSafe(iconlist, this_Icon, tmpNode)
579 D(bug("[IconVolumeList] %s: Destroying Removed IconEntry for '%s' @ %p\n", __PRETTY_FUNCTION__, this_Icon->ie_IconListEntry.label, this_Icon));
580 Remove((struct Node*)&this_Icon->ie_IconNode);
581 DoMethod(obj, MUIM_IconList_DestroyEntry, this_Icon);
583 D(bug("[IconVolumeList] %s: Updating Icon List\n", __PRETTY_FUNCTION__));
584 ForeachNodeSafe(&newiconlist, this_Icon, tmpNode)
586 Remove((struct Node*)&this_Icon->ie_IconNode);
587 DoMethod(obj, MUIM_Family_AddTail, (struct Node*)&this_Icon->ie_IconNode);
591 /* default display/sorting flags */
592 DoMethod(obj, MUIM_IconList_Sort);
594 DoSuperMethodA(CLASS, obj, (Msg) message);
596 return 1;
600 IPTR IconVolumeList__MUIM_IconList_CreateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_CreateEntry *message)
602 struct IconEntry *this_Icon = NULL;
603 struct VolumeIcon_Private *volPrivate = NULL;
606 bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__);
608 if (message->icon_dob)
610 bug("[IconVolumeList] %s: Icon DiskObj @ %p\n", __PRETTY_FUNCTION__, message->icon_dob);
614 this_Icon = DoSuperMethodA(CLASS, obj, (Msg) message);
615 if ((this_Icon) && (this_Icon->ie_IconListEntry.type == ST_ROOT))
617 if ((volPrivate = AllocMem(sizeof(struct VolumeIcon_Private), MEMF_CLEAR)) != NULL)
619 this_Icon->ie_IconListEntry.udata = volPrivate;
621 else
623 DoMethod(obj, MUIM_IconList_DestroyEntry, this_Icon);
626 return this_Icon;
629 IPTR IconVolumeList__MUIM_IconList_UpdateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_UpdateEntry *message)
631 struct IconEntry *this_Icon = NULL;
632 struct VolumeIcon_Private *volPrivate = NULL;
634 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
636 this_Icon = DoSuperMethodA(CLASS, obj, (Msg) message);
638 return this_Icon;
641 IPTR IconVolumeList__MUIM_IconList_DestroyEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DestroyEntry *message)
643 struct VolumeIcon_Private *volPrivate = NULL;
644 IPTR rv = NULL;
646 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
648 volPrivate = message->icon->ie_IconListEntry.udata;
650 rv = DoSuperMethodA(CLASS, obj, (Msg) message);
652 if (volPrivate)
653 FreeMem(volPrivate, sizeof(struct VolumeIcon_Private));
655 return rv;
659 ///OM_GET()
660 /**************************************************************************
661 OM_GET
662 **************************************************************************/
663 IPTR IconVolumeList__OM_GET(struct IClass *CLASS, Object *obj, struct opGet *message)
665 #define STORE *(message->opg_Storage)
667 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
669 switch (message->opg_AttrID)
671 #warning "TODO: Get the version/revision from our config.."
672 case MUIA_Version: STORE = (IPTR)1; return 1;
673 case MUIA_Revision: STORE = (IPTR)3; return 1;
676 return DoSuperMethodA(CLASS, obj, (Msg) message);
677 #undef STORE
681 #if WANDERER_BUILTIN_ICONVOLUMELIST
682 BOOPSI_DISPATCHER(IPTR, IconVolumeList_Dispatcher, CLASS, obj, message)
684 #if !defined(__AROS__)
685 struct IClass *CLASS = cl;
686 Msg message = msg;
687 #endif
688 switch (message->MethodID)
690 case OM_NEW: return IconVolumeList__OM_NEW(CLASS, obj, (struct opSet *)message);
691 case OM_GET: return IconVolumeList__OM_GET(CLASS, obj, (struct opGet *)message);
692 case MUIM_IconList_Update: return IconVolumeList__MUIM_IconList_Update(CLASS, obj, (struct MUIP_IconList_Update *)message);
693 case MUIM_IconList_CreateEntry: return IconVolumeList__MUIM_IconList_CreateEntry(CLASS,obj,(APTR)message);
694 case MUIM_IconList_UpdateEntry: return IconVolumeList__MUIM_IconList_UpdateEntry(CLASS,obj,(APTR)message);
695 case MUIM_IconList_DestroyEntry: return IconVolumeList__MUIM_IconList_DestroyEntry(CLASS,obj,(APTR)message);
698 return DoSuperMethodA(CLASS, obj, message);
700 BOOPSI_DISPATCHER_END
702 #if defined(__AROS__)
703 /* Class descriptor. */
704 const struct __MUIBuiltinClass _MUI_IconVolumeList_desc = {
705 MUIC_IconVolumeList,
706 MUIC_IconList,
707 sizeof(struct IconVolumeList_DATA),
708 (void*)IconVolumeList_Dispatcher
710 #endif
711 #else
712 #if !defined(__AROS__)
713 struct MUI_CustomClass *initIconVolumeListClass(void)
715 return (struct MUI_CustomClass *) MUI_CreateCustomClass(NULL, NULL, IconList_Class, sizeof(struct IconVolumeList_DATA), ENTRY(IconVolumeList_Dispatcher));
717 #endif
718 #endif /* WANDERER_BUILTIN_ICONVOLUMELIST */