2 Copyright (C) 2013, The AROS Development Team.
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/memory.h>
10 #include <hidd/hidd.h>
11 #include <libraries/asl.h>
12 #include <mui/NListtree_mcc.h>
13 #include <mui/NListview_mcc.h>
14 #include <utility/tagitem.h>
15 #include <utility/hooks.h>
17 #include <proto/alib.h>
18 #include <proto/dos.h>
19 #include <proto/exec.h>
20 #include <proto/muimaster.h>
21 #include <proto/oop.h>
22 #include <proto/utility.h>
23 #include <proto/intuition.h>
32 #include <aros/debug.h>
34 #define APPNAME "SysExplorer"
35 #define VERSION "SysExplorer 0.2"
40 struct MUI_CustomClass
*winClass
;
44 struct InsertObjectMsg
47 struct MUI_CustomClass
*winClass
;
53 struct MUI_CustomClass
**muiClass
;
54 void (*enumFunc
)(OOP_Object
*obj
, struct MUI_NListtree_TreeNode
*parent
);
57 static const struct ClassHandlers
*FindClassHandler(OOP_Object
*obj
);
59 const char version
[] = "$VER: " VERSION
" (" ADATE
")\n";
61 static Object
*app
, *main_window
, *property_window
, *hidd_tree
;
62 static Object
*property_menu
, *expand_menu
, *collapse_menu
, *quit_menu
;
64 OOP_AttrBase HiddAttrBase
;
65 OOP_AttrBase HWAttrBase
;
66 OOP_AttrBase HiddATABusAB
;
67 OOP_AttrBase HiddATAUnitAB
;
69 const struct OOP_ABDescr abd
[] =
71 {IID_Hidd
, &HiddAttrBase
},
72 {IID_HW
, &HWAttrBase
},
73 {IID_Hidd_ATABus
, &HiddATABusAB
},
74 {IID_Hidd_ATAUnit
, &HiddATAUnitAB
},
78 /* Here we have enumerators for different device and subsystem classes */
80 static void addATAUnit(OOP_Object
*dev
, ULONG attrID
, struct MUI_NListtree_TreeNode
*parent
)
82 OOP_Object
*unit
= NULL
;
84 OOP_GetAttr(dev
, attrID
, (IPTR
*)&unit
);
87 struct InsertObjectMsg msg
=
90 .winClass
= ATAUnitWindow_CLASS
94 OOP_GetAttr(unit
, aHidd_ATAUnit_Model
, (IPTR
*)&name
);
95 DoMethod(hidd_tree
, MUIM_NListtree_Insert
, name
, &msg
,
96 parent
, MUIV_NListtree_Insert_PrevNode_Tail
, 0);
100 static void ataUnitsEnum(OOP_Object
*dev
, struct MUI_NListtree_TreeNode
*parent
)
102 addATAUnit(dev
, aHidd_ATABus_Master
, parent
);
103 addATAUnit(dev
, aHidd_ATABus_Slave
, parent
);
106 AROS_UFH3S(BOOL
, enumFunc
,
107 AROS_UFHA(struct Hook
*, h
, A0
),
108 AROS_UFHA(OOP_Object
*, obj
, A2
),
109 AROS_UFHA(void *, parent
, A1
))
113 CONST_STRPTR name
= NULL
;
114 struct MUI_NListtree_TreeNode
*tn
;
116 struct InsertObjectMsg msg
=
121 const struct ClassHandlers
*clHandlers
= FindClassHandler(obj
);
123 /* This is either HW or HIDD subclass */
124 OOP_GetAttr(obj
, aHW_ClassName
, (IPTR
*)&name
);
126 OOP_GetAttr(obj
, aHidd_HardwareName
, (IPTR
*)&name
);
130 if (clHandlers
->muiClass
)
131 msg
.winClass
= *(clHandlers
->muiClass
);
132 if (clHandlers
->enumFunc
)
133 flags
= TNF_LIST
|TNF_OPEN
;
136 tn
= (APTR
)DoMethod(hidd_tree
, MUIM_NListtree_Insert
, name
, &msg
,
137 parent
, MUIV_NListtree_Insert_PrevNode_Tail
, flags
);
138 D(bug("Inserted TreeNode 0x%p <%s> UserData 0x%p\n", tn
, tn
->tn_Name
, tn
->tn_User
));
140 /* If we have enumerator for this class, call it now */
141 if (clHandlers
&& clHandlers
->enumFunc
)
142 clHandlers
->enumFunc(obj
, tn
);
144 return FALSE
; /* Continue enumeration */
149 static const struct Hook enum_hook
=
154 static void hwEnum(OOP_Object
*obj
, struct MUI_NListtree_TreeNode
*tn
)
156 HW_EnumDrivers(obj
, (struct Hook
*)&enum_hook
, tn
);
160 * This table lists handlers for known public classes.
161 * It specifies information window class, as well as function
162 * to enumerate children objects for the class.
164 * For proper operation CLIDs in this table should
165 * be sorted from subclasses to superclasses.
167 static const struct ClassHandlers classHandlers
[] =
169 {CLID_HW_Root
, &ComputerWindow_CLASS
, hwEnum
},
170 {CLID_HW
, NULL
, hwEnum
},
171 {CLID_Hidd_ATABus
, &ATAWindow_CLASS
, ataUnitsEnum
},
172 {CLID_Hidd
, &GenericWindow_CLASS
, NULL
},
173 {NULL
, NULL
, NULL
}
176 static const struct ClassHandlers
*FindClassHandler(OOP_Object
*obj
)
180 for (i
= 0; classHandlers
[i
].classID
; i
++)
184 for (cl
= OOP_OCLASS(obj
); cl
; cl
= cl
->superclass
)
186 if (!strcmp(cl
->ClassNode
.ln_Name
, classHandlers
[i
].classID
))
187 return &classHandlers
[i
];
193 AROS_UFH3S(void, closeFunc
,
194 AROS_UFHA(struct Hook
*, h
, A0
),
195 AROS_UFHA(Object
*, obj
, A2
),
196 AROS_UFHA(struct ObjectUserData
**, msg
, A1
))
200 D(bug("closeFunc address 0x%p\n", closeFunc
));
201 D(bug("Close window 0x%p, ObjectUserData 0x%p\n", obj
, *msg
));
203 SET(obj
, MUIA_Window_Open
, FALSE
);
204 DoMethod(app
, OM_REMMEMBER
, obj
);
205 DoMethod(app
, MUIM_Application_PushMethod
, obj
, 1, OM_DISPOSE
);
212 static const struct Hook close_hook
=
217 AROS_UFH3S(APTR
, constructFunc
,
218 AROS_UFHA(struct Hook
*, h
, A0
),
219 AROS_UFHA(Object
*, obj
, A2
),
220 AROS_UFHA(struct MUIP_NListtree_ConstructMessage
*, msg
, A1
))
224 struct InsertObjectMsg
*insertMsg
= msg
->UserData
;
225 struct ObjectUserData
*data
= AllocPooled(msg
->MemPool
, sizeof(struct ObjectUserData
));
227 D(bug("%s: insertMsg 0x%p ObjectUserData 0x%p\n", msg
->Name
, insertMsg
, data
));
230 data
->obj
= insertMsg
->obj
;
231 data
->winClass
= insertMsg
->winClass
;
239 AROS_UFH3S(void, destructFunc
,
240 AROS_UFHA(struct Hook
*, h
, A0
),
241 AROS_UFHA(Object
*, obj
, A2
),
242 AROS_UFHA(struct MUIP_NListtree_DestructMessage
*, msg
, A1
))
246 FreePooled(msg
->MemPool
, msg
->UserData
, sizeof(struct ObjectUserData
));
251 static const struct Hook constructHook
=
253 .h_Entry
= constructFunc
256 static const struct Hook destructHook
=
258 .h_Entry
= destructFunc
261 AROS_UFH3S(void, propertyFunc
,
262 AROS_UFHA(struct Hook
*, h
, A0
),
263 AROS_UFHA(Object
*, obj
, A2
),
264 AROS_UFHA(struct MUI_NListtree_TreeNode
**, tn
, A1
))
268 struct MUI_NListtree_TreeNode
*node
= *tn
;
269 struct ObjectUserData
*data
;
273 /* if we were called from menu we must 1st find the current entry */
274 node
= (struct MUI_NListtree_TreeNode
*)XGET(hidd_tree
, MUIA_NListtree_Active
);
279 /* Do nothing if still no current entry */
283 data
= node
->tn_User
;
284 D(bug("propertyFunc called: TreeNode 0x%p <%s> UserData 0x%p\n", node
, node
->tn_Name
, data
));
285 D(bug("Window 0x%p\n", data
->win
));
289 /* The window is already open, show it to the user */
290 DoMethod(data
->win
, MUIM_Window_ToFront
);
291 SET(data
->win
, MUIA_Window_Activate
, TRUE
);
297 /* We have information window class. Open the window. */
298 data
->win
= NewObject(data
->winClass
->mcc_Class
, NULL
,
299 MUIA_PropertyWin_Object
, (IPTR
)data
->obj
,
301 D(bug("Created window 0x%p\n", data
->win
));
305 DoMethod(app
, OM_ADDMEMBER
, data
->win
);
306 DoMethod(data
->win
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
308 MUIM_CallHook
, &close_hook
, data
);
309 SET(data
->win
, MUIA_Window_Open
, TRUE
);
316 static const struct Hook property_hook
=
318 .h_Entry
= propertyFunc
321 static BOOL
GUIinit()
325 app
= ApplicationObject
,
326 MUIA_Application_Title
, (IPTR
)APPNAME
,
327 MUIA_Application_Version
, (IPTR
)VERSION
,
328 MUIA_Application_Copyright
, (IPTR
)"(C) 2013, The AROS Development Team",
329 MUIA_Application_Author
, (IPTR
)"Pavel Fedin",
330 MUIA_Application_Base
, (IPTR
)APPNAME
,
331 MUIA_Application_Description
, __(MSG_DESCRIPTION
),
333 MUIA_Application_Menustrip
, (IPTR
)(MenustripObject
,
334 MUIA_Family_Child
, (IPTR
)(MenuObject
,
335 MUIA_Menu_Title
, __(MSG_MENU_PROJECT
),
336 MUIA_Family_Child
, (IPTR
)(property_menu
= MenuitemObject
,
337 MUIA_Menuitem_Title
, (IPTR
)"Properties",
339 MUIA_Family_Child
, (IPTR
)(expand_menu
= MenuitemObject
,
340 MUIA_Menuitem_Title
, (IPTR
)"Expand All",
342 MUIA_Family_Child
, (IPTR
)(collapse_menu
= MenuitemObject
,
343 MUIA_Menuitem_Title
, (IPTR
)"Collapse All",
345 MUIA_Family_Child
, (IPTR
)(quit_menu
= MenuitemObject
,
346 MUIA_Menuitem_Title
, __(MSG_MENU_QUIT
),
351 SubWindow
, (IPTR
)(main_window
= WindowObject
,
352 MUIA_Window_Title
, __(MSG_WINTITLE
),
353 MUIA_Window_ID
, MAKE_ID('S', 'Y', 'E', 'X'),
354 WindowContents
, (IPTR
)(HGroup
,
355 Child
, (IPTR
)(NListviewObject
,
356 MUIA_NListview_NList
, (IPTR
)(hidd_tree
= NListtreeObject
,
358 MUIA_CycleChain
, TRUE
,
359 MUIA_NListtree_ConstructHook
, (IPTR
)&constructHook
,
360 MUIA_NListtree_DestructHook
, (IPTR
)&destructHook
,
361 MUIA_NListtree_DragDropSort
, FALSE
, /* forbid sorting by drag'n'drop */
370 OOP_Object
*hwRoot
= OOP_NewObject(NULL
, CLID_HW_Root
, NULL
);
374 /* This will kick our recursive enumeration into action */
375 CALLHOOKPKT((struct Hook
*)&enum_hook
, hwRoot
, MUIV_NListtree_Insert_ListNode_Root
);
378 /* Quit application if the main window's closegadget or the esc key is pressed. */
379 DoMethod(main_window
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
381 MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
383 DoMethod(property_window
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
385 MUIM_Set
, MUIA_Window_Open
, FALSE
);
388 DoMethod(property_menu
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
390 MUIM_CallHook
, &property_hook
, 0);
392 DoMethod(expand_menu
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
394 MUIM_NListtree_Open
, MUIV_NListtree_Open_ListNode_Root
, MUIV_NListtree_Open_TreeNode_All
, 0);
396 DoMethod(collapse_menu
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
398 MUIM_NListtree_Close
, MUIV_NListtree_Close_ListNode_Root
, MUIV_NListtree_Close_TreeNode_All
, 0);
400 DoMethod(quit_menu
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
402 MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
404 DoMethod(hidd_tree
, MUIM_Notify
, MUIA_NListtree_DoubleClick
, MUIV_EveryTime
,
406 MUIM_CallHook
, &property_hook
, MUIV_TriggerValue
);
414 int __nocommandline
= 1;
418 if (!Locale_Initialize())
421 if (!OOP_ObtainAttrBases(abd
))
423 Locale_Deinitialize();
429 SET(main_window
, MUIA_Window_Open
, TRUE
);
431 if (XGET(main_window
, MUIA_Window_Open
))
433 DoMethod(app
, MUIM_Application_Execute
);
434 SET(main_window
, MUIA_Window_Open
, FALSE
);
440 OOP_ReleaseAttrBases(abd
);
442 Locale_Deinitialize();