2 Copyright 2002-2008, The AROS Development Team. All rights reserved.
7 #include "../portable_macros.h"
8 #define WANDERER_BUILTIN_ICONVOLUMELIST 1
10 #include <aros/debug.h>
13 #define DEBUG_ILC_EVENTS
14 #define DEBUG_ILC_KEYEVENTS
15 #define DEBUG_ILC_ICONRENDERING
16 #define DEBUG_ILC_ICONSORTING
17 #define DEBUG_ILC_ICONSORTING_DUMP
18 #define DEBUG_ILC_ICONPOSITIONING
19 #define DEBUG_ILC_LASSO
20 #define DEBUG_ILC_MEMALLOC
29 #include <dos/datetime.h>
30 #include <dos/filehandler.h>
32 #include <exec/memory.h>
33 #include <graphics/gfx.h>
34 #include <graphics/view.h>
35 #include <graphics/rpattr.h>
36 #include <workbench/icon.h>
37 #include <workbench/workbench.h>
40 #include <devices/rawkeycodes.h>
41 #include <clib/alib_protos.h>
44 #include <proto/exec.h>
45 #include <proto/graphics.h>
46 #include <proto/utility.h>
47 #include <proto/dos.h>
48 #include <proto/icon.h>
49 #include <proto/layers.h>
50 #include <proto/dos.h>
51 #include <proto/iffparse.h>
54 #include <prefs/prefhdr.h>
55 #include <prefs/wanderer.h>
57 #include <prefs_AROS/prefhdr.h>
58 #include <prefs_AROS/wanderer.h>
61 #include <proto/cybergraphics.h>
64 #include <cybergraphx/cybergraphics.h>
66 #include <cybergraphx_AROS/cybergraphics.h>
70 #if defined(__AMIGA__) && !defined(__PPC__)
71 #define NO_INLINE_STDARG
73 #include <proto/intuition.h>
74 #include <proto/muimaster.h>
75 #include <libraries/mui.h>
76 //#include "muimaster_intern.h"
77 //#include "support.h"
79 #include "iconlist_attributes.h"
80 //#include "icon_attributes.h"
82 #include "iconvolumelist_private.h"
88 #define D(x) if (DEBUG) x
90 #define bug DebugPrintF
99 #define __DL_UNIT dl->dol_Ext.dol_AROS.dol_Unit
101 extern struct Library
*MUIMasterBase
;
103 /* sba: taken from SimpleFind3 */
111 struct NewDOSVolumeNode
117 struct Device
*device
;
119 struct MsgPort
*port
;
122 ///IconVolumeList__CreateDOSList()
123 static struct NewDosList
*IconVolumeList__CreateDOSList(void)
125 APTR pool
= CreatePool(MEMF_PUBLIC
| MEMF_CLEAR
,4096,4096);
127 D(bug("[IconVolList]: %s()\n", __PRETTY_FUNCTION__
));
131 struct NewDosList
*ndl
= (struct NewDosList
*)AllocPooled(pool
, sizeof(struct NewDosList
));
134 struct DosList
*dl
= NULL
;
136 NewList((struct List
*)ndl
);
139 dl
= LockDosList(LDF_VOLUMES
|LDF_READ
);
140 while(( dl
= NextDosEntry(dl
, LDF_VOLUMES
)))
144 UBYTE
*dosname
= (UBYTE
*)AROS_BSTR_ADDR(dl
->dol_Name
);
145 LONG len
= AROS_BSTR_strlen(dl
->dol_Name
);
147 if ((vn_VolName
= (STRPTR
)AllocPooled(pool
, len
+ 2)))
149 struct NewDOSVolumeNode
*ndn
= NULL
;
151 vn_VolName
[len
] = ':';
152 vn_VolName
[len
+ 1] = 0;
153 strncpy(vn_VolName
, dosname
, len
);
155 if ((ndn
= (struct NewDOSVolumeNode
*)AllocPooled(pool
, sizeof(*ndn
))))
157 ndn
->vn_VolName
= vn_VolName
;
158 ndn
->unit
= __DL_UNIT
;
159 D(bug("[IconVolList] %s: Registering Volume '%s' @ %p (Device '%s' @ 0x%p, Unit @ 0x%p) Type: %d\n", __PRETTY_FUNCTION__
, ndn
->vn_VolName
, dl
, dl
->dol_Ext
.dol_AROS
.dol_Device
->dd_Library
.lib_Node
.ln_Name
, dl
->dol_Ext
.dol_AROS
.dol_Device
, ndn
->unit
, dl
->dol_Type
));
160 if (dl
->dol_misc
.dol_handler
.dol_Startup
)
162 struct FileSysStartupMsg
*thisfs_SM
= dl
->dol_misc
.dol_handler
.dol_Startup
;
163 D(bug("[IconVolList] %s: Startup msg @ 0x%p\n", __PRETTY_FUNCTION__
, thisfs_SM
));
164 D(bug("[IconVolList] %s: Startup Device @ %p, Unit %d\n", __PRETTY_FUNCTION__
, thisfs_SM
->fssm_Device
, thisfs_SM
->fssm_Unit
));
167 if (dl
->dol_Task
!= NULL
)
169 ndn
->port
= dl
->dol_Task
;
170 D(bug("[IconVolList] %s: Packet Style device\n", __PRETTY_FUNCTION__
));
172 #if defined(__AROS__)
173 else if (dl
->dol_Ext
.dol_AROS
.dol_Device
!= NULL
)
175 D(bug("[IconVolList] %s: IOFS Style device\n", __PRETTY_FUNCTION__
));
176 ndn
->port
= dl
->dol_Ext
.dol_AROS
.dol_Device
;
181 D(bug("[IconVolList] %s: Unknown device type\n", __PRETTY_FUNCTION__
));
183 AddTail((struct List
*)ndl
, (struct Node
*)ndn
);
187 UnLockDosList(LDF_VOLUMES
|LDF_READ
);
189 dl
= LockDosList(LDF_DEVICES
|LDF_READ
);
190 while(( dl
= NextDosEntry(dl
, LDF_DEVICES
)))
192 struct NewDOSVolumeNode
*ndn
= NULL
;
193 char *nd_nambuf
= NULL
;
194 BPTR nd_lock
= (BPTR
)NULL
;
195 struct InfoData
*nd_paramblock
= NULL
;
197 UBYTE
*dosname
= (UBYTE
*)AROS_BSTR_ADDR(dl
->dol_Name
);
198 LONG len
= AROS_BSTR_strlen(dl
->dol_Name
);
200 D(bug("[IconVolList] %s: Checking Device '%s' @ %p (Device '%s' @ 0x%p, Unit @ 0x%p) Type: %d\n", __PRETTY_FUNCTION__
, dosname
, dl
, dl
->dol_Ext
.dol_AROS
.dol_Device
->dd_Library
.lib_Node
.ln_Name
, dl
->dol_Ext
.dol_AROS
.dol_Device
, __DL_UNIT
, dl
->dol_Type
));
201 #if defined(__AROS__)
202 if ((dl
->dol_Task
== NULL
) && (dl
->dol_Ext
.dol_AROS
.dol_Device
!= NULL
))
204 D(bug("[IconVolList] %s: '%s' : IOFS Device\n", __PRETTY_FUNCTION__
, dosname
));
208 if (dl
->dol_Task
== NULL
)
210 D(bug("[IconVolList] %s: '%s' : dol_Task == NULL!\n", __PRETTY_FUNCTION__
, dosname
));
215 D(bug("[IconVolList] %s: '%s' : Packet Device\n", __PRETTY_FUNCTION__
, dosname
));
218 if ((nd_nambuf
= AllocPooled(pool
, len
+ 2)) != NULL
)
220 strncpy(nd_nambuf
, dosname
, len
);
221 nd_nambuf
[len
] = ':';
222 nd_nambuf
[len
+ 1] = 0;
223 ////sprintf(nd_nambuf, "%s:", dosname);
226 nd_paramblock
= NULL
;
228 D(bug("[IconVolList] %s: '%s' : Checking for Attached Volumes ... \n", __PRETTY_FUNCTION__
, dosname
));
229 /* Find the Volume attached to this device */
231 ndn
= (struct NewDOSVolumeNode
*)GetHead(ndl
);
234 if ((ndn
->port
!= NULL
) &&
236 (ndn
->port
== dl
->dol_Task
)
237 #if defined(__AROS__)
238 || (ndn
->port
== dl
->dol_Ext
.dol_AROS
.dol_Device
)
246 D(bug("[IconVolList] %s: '%s' : Attempting to Lock() device ... \n", __PRETTY_FUNCTION__
, dosname
));
247 if ((nd_lock
= Lock(nd_nambuf
, SHARED_LOCK
)) == NULL
)
249 D(bug("[IconVolList] %s: '%s' : Failed to obtain Lock()\n", __PRETTY_FUNCTION__
, dosname
));
252 if ((nd_lock
) && (nd_paramblock
== NULL
))
254 if ((nd_paramblock
= AllocMem(sizeof(struct InfoData
), MEMF_CLEAR
|MEMF_PUBLIC
)) == NULL
)
256 D(bug("[IconVolList] %s: '%s' : Failed to allocate storage for device paramblock\n", __PRETTY_FUNCTION__
, dosname
));
259 D(bug("[IconVolList] %s: Getting Info for '%s'\n", __PRETTY_FUNCTION__
, nd_nambuf
));
260 Info(nd_lock
, nd_paramblock
);
262 if (ndn
->unit
== __DL_UNIT
)
264 if ((nd_paramblock
) && (nd_paramblock
->id_DiskType
!= ID_NO_DISK_PRESENT
))
266 D(bug("[IconVolList] %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
)));
273 if (nd_paramblock
->id_DiskState
== ID_VALIDATING
)
275 D(bug("[IconVolList] %s: '%s' : Validating\n", __PRETTY_FUNCTION__
, nd_nambuf
));
281 if (nd_paramblock
->id_DiskState
== ID_WRITE_PROTECTED
)
283 ndn
->vn_FLags
|= ICONENTRY_VOL_READONLY
;
284 D(bug("[IconVolList] %s: '%s' : Volume is WRITE-PROTECTED\n", __PRETTY_FUNCTION__
, nd_nambuf
));
287 switch (nd_paramblock
->id_DiskType
)
290 case ID_UNREADABLE_DISK
:
294 case ID_NOT_REALLY_DOS
:
298 case ID_KICKSTART_DISK
:
303 /* A filesystem type.. ie ID_DOS_DISK */
309 if (nd_namext_len
> 0)
311 char *newVolName
= NULL
;
312 newVolName
= AllocPooled(pool
, strlen(ndn
->vn_VolName
) + nd_namext_len
+ 2);
313 sprintf(newVolName
, "%s%s", ndn
->vn_VolName
, nd_namext
);
314 ndn
->vn_VolName
= newVolName
;
319 D(bug("[IconVolList] %s: '%s' : No Media Inserted (error state?)\n", __PRETTY_FUNCTION__
, nd_nambuf
));
321 ndn
->vn_DevName
= nd_nambuf
;
322 D(bug("[IconVolList] %s: DeviceName set to '%s' for '%s'\n", __PRETTY_FUNCTION__
, ndn
->vn_DevName
, ndn
->vn_VolName
));
326 D(bug("[IconVolList] %s: '%s' : Volume not attached to this device .. skipping\n", __PRETTY_FUNCTION__
, nd_nambuf
));
331 D(bug("[IconVolList] %s: '%s' : Volume '%s' is OFFLINE\n", __PRETTY_FUNCTION__
, nd_nambuf
, ndn
->vn_VolName
));
332 ndn
->vn_FLags
|= ICONENTRY_VOL_OFFLINE
;
335 ndn
= (struct NewDOSVolumeNode
*)GetSucc(ndn
);
340 D(bug("[IconVolList] %s: '%s' : Couldnt find an associated Volume\n", __PRETTY_FUNCTION__
, nd_nambuf
));
344 FreeMem(nd_paramblock
, sizeof(struct InfoData
));
349 UnLockDosList(LDF_DEVICES
|LDF_READ
);
359 ///IconVolumeList__DestroyDOSList()
360 static void IconVolumeList__DestroyDOSList(struct NewDosList
*ndl
)
362 D(bug("[IconVolList]: %s()\n", __PRETTY_FUNCTION__
));
363 if (ndl
&& ndl
->pool
) DeletePool(ndl
->pool
);
366 /* sba: End SimpleFind3 */
369 /**************************************************************************
371 **************************************************************************/
372 IPTR
IconVolumeList__OM_NEW(struct IClass
*CLASS
, Object
*obj
, struct opSet
*message
)
374 struct IconDrawerList_DATA
*data
= NULL
;
375 // struct TagItem *tag = NULL,
378 D(bug("[IconVolList]: %s()\n", __PRETTY_FUNCTION__
));
380 obj
= (Object
*)DoSuperNewTags(CLASS
, obj
, NULL
,
381 TAG_MORE
, (IPTR
) message
->ops_AttrList
);
383 if (!obj
) return FALSE
;
385 data
= INST_DATA(CLASS
, obj
);
387 SET(obj
, MUIA_IconList_DisplayFlags
, ICONLIST_DISP_VERTICAL
);
388 SET(obj
, MUIA_IconList_SortFlags
, ICONLIST_SORT_MASK
);
390 D(bug("[IconVolList] obj = %ld\n", obj
));
395 ///MUIM_IconList_Update()
396 /**************************************************************************
398 **************************************************************************/
399 IPTR
IconVolumeList__MUIM_IconList_Update(struct IClass
*CLASS
, Object
*obj
, struct MUIP_IconList_Update
*message
)
401 //struct IconVolumeList_DATA *data = INST_DATA(CLASS, obj);
402 struct IconEntry
*this_Icon
= NULL
;
403 struct NewDosList
*ndl
= NULL
;
406 char *devname
= NULL
;
408 D(bug("[IconVolList]: %s()\n", __PRETTY_FUNCTION__
));
410 DoSuperMethodA(CLASS
, obj
, (Msg
) message
);
412 DoMethod(obj
, MUIM_IconList_Clear
);
414 if ((ndl
= IconVolumeList__CreateDOSList()) != NULL
)
416 struct NewDOSVolumeNode
*nd
= NULL
;
418 D(bug("[IconVolList] %s: DOSList @ %p\n", __PRETTY_FUNCTION__
, ndl
));
422 Foreach_Node(ndl
, nd
);
425 D(bug("[IconVolList] %s: DOSList Node @ %p\n", __PRETTY_FUNCTION__
, nd
));
428 D(bug("[IconVolList] %s: Adding icon for '%s'\n", __PRETTY_FUNCTION__
, nd
->vn_VolName
));
430 if (nd
->vn_FLags
& ICONENTRY_VOL_OFFLINE
)
431 devname
= nd
->vn_VolName
;
433 devname
= nd
->vn_DevName
;
435 if ((this_Icon
= (struct IconEntry
*)DoMethod(obj
, MUIM_IconList_CreateEntry
, (IPTR
)devname
, (IPTR
)nd
->vn_VolName
, (IPTR
)NULL
, (IPTR
)NULL
, ST_ROOT
)) == NULL
)
437 D(bug("[IconVolList] %s: Failed to Add IconEntry for '%s'\n", __PRETTY_FUNCTION__
, nd
->vn_VolName
));
441 if (!(this_Icon
->ile_Flags
& ICONENTRY_FLAG_HASICON
))
442 this_Icon
->ile_Flags
|= ICONENTRY_FLAG_HASICON
;
444 if ((strcasecmp(nd
->vn_VolName
, "Ram Disk:")) == 0)
446 D(bug("[IconVolList] %s: Setting Ram Disk's icon node priority to 5\n", __PRETTY_FUNCTION__
));
447 this_Icon
->ile_IconNode
.ln_Pri
= 5; // Special dirs get Priority 5
451 this_Icon
->ile_IconNode
.ln_Pri
= 1; // Fixed Media get Priority 1
454 } /* (nd->vn_VolName) */
456 IconVolumeList__DestroyDOSList(ndl
);
459 /* default display/sorting flags */
460 DoMethod(obj
, MUIM_IconList_Sort
);
466 #if WANDERER_BUILTIN_ICONVOLUMELIST
467 BOOPSI_DISPATCHER(IPTR
, IconVolumeList_Dispatcher
, CLASS
, obj
, message
)
469 #if !defined(__AROS__)
470 struct IClass
*CLASS
= cl
;
473 switch (message
->MethodID
)
475 case OM_NEW
: return IconVolumeList__OM_NEW(CLASS
, obj
, (struct opSet
*)message
);
476 case MUIM_IconList_Update
: return IconVolumeList__MUIM_IconList_Update(CLASS
,obj
,(APTR
)message
);
479 return DoSuperMethodA(CLASS
, obj
, message
);
481 BOOPSI_DISPATCHER_END
483 #if defined(__AROS__)
484 /* Class descriptor. */
485 const struct __MUIBuiltinClass _MUI_IconVolumeList_desc
= {
488 sizeof(struct IconVolumeList_DATA
),
489 (void*)IconVolumeList_Dispatcher
493 #if !defined(__AROS__)
494 struct MUI_CustomClass
*initIconVolumeListClass(void)
496 return (struct MUI_CustomClass
*) MUI_CreateCustomClass(NULL
, NULL
, IconList_Class
, sizeof(struct IconVolumeList_DATA
), ENTRY(IconVolumeList_Dispatcher
));
499 #endif /* WANDERER_BUILTIN_ICONVOLUMELIST */