support clicking on column headers, and enable sorting based on name, date and size...
[AROS.git] / workbench / system / Wanderer / Classes / iconvolumelist.c
blobbe756f7bbd53f905a45912605c2b477f5fda1d1e
1 /*
2 Copyright 2002-2010, 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 /* work around to only start scanning dos list after all */
141 /* shared locks are gone, eg. in rom/dos/getdeviceproc.c RunHandler */
142 dl = LockDosList(LDF_VOLUMES|LDF_WRITE);
143 while(( dl = NextDosEntry(dl, LDF_VOLUMES)))
145 STRPTR vn_VolName;
147 UBYTE *dosname = (UBYTE*)AROS_BSTR_ADDR(dl->dol_Name);
148 LONG len = AROS_BSTR_strlen(dl->dol_Name);
150 if ((vn_VolName = (STRPTR)AllocPooled(newdvl->dvl_Pool, len + 2)))
152 newdvn = NULL;
154 vn_VolName[len] = ':';
155 vn_VolName[len + 1] = 0;
156 strncpy(vn_VolName, dosname, len);
158 if ((newdvn = (struct DOSVolumeNode*)AllocPooled(newdvl->dvl_Pool, sizeof(struct DOSVolumeNode))))
160 newdvn->dvn_VolName = vn_VolName;
161 newdvn->dvn_Device = __DL_DEVICE;
162 if ((newdvn->dvn_Unit = __DL_UNIT) == NULL)
164 D(bug("[IconVolumeList] %s: Volume '%s' is OFFLINE\n", __PRETTY_FUNCTION__, newdvn->dvn_VolName));
165 newdvn->dvn_FLags |= (ICONENTRY_VOL_OFFLINE|ICONENTRY_VOL_DISABLED);
168 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));
169 if (dl->dol_misc.dol_handler.dol_Startup)
171 struct FileSysStartupMsg *thisfs_SM = dl->dol_misc.dol_handler.dol_Startup;
172 D(bug("[IconVolumeList] %s: Startup msg @ 0x%p\n", __PRETTY_FUNCTION__, thisfs_SM));
173 D(bug("[IconVolumeList] %s: Startup Device @ %p, Unit %d\n", __PRETTY_FUNCTION__, thisfs_SM->fssm_Device, thisfs_SM->fssm_Unit));
176 if (dl->dol_Task != NULL)
178 D(bug("[IconVolumeList] %s: Packet Style device\n", __PRETTY_FUNCTION__));
179 newdvn->dvn_Port = dl->dol_Task;
181 #if defined(__AROS__)
182 else if (dl->dol_Ext.dol_AROS.dol_Device != NULL)
184 D(bug("[IconVolumeList] %s: IOFS Style device\n", __PRETTY_FUNCTION__));
185 newdvn->dvn_Port = dl->dol_Ext.dol_AROS.dol_Device;
187 #endif
188 else
190 D(bug("[IconVolumeList] %s: Unknown device type\n", __PRETTY_FUNCTION__));
192 AddTail((struct List*)&newdvl->dvl_List, (struct Node*)&newdvn->dvn_Node);
196 D(bug("[IconVolumeList] Finished registering volumes\n"));
197 UnLockDosList(LDF_VOLUMES|LDF_WRITE);
199 dl = LockDosList(LDF_DEVICES|LDF_READ);
200 while(( dl = NextDosEntry(dl, LDF_DEVICES)))
202 struct DOSVolumeNode *dvn = NULL;
203 char *nd_nambuf = NULL;
204 struct InfoData *nd_paramblock = NULL;
206 UBYTE *dosname = (UBYTE*)AROS_BSTR_ADDR(dl->dol_Name);
207 LONG len = AROS_BSTR_strlen(dl->dol_Name);
209 D(bug("[IconVolumeList] %s: Checking Device '%s' @ %p (Device ", __PRETTY_FUNCTION__, dosname, dl));
210 D(if (dl->dol_Ext.dol_AROS.dol_Device) bug("'%s' ", dl->dol_Ext.dol_AROS.dol_Device->dd_Library.lib_Node.ln_Name));
211 D(bug("@ 0x%p, Unit @ 0x%p) Type: %d\n", dl->dol_Ext.dol_AROS.dol_Device, __DL_UNIT, dl->dol_Type));
212 #if defined(__AROS__)
213 if (dl->dol_Ext.dol_AROS.dol_Device == NULL)
214 #else
215 if (dl->dol_Task == NULL)
216 #endif
218 D(bug("[IconVolumeList] %s: '%s' : handler inactive!\n", __PRETTY_FUNCTION__, dosname));
219 continue;
222 if ((nd_nambuf = AllocPooled(newdvl->dvl_Pool, len + 2)) != NULL)
224 strncpy(nd_nambuf, dosname, len);
225 nd_nambuf[len] = ':';
226 nd_nambuf[len + 1] = 0;
228 if ((nd_paramblock = AllocMem(sizeof(struct InfoData), MEMF_CLEAR|MEMF_PUBLIC)) != NULL)
230 struct IOFileSys *_iofs = NULL;
231 if ((_iofs = AllocMem(sizeof(struct IOFileSys), MEMF_CLEAR|MEMF_PUBLIC)) != NULL)
233 struct Process *me = (struct Process *)FindTask(NULL);
235 D(bug("[IconVolumeList] %s: Getting Info for '%s'\n", __PRETTY_FUNCTION__, nd_nambuf));
237 _iofs->IOFS.io_Message.mn_Node.ln_Type = 0;
238 _iofs->IOFS.io_Message.mn_ReplyPort = &me->pr_MsgPort;
239 _iofs->IOFS.io_Message.mn_Length = sizeof(struct IOFileSys);
240 _iofs->IOFS.io_Command = FSA_DISK_INFO;
242 _iofs->IOFS.io_Flags = IOF_QUICK;
244 _iofs->IOFS.io_Device = __DL_DEVICE;
245 _iofs->IOFS.io_Unit = __DL_UNIT;
247 _iofs->io_Union.io_INFO.io_Info = nd_paramblock;
249 DoIO(&_iofs->IOFS);
251 if (_iofs->io_DosError != 0)
253 D(bug("[IconVolumeList] %s: FSA_DISK_INFO returns error %08x\n", __PRETTY_FUNCTION__, _iofs->io_DosError));
254 FreeMem(nd_paramblock, sizeof(struct InfoData));
255 nd_paramblock = NULL;
257 FreeMem(_iofs, sizeof(struct IOFileSys));
259 else
261 D(bug("[IconVolumeList] %s: Failed to allocate IOFileSys storage\n", __PRETTY_FUNCTION__));
263 FreeMem(nd_paramblock, sizeof(struct InfoData));
264 nd_paramblock = NULL;
267 else
269 D(bug("[IconVolumeList] %s: Failed to allocate InfoData storage\n", __PRETTY_FUNCTION__, nd_nambuf));
272 D(bug("[IconVolumeList] %s: '%s' : Checking for Attached Volumes ... \n", __PRETTY_FUNCTION__, dosname));
273 /* Find the Volume attached to this device */
274 BOOL found = FALSE;
275 dvn = (struct DOSVolumeNode*)GetHead((struct List*)&newdvl->dvl_List);
276 while ((dvn))
278 if ((dvn->dvn_Port != NULL) &&
280 (dvn->dvn_Port == dl->dol_Task)
281 #if defined(__AROS__)
282 || (dvn->dvn_Port == dl->dol_Ext.dol_AROS.dol_Device)
283 #endif
286 if ((dvn->dvn_Unit) && ~(newdvn->dvn_FLags & ICONENTRY_VOL_OFFLINE))
288 if (dvn->dvn_Unit == __DL_UNIT)
290 if ((nd_paramblock) && (nd_paramblock->id_DiskType != ID_NO_DISK_PRESENT))
292 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)));
294 STRPTR nd_namext;
295 int nd_namext_len = 0;
297 found = TRUE;
298 dvn->dvn_FLags &= ~(ICONENTRY_VOL_OFFLINE|ICONENTRY_VOL_DISABLED);
300 if (nd_paramblock->id_DiskState == ID_VALIDATING)
302 D(bug("[IconVolumeList] %s: '%s' : Validating\n", __PRETTY_FUNCTION__, nd_nambuf));
303 nd_namext = "BUSY";
304 nd_namext_len = 4;
306 else
308 if (nd_paramblock->id_DiskState == ID_WRITE_PROTECTED)
310 D(bug("[IconVolumeList] %s: '%s' : Volume is WRITE-PROTECTED\n", __PRETTY_FUNCTION__, nd_nambuf));
311 dvn->dvn_FLags |= ICONENTRY_VOL_READONLY;
315 if (nd_namext_len > 0)
317 char *newVolName = NULL;
318 if ((newVolName = AllocPooled(newdvl->dvl_Pool, strlen(dvn->dvn_VolName) + nd_namext_len + 2)) != NULL)
320 sprintf(newVolName, "%s%s", dvn->dvn_VolName, nd_namext);
321 dvn->dvn_VolName = newVolName;
325 else
327 D(bug("[IconVolumeList] %s: '%s' : No Media Inserted (error state?)\n", __PRETTY_FUNCTION__, nd_nambuf));
329 dvn->dvn_DevName = nd_nambuf;
330 D(bug("[IconVolumeList] %s: DeviceName set to '%s' for '%s'\n", __PRETTY_FUNCTION__, dvn->dvn_DevName, dvn->dvn_VolName));
332 else
334 D(bug("[IconVolumeList] %s: '%s' : Volume not attached to this device .. skipping\n", __PRETTY_FUNCTION__, nd_nambuf));
338 dvn = (struct DOSVolumeNode*)GetSucc(dvn);
339 } /* dvn */
341 if (!(found))
343 D(bug("[IconVolumeList] %s: '%s' : Couldnt find an associated Volume\n", __PRETTY_FUNCTION__, nd_nambuf));
344 if ((nd_paramblock) && (nd_paramblock->id_DiskType != ID_NO_DISK_PRESENT))
346 if ((newdvn = (struct DOSVolumeNode *)AllocPooled(newdvl->dvl_Pool, sizeof(struct DOSVolumeNode))))
348 STRPTR nd_namext;
349 int nd_namext_len = 0;
351 newdvn->dvn_Unit = __DL_UNIT;
352 newdvn->dvn_Device = __DL_DEVICE;
354 switch (nd_paramblock->id_DiskType)
356 /*case ID_BUSY_DISK:
357 nd_namext = "BUSY";
358 nd_namext_len = 4;
359 break;*/
360 case ID_UNREADABLE_DISK:
361 nd_namext = "BAD";
362 nd_namext_len = 3;
363 break;
364 case ID_NOT_REALLY_DOS:
365 nd_namext = "NDOS";
366 nd_namext_len = 4;
367 break;
368 case ID_KICKSTART_DISK:
369 nd_namext = "KICK";
370 nd_namext_len = 4;
371 break;
373 if (nd_namext_len > 0)
375 if ((newdvn->dvn_VolName = AllocPooled(newdvl->dvl_Pool, strlen(nd_nambuf) + nd_namext_len + 2)) != NULL)
377 sprintf(newdvn->dvn_VolName, "%s%s", nd_nambuf, nd_namext);
378 newdvn->dvn_DevName = nd_nambuf;
379 newdvn->dvn_FLags |= ICONENTRY_VOL_DISABLED;
380 AddTail((struct List*)&newdvl->dvl_List, (struct Node*)&newdvn->dvn_Node);
383 else
385 D(bug("[IconVolumeList] %s: '%s' : Unknown Condition?\n", __PRETTY_FUNCTION__, nd_nambuf));
391 if (nd_paramblock)
392 FreeMem(nd_paramblock, sizeof(struct InfoData));
395 UnLockDosList(LDF_DEVICES|LDF_READ);
397 return newdvl;
399 DeletePool(pool);
401 return NULL;
405 ///IconVolumeList__DestroyDOSList()
406 static void IconVolumeList__DestroyDOSList(struct DOSVolumeList *dvl)
408 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
409 if (dvl && dvl->dvl_Pool) DeletePool(dvl->dvl_Pool);
412 /* sba: End SimpleFind3 */
414 ///OM_NEW()
415 /**************************************************************************
416 OM_NEW
417 **************************************************************************/
418 IPTR IconVolumeList__OM_NEW(struct IClass *CLASS, Object *obj, struct opSet *message)
420 struct IconDrawerList_DATA *data = NULL;
421 // struct TagItem *tag = NULL,
422 // *tags = NULL;
424 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
426 obj = (Object *)DoSuperNewTags(CLASS, obj, NULL,
427 TAG_MORE, (IPTR) message->ops_AttrList);
429 if (!obj)
430 return FALSE;
432 data = INST_DATA(CLASS, obj);
434 SET(obj, MUIA_IconList_DisplayFlags, ICONLIST_DISP_VERTICAL);
435 SET(obj, MUIA_IconList_SortFlags, MUIV_IconList_Sort_MASK);
437 D(bug("[IconVolumeList] obj @ %p\n", obj));
438 return (IPTR)obj;
442 struct IconEntry *FindIconlistVolumeIcon(struct List *iconlist, char *icondevname)
444 struct IconEntry *foundEntry = NULL;
446 ForeachNode(iconlist, foundEntry)
448 if ((foundEntry->ie_IconListEntry.type == ST_ROOT) && (((strcasecmp(foundEntry->ie_IconNode.ln_Name, icondevname)) == 0) ||
449 ((strcasecmp(foundEntry->ie_IconListEntry.label, icondevname)) == 0)))
450 return foundEntry;
452 return NULL;
455 ///MUIM_IconList_Update()
456 /**************************************************************************
457 MUIM_IconList_Update
458 **************************************************************************/
459 IPTR IconVolumeList__MUIM_IconList_Update(struct IClass *CLASS, Object *obj, struct MUIP_IconList_Update *message)
461 //struct IconVolumeList_DATA *data = INST_DATA(CLASS, obj);
462 struct IconEntry *this_Icon = NULL;
463 struct DOSVolumeList *dvl = NULL;
464 struct DOSVolumeNode *dvn = NULL;
465 char *devname = NULL;
466 struct List *iconlist = NULL;
467 struct List newiconlist;
468 struct Node *tmpNode = NULL;
470 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
472 GET(obj, MUIA_Family_List, &iconlist);
474 if (iconlist != NULL)
476 NewList(&newiconlist);
478 if ((dvl = IconVolumeList__CreateDOSList()) != NULL)
480 D(bug("[IconVolumeList] %s: DOSVolumeList @ %p\n", __PRETTY_FUNCTION__, dvl));
482 #ifdef __AROS__
483 ForeachNode(dvl, dvn)
484 #else
485 Foreach_Node(dvl, dvn);
486 #endif
488 D(bug("[IconVolumeList] %s: DOSVolumeNode @ %p\n", __PRETTY_FUNCTION__, dvn));
489 if (dvn->dvn_VolName)
491 D(bug("[IconVolumeList] %s: DOSList Entry '%s'\n", __PRETTY_FUNCTION__, dvn->dvn_VolName));
492 struct DiskObject *volDOB = NULL;
494 if (dvn->dvn_FLags & ICONENTRY_VOL_OFFLINE)
495 devname = dvn->dvn_VolName;
496 else
497 devname = dvn->dvn_DevName;
499 D(bug("[IconVolumeList] %s: Processing '%s'\n", __PRETTY_FUNCTION__, devname));
501 if ((this_Icon = FindIconlistVolumeIcon(iconlist, devname)) != NULL)
503 BOOL entrychanged = FALSE;
504 volDOB = this_Icon->ie_DiskObj;
506 Remove((struct Node*)&this_Icon->ie_IconNode);
508 D(bug("[IconVolumeList] %s: Found existing IconEntry for '%s' @ %p\n", __PRETTY_FUNCTION__, this_Icon->ie_IconListEntry.label, this_Icon));
510 /* Compare the Entry and update as needed ... */
511 if (strcmp(this_Icon->ie_IconListEntry.label, dvn->dvn_VolName) != 0)
512 entrychanged = TRUE;
514 if ((this_Icon->ie_IconListEntry.udata) &&
515 (dvn->dvn_FLags != ((struct VolumeIcon_Private *)this_Icon->ie_IconListEntry.udata)->vip_FLags))
516 entrychanged = TRUE;
518 if ((dvn->dvn_FLags & ICONENTRY_VOL_DISABLED) && !(volDOB))
520 volDOB = GetIconTags
522 dvn->dvn_DevName,
523 ICONGETA_FailIfUnavailable, FALSE,
524 ICONGETA_GenerateImageMasks, TRUE,
525 TAG_DONE
529 if (entrychanged)
531 D(bug("[IconVolumeList] %s: IconEntry changed - updating..\n", __PRETTY_FUNCTION__));
532 this_Icon = (struct IconEntry *)DoMethod(obj, MUIM_IconList_UpdateEntry, this_Icon, (IPTR)devname, (IPTR)dvn->dvn_VolName, (IPTR)NULL, volDOB, ST_ROOT);
534 if (this_Icon)
535 AddTail(&newiconlist, (struct Node*)&this_Icon->ie_IconNode);
537 else
539 if (dvn->dvn_FLags & ICONENTRY_VOL_DISABLED)
541 volDOB = GetIconTags
543 dvn->dvn_DevName,
544 ICONGETA_FailIfUnavailable, FALSE,
545 ICONGETA_GenerateImageMasks, TRUE,
546 TAG_DONE
550 if ((this_Icon = (struct IconEntry *)DoMethod(obj, MUIM_IconList_CreateEntry, (IPTR)devname, (IPTR)dvn->dvn_VolName, (IPTR)NULL, volDOB, ST_ROOT)) != NULL)
552 struct VolumeIcon_Private *volPrivate = this_Icon->ie_IconListEntry.udata;
554 volPrivate->vip_FLags = dvn->dvn_FLags;
556 D(bug("[IconVolumeList] %s: Created IconEntry for '%s' @ %p\n", __PRETTY_FUNCTION__, this_Icon->ie_IconListEntry.label, this_Icon));
557 if (!(this_Icon->ie_Flags & ICONENTRY_FLAG_HASICON))
558 this_Icon->ie_Flags |= ICONENTRY_FLAG_HASICON;
560 if ((strcasecmp(dvn->dvn_VolName, "Ram Disk:")) == 0)
562 D(bug("[IconVolumeList] %s: Setting '%s' entry node priority to 5\n", __PRETTY_FUNCTION__, this_Icon->ie_IconListEntry.label));
563 this_Icon->ie_IconNode.ln_Pri = 5; // Special dirs get Priority 5
565 else
567 this_Icon->ie_IconNode.ln_Pri = 2; // Fixed Media get Priority 2
569 AddTail(&newiconlist, (struct Node*)&this_Icon->ie_IconNode);
571 else
573 D(bug("[IconVolumeList] %s: Failed to Add IconEntry for '%s'\n", __PRETTY_FUNCTION__, dvn->dvn_VolName));
576 } /* (dvn->dvn_VolName) */
578 IconVolumeList__DestroyDOSList(dvl);
579 ForeachNodeSafe(iconlist, this_Icon, tmpNode)
581 if (this_Icon->ie_IconListEntry.type == ST_ROOT)
583 D(bug("[IconVolumeList] %s: Destroying Removed IconEntry for '%s' @ %p\n", __PRETTY_FUNCTION__, this_Icon->ie_IconListEntry.label, this_Icon));
584 Remove((struct Node*)&this_Icon->ie_IconNode);
585 DoMethod(obj, MUIM_IconList_DestroyEntry, this_Icon);
588 D(bug("[IconVolumeList] %s: Updating IconList\n", __PRETTY_FUNCTION__));
589 ForeachNodeSafe(&newiconlist, this_Icon, tmpNode)
591 Remove((struct Node*)&this_Icon->ie_IconNode);
592 DoMethod(obj, MUIM_Family_AddTail, (struct Node*)&this_Icon->ie_IconNode);
596 /* default display/sorting flags */
598 DoSuperMethodA(CLASS, obj, (Msg) message);
600 return 1;
604 IPTR IconVolumeList__MUIM_IconList_CreateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_CreateEntry *message)
606 struct IconEntry *this_Icon = NULL;
607 struct VolumeIcon_Private *volPrivate = NULL;
610 bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__);
612 if (message->entry_dob)
614 bug("[IconVolumeList] %s: Entry DiskObj @ %p\n", __PRETTY_FUNCTION__, message->entry_dob);
618 this_Icon = DoSuperMethodA(CLASS, obj, (Msg) message);
619 if ((this_Icon) && (this_Icon->ie_IconListEntry.type == ST_ROOT))
621 if ((volPrivate = AllocMem(sizeof(struct VolumeIcon_Private), MEMF_CLEAR)) != NULL)
623 this_Icon->ie_IconListEntry.udata = volPrivate;
625 else
627 DoMethod(obj, MUIM_IconList_DestroyEntry, this_Icon);
630 return this_Icon;
633 IPTR IconVolumeList__MUIM_IconList_UpdateEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_UpdateEntry *message)
635 struct IconEntry *this_Icon = NULL;
636 struct VolumeIcon_Private *volPrivate = NULL;
638 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
640 this_Icon = DoSuperMethodA(CLASS, obj, (Msg) message);
642 return this_Icon;
645 IPTR IconVolumeList__MUIM_IconList_DestroyEntry(struct IClass *CLASS, Object *obj, struct MUIP_IconList_DestroyEntry *message)
647 struct VolumeIcon_Private *volPrivate = NULL;
648 IPTR rv = NULL;
650 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
652 volPrivate = message->entry->ie_IconListEntry.udata;
654 rv = DoSuperMethodA(CLASS, obj, (Msg) message);
656 if (volPrivate)
657 FreeMem(volPrivate, sizeof(struct VolumeIcon_Private));
659 return rv;
663 ///OM_GET()
664 /**************************************************************************
665 OM_GET
666 **************************************************************************/
667 IPTR IconVolumeList__OM_GET(struct IClass *CLASS, Object *obj, struct opGet *message)
669 #define STORE *(message->opg_Storage)
671 D(bug("[IconVolumeList]: %s()\n", __PRETTY_FUNCTION__));
673 switch (message->opg_AttrID)
675 #warning "TODO: Get the version/revision from our config.."
676 case MUIA_Version: STORE = (IPTR)1; return 1;
677 case MUIA_Revision: STORE = (IPTR)3; return 1;
680 return DoSuperMethodA(CLASS, obj, (Msg) message);
681 #undef STORE
685 #if WANDERER_BUILTIN_ICONVOLUMELIST
686 BOOPSI_DISPATCHER(IPTR, IconVolumeList_Dispatcher, CLASS, obj, message)
688 #if !defined(__AROS__)
689 struct IClass *CLASS = cl;
690 Msg message = msg;
691 #endif
692 switch (message->MethodID)
694 case OM_NEW: return IconVolumeList__OM_NEW(CLASS, obj, (struct opSet *)message);
695 case OM_GET: return IconVolumeList__OM_GET(CLASS, obj, (struct opGet *)message);
696 case MUIM_IconList_Update: return IconVolumeList__MUIM_IconList_Update(CLASS, obj, (struct MUIP_IconList_Update *)message);
697 case MUIM_IconList_CreateEntry: return IconVolumeList__MUIM_IconList_CreateEntry(CLASS,obj,(APTR)message);
698 case MUIM_IconList_UpdateEntry: return IconVolumeList__MUIM_IconList_UpdateEntry(CLASS,obj,(APTR)message);
699 case MUIM_IconList_DestroyEntry: return IconVolumeList__MUIM_IconList_DestroyEntry(CLASS,obj,(APTR)message);
702 return DoSuperMethodA(CLASS, obj, message);
704 BOOPSI_DISPATCHER_END
706 #if defined(__AROS__)
707 /* Class descriptor. */
708 const struct __MUIBuiltinClass _MUI_IconVolumeList_desc = {
709 MUIC_IconVolumeList,
710 MUIC_IconList,
711 sizeof(struct IconVolumeList_DATA),
712 (void*)IconVolumeList_Dispatcher
714 #endif
715 #else
716 #if !defined(__AROS__)
717 struct MUI_CustomClass *initIconVolumeListClass(void)
719 return (struct MUI_CustomClass *) MUI_CreateCustomClass(NULL, NULL, IconList_Class, sizeof(struct IconVolumeList_DATA), ENTRY(IconVolumeList_Dispatcher));
721 #endif
722 #endif /* WANDERER_BUILTIN_ICONVOLUMELIST */