copy more of the Mason prefs icons
[AROS.git] / rom / hidds / hidd / hwclass.c
blob350dcc754586174651743ea8b78513eb0a8dd2a9
1 /*
2 Copyright © 2013-2016, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
7 #include <hidd/hidd.h>
8 #include <oop/oop.h>
9 #include <utility/hooks.h>
10 #include <utility/tagitem.h>
11 #include <proto/exec.h>
12 #include <proto/oop.h>
13 #include <proto/utility.h>
15 #include "hiddclass_intern.h"
17 /*****************************************************************************************
19 NAME
20 --background_hwclass--
22 LOCATION
23 CLID_HW
25 NOTES
26 This class is a base class for all hardware subsystems in AROS. Its
27 main purpose is to manage hardware drivers.
29 A "subsystem" is a kind of devices, e. g. keyboards, mice, etc. This
30 class stores information about existing device instances and can provide
31 this information to user's software.
33 A typical subsystem class should be a singletone. This greatly simplifies
34 handling it.
36 *****************************************************************************************/
38 #define IS_HW_ATTR(attr, idx) ((idx = attr - HWAttrBase) < num_HW_Attrs)
40 /*****************************************************************************************
42 NAME
43 aoHW_ClassName
45 SYNOPSIS
46 [I.G], CONST_STRPTR
48 LOCATION
49 CLID_HW
51 FUNCTION
52 Query human-readable description of the class. E. g. "Keyboards".
54 NOTES
56 EXAMPLE
58 BUGS
60 SEE ALSO
62 INTERNALS
64 *****************************************************************************************/
65 /*****************************************************************************************
67 NAME
68 aoHW_InUse
70 SYNOPSIS
71 [..G], BOOL
73 LOCATION
74 CLID_HW
76 FUNCTION
77 Return TRUE if the subsystem is currently in use by some driver(s)
78 and FALSE otherwise.
80 NOTES
82 EXAMPLE
84 BUGS
86 SEE ALSO
88 INTERNALS
90 *****************************************************************************************/
92 OOP_Object *HW__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
94 struct Library *UtilityBase = CSD(cl)->cs_UtilityBase;
96 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, &msg->mID);
97 if (o)
99 struct HWData *data = OOP_INST_DATA(cl, o);
101 NEWLIST(&data->drivers);
102 InitSemaphore(&data->driver_lock);
104 data->name = (const char *)GetTagData(aHW_ClassName,
105 (IPTR)"Unknown hardware",
106 msg->attrList);
108 return o;
111 void HW__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
113 struct HWData *data = OOP_INST_DATA(cl, o);
114 IPTR idx;
116 if (IS_HW_ATTR(msg->attrID, idx))
118 switch (idx)
120 case aoHW_ClassName:
121 *msg->storage = (IPTR)data->name;
122 return;
124 case aoHW_InUse:
125 *msg->storage = IsListEmpty(&data->drivers) ? FALSE : TRUE;
126 return;
129 OOP_DoSuperMethod(cl, o, &msg->mID);
132 /*****************************************************************************************
134 NAME
135 moHW_AddDriver
137 SYNOPSIS
138 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHW_AddHardwareDriver *Msg);
140 OOP_Object *HW_AddDriver(OOP_Object *obj, OOP_Class *driverClass,
141 struct TagItem *tags);
143 LOCATION
144 CLID_HW
146 FUNCTION
147 Creates a hardware driver object and registers it in the subsystem.
149 INPUTS
150 obj - A subsystem object to operate on.
151 driverClass - A pointer to OOP class of the driver. In order to create an object
152 of some previously registered public class, use
153 oop.library/OOP_FindClass().
154 tags - An optional taglist which will be passed to driver class' New() method.
156 RESULT
157 A pointer to driver object or NULL in case of failure.
159 NOTES
160 Do not dispose the returned object yourself, use HW_RemoveDriver() for it.
162 EXAMPLE
164 BUGS
166 SEE ALSO
167 moHW_RemHardwareDriver
169 INTERNALS
171 *****************************************************************************************/
173 OOP_Object *HW__HW__AddDriver(OOP_Class *cl, OOP_Object *o,
174 struct pHW_AddDriver *msg)
176 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
177 struct HWData *data = OOP_INST_DATA(cl, o);
178 OOP_Object *drv = NULL;
179 struct DriverNode *dn;
181 D(bug("[HW] Adding Driver class 0x%p\n", msg->driverClass));
183 if (msg->driverClass != NULL)
185 // Get some extra memory for driver node
186 dn = AllocPooled(CSD(cl)->MemPool, sizeof(struct DriverNode));
187 if (dn)
189 drv = OOP_NewObject(msg->driverClass, NULL, msg->tags);
191 if (!drv)
193 FreePooled(CSD(cl)->MemPool, dn, sizeof(struct DriverNode));
194 D(bug("[HW] Driver did not initialize\n"));
195 return NULL;
198 if (HW_SetUpDriver(o, drv))
200 /* Add the driver to the end of drivers list */
201 dn->driverObject = drv;
202 ObtainSemaphore(&data->driver_lock);
203 ADDTAIL(&data->drivers, dn);
204 ReleaseSemaphore(&data->driver_lock);
206 return drv;
209 OOP_DisposeObject(drv);
212 return NULL;
215 /*****************************************************************************************
217 NAME
218 moHW_RemoveDriver
220 SYNOPSIS
221 void OOP_DoMethod(OOP_Object *obj, struct pHW_RemoveDriver *Msg);
223 void HW_RemoveDriver(OOP_Object *obj, OOP_Object *driver);
225 LOCATION
226 CLID_HW
228 FUNCTION
229 Unregisters and disposes hardware driver object.
231 INPUTS
232 obj - A subsystem object from which the driver should be removed.
233 driver - A pointer to a driver object, returned by HW_AddDriver().
235 RESULT
236 TRUE if removal successful or FALSE upon failure.
238 NOTES
239 The base class returns FALSE only if the driver is not registered
240 in the subsystem. However, subclasses implementing actual subsystems
241 can add their own checks, for example whether the driver currently
242 owns some objects which are in use, and thus cannot be disposed.
244 EXAMPLE
246 BUGS
248 SEE ALSO
249 moHW_AddDriver
251 INTERNALS
253 *****************************************************************************************/
255 BOOL HW__HW__RemoveDriver(OOP_Class *cl, OOP_Object *o,
256 struct pHW_RemoveDriver *msg)
258 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
259 struct HWData *data = OOP_INST_DATA(cl, o);
260 struct DriverNode *dn = NULL, *next = NULL, *rem = NULL;
262 D(bug("[HW] Removing hardware driver %p\n", msg->driverObject));
264 /* Get exclusive lock on driver list */
265 ObtainSemaphore(&data->driver_lock);
266 ForeachNodeSafe(&data->drivers, dn, next)
268 if (dn->driverObject == msg->driverObject)
270 Remove((struct Node *)dn);
271 rem = dn;
274 ReleaseSemaphore(&data->driver_lock);
276 /* If driver removed, rem contains pointer to removed DriverNode */
277 if (rem)
279 HW_CleanUpDriver(o, rem->driverObject);
281 /* Dispose driver */
282 OOP_DisposeObject(rem->driverObject);
283 /* And free memory for DriverNode */
284 FreePooled(CSD(cl)->MemPool, rem, sizeof(struct DriverNode));
287 D(bug("[HW] Mgr::RemHardwareDriver() %s\n", rem ? "succeeded" : "failed"));
289 return rem ? TRUE : FALSE;
292 /*****************************************************************************************
294 NAME
295 moHW_EnumDrivers
297 SYNOPSIS
298 void OOP_DoMethod(OOP_Object *obj, struct pHW_EnumDrivers *Msg);
300 void HW_EnumDrivers(OOP_Object *obj, struct Hook *callback, APTR hookMsg);
302 LOCATION
303 CLID_HW
305 FUNCTION
306 Enumerates all installed driver in the subsystem.
308 INPUTS
309 obj - A subsystem object to query.
310 callback - A user-supplied hook which will be called for every driver.
311 hookMsg - A user-defined data to be passed to the hook.
313 The hook will be called with the following parameters:
314 AROS_UFHA(struct Hook *, hook , A0)
315 - A pointer to hook structure itself
316 AROS_UFHA(OOP_Object * , driverObject, A2)
317 - A device driver object
318 AROS_UFHA(APTR , message , A1)
319 - User-defined data
321 The hook should return FALSE in order to continue enumeration
322 or TRUE in order to stop it.
324 RESULT
325 None.
327 NOTES
329 EXAMPLE
331 BUGS
333 SEE ALSO
335 INTERNALS
336 The function uses internal semaphore locking. Because of this,
337 it is illegal to attempt to add or remove drivers within the hook.
339 *****************************************************************************************/
341 void HW__HW__EnumDrivers(OOP_Class *cl, OOP_Object *o, struct pHW_EnumDrivers *msg)
343 struct HWData *data = OOP_INST_DATA(cl, o);
344 struct DriverNode *dn;
346 /* Lock driver list for shared use */
347 ObtainSemaphoreShared(&data->driver_lock);
349 /* For every driver in the system... */
350 ForeachNode(&data->drivers, dn)
353 * Explicit cast to BOOL makes it possible to declare the hook as
354 * returning BOOL, not IPTR. BOOL is 16-bit wide, so higher bits
355 * of result may carry random trash.
357 BOOL stop = CALLHOOKPKT(msg->callback, dn->driverObject, msg->hookMsg);
359 if (stop)
360 break;
363 ReleaseSemaphore(&data->driver_lock);
366 /*****************************************************************************************
368 NAME
369 moHW_SetUpDriver
371 SYNOPSIS
372 void OOP_DoMethod(OOP_Object *obj, struct pHW_SetUpDriver *Msg);
374 void HW_SetUpDriver(OOP_Object *obj, OOP_Object *driverObject);
376 LOCATION
377 CLID_HW
379 FUNCTION
380 Performs subsystem-specific setup after driver object creation.
381 This method is intended to be used only by subclasses of CLID_HW.
383 INPUTS
384 obj - A subsystem object.
385 driverObject - Device driver object.
387 RESULT
388 TRUE if setup completed successfully and FALSE in case of error.
389 If this method returns error, the driver object will be disposed
390 and moHW_AddDriver method will fail.
392 NOTES
393 In base class this method does nothing and always returns TRUE.
395 EXAMPLE
397 BUGS
399 SEE ALSO
400 moHW_CleanUpDriver
402 INTERNALS
404 *****************************************************************************************/
406 BOOL HW__HW__SetUpDriver(OOP_Class *cl, OOP_Object *o, struct pHW_SetUpDriver *msg)
408 /* By default we have nothing to do here */
409 return TRUE;
412 /*****************************************************************************************
414 NAME
415 moHW_CleanUpDriver
417 SYNOPSIS
418 void OOP_DoMethod(OOP_Object *obj, struct pHW_CleanUpDriver *Msg);
420 void HW_CleanUpDriver(OOP_Object *obj, OOP_Object *driverObject);
422 LOCATION
423 CLID_HW
425 FUNCTION
426 Performs subsystem-specific cleanup before driver object disposal.
427 This method is intended to be used only by subclasses of CLID_HW.
429 INPUTS
430 obj - A subsystem object.
431 driverObject - Device driver object.
433 RESULT
434 None.
436 NOTES
437 In base class this method does nothing.
439 EXAMPLE
441 BUGS
443 SEE ALSO
444 moHW_SetUpDriver
446 INTERNALS
448 *****************************************************************************************/
450 void HW__HW__CleanUpDriver(OOP_Class *cl, OOP_Object *o, struct pHW_CleanUpDriver *msg)
452 /* By default we have nothing to do here */