2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
5 Desc: Main class for HIDD.
9 #include <exec/types.h>
10 #include <exec/libraries.h>
11 #include <exec/lists.h>
12 #include <exec/semaphores.h>
13 #include <exec/memory.h>
14 #include <exec/alerts.h>
16 #include <utility/tagitem.h>
17 #include <utility/hooks.h>
19 #include <hidd/hidd.h>
21 #include <proto/exec.h>
22 #include <proto/oop.h>
23 #include <proto/utility.h>
25 #include <aros/symbolsets.h>
29 #include "hiddclass_intern.h"
31 #include LC_LIBDEFS_FILE
36 #include <aros/debug.h>
38 /*****************************************************************************************
47 This class is a base class for all object-oriented hardware drivers in AROS. Its
48 main purpose is to provide some information about the driver itself.
50 At the moment this class is just a primary design. Many defined attributes and
51 methods are drafts and reserved. This documentation includes only already
52 estabilished definitions. Do not use any other methods and attributes, their
53 definitions may change at any moment.
55 *****************************************************************************************/
57 static const char unknown
[] = "--unknown device--";
59 #define IS_HIDD_ATTR(attr, idx) ((idx = attr - HiddAttrBase) < num_Hidd_Attrs)
61 /*****************************************************************************************
73 Query hardware manufacturer's numeric ID. This ID may come for example from PCI
74 or Zorro bus configuration data.
77 It is valid to return 0 if your hardware doesn't provide any ID number.
79 Initial value for this attribute is usually supplied by driver class in its
80 moRoot_New implementation.
91 *****************************************************************************************/
93 /*****************************************************************************************
105 Name of the driver instance under which it is known to the OS. This name is
106 provided to OS components that use the driver. For example Intuition's MONITORCLASS
107 expects to find something like "ati_dvi1.monitor", "ati_vga1.monitor" or
108 "pcvga.monitor" here.
110 Note that is is instance name, not class name. Different instances of the driver may
111 need to provide different names for different objects (like in ATI example) in order
112 to let the OS to distinguish between them.
114 The supplied string is internally copied, you may destroy it after object creation.
117 Initial value for this attribute is usually supplied by driver class in its
118 moRoot_New implementation.
129 *****************************************************************************************/
131 /*****************************************************************************************
143 Query hardware name string.
146 Initial value for this attribute is usually supplied by driver class in its
147 moRoot_New implementation.
149 The supplied string is not copied!
160 *****************************************************************************************/
162 /*****************************************************************************************
174 Query hardware's numeric produce ID. This ID may come for example from PCI
175 or Zorro bus configuration data.
178 It is valid to return 0 if your hardware doesn't provide any ID number.
180 Initial value for this attribute is usually supplied by driver class in its
181 moRoot_New implementation.
192 *****************************************************************************************/
194 /*****************************************************************************************
206 Query hardware manufacturer string. NULL is a valid value for this attribute
207 meaning that the information is not specified.
210 Initial value for this attribute is usually supplied by driver class in its
211 moRoot_New implementation.
213 The supplied string is not copied!
224 *****************************************************************************************/
226 /* Implementation of root HIDD class methods. */
227 VOID
HIDDCl__Root__Set(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
);
229 /*** HIDD::New() **************************************************************/
231 OOP_Object
*HIDDCl__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
233 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
234 EnterFunc(bug("HIDD::New(cl=%s)\n", cl
->ClassNode
.ln_Name
));
235 D(bug("DoSuperMethod:%p\n", cl
->DoSuperMethod
));
236 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
240 struct TagItem
*list
= msg
->attrList
;
241 struct pRoot_Set set_msg
;
244 name
= (STRPTR
)GetTagData(aHidd_Name
, 0, list
);
246 ULONG l
= strlen(name
)+1;
248 name2
= AllocVec(l
, MEMF_ANY
);
251 CopyMem(name
, name2
, l
);
253 name2
= (STRPTR
)unknown
;
255 hd
= OOP_INST_DATA(cl
, o
);
257 /* Initialise the HIDD class. These fields are publicly described
258 as not being settable at Init time, however it is the only way to
259 get proper abstraction if you ask me. Plus it does reuse code
262 To pass these into the init code I would recommend that your
263 pass in a TagList of your tags, which is linked to the user's
264 tags by a TAG_MORE. This way you will prevent them from setting
268 hd
->hd_Type
= GetTagData(aHidd_Type
, 0, list
);
269 hd
->hd_SubType
= GetTagData(aHidd_SubType
, 0, list
);
270 hd
->hd_Producer
= GetTagData(aHidd_Producer
, 0, list
);
273 hd
->hd_HWName
= (STRPTR
)GetTagData(aHidd_HardwareName
,(IPTR
)unknown
, list
);
274 hd
->hd_ProducerName
= (STRPTR
)GetTagData(aHidd_ProducerName
, 0, list
);
276 hd
->hd_Status
= GetTagData(aHidd_Status
, vHidd_StatusUnknown
, list
);
277 hd
->hd_Locking
= GetTagData(aHidd_Locking
, vHidd_LockShared
, list
);
278 hd
->hd_ErrorCode
= GetTagData(aHidd_ErrorCode
, 0, list
);
280 hd
->hd_Active
= TRUE
; /* Set default, GetTagData() comes later */
282 /* Use OM_SET to set the rest */
285 set_msg
.attrList
= msg
->attrList
;
286 HIDDCl__Root__Set(cl
, o
, &set_msg
);
289 ReturnPtr("HIDD::New", OOP_Object
*, o
);
292 /*** HIDD::Dispose() **********************************************************/
293 VOID
HIDDCl__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
295 struct HIDDData
*hd
= OOP_INST_DATA(cl
, o
);
297 if (hd
->hd_Name
!= (STRPTR
)unknown
)
298 FreeVec(hd
->hd_Name
);
300 OOP_DoSuperMethod(cl
, o
, msg
);
303 /*** HIDD::Set() **************************************************************/
305 VOID
HIDDCl__Root__Set(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
)
307 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
308 struct TagItem
*tstate
= msg
->attrList
;
310 struct HIDDData
*hd
= OOP_INST_DATA(cl
, o
);
312 EnterFunc(bug("HIDD::Set(cl=%s)\n", cl
->ClassNode
.ln_Name
));
314 while((tag
= NextTagItem(&tstate
)))
318 if (IS_HIDD_ATTR(tag
->ti_Tag
, idx
))
323 hd
->hd_Active
= tag
->ti_Data
;
330 ReturnVoid("HIDD::Set");
334 /*** HIDD::Get() **************************************************************/
336 VOID
HIDDCl__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
338 struct HIDDData
*hd
= OOP_INST_DATA(cl
, o
);
341 EnterFunc(bug("HIDD::Get(cl=%s)\n", cl
->ClassNode
.ln_Name
));
343 if (IS_HIDD_ATTR(msg
->attrID
, idx
))
347 case aoHidd_Type
: *msg
->storage
= hd
->hd_Type
; break;
348 case aoHidd_SubType
: *msg
->storage
= hd
->hd_SubType
; break;
349 case aoHidd_Producer
: *msg
->storage
= hd
->hd_Producer
; break;
350 case aoHidd_Name
: *msg
->storage
= (IPTR
)hd
->hd_Name
; break;
351 case aoHidd_HardwareName
: *msg
->storage
= (IPTR
)hd
->hd_HWName
; break;
352 case aoHidd_Active
: *msg
->storage
= hd
->hd_Active
; break;
353 case aoHidd_Status
: *msg
->storage
= hd
->hd_Status
; break;
354 case aoHidd_ErrorCode
: *msg
->storage
= hd
->hd_ErrorCode
; break;
355 case aoHidd_Locking
: *msg
->storage
= hd
->hd_Locking
; break;
357 *msg
->storage
= hd
->hd_Product
;
359 case aoHidd_ProducerName
:
360 *msg
->storage
= (IPTR
)hd
->hd_ProducerName
;
362 default : OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
); break;
365 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
369 ReturnVoid("HIDD::Get");
374 /***********************************
375 ** Unimplemented methods
381 /* switch(msg->MethodID)
384 retval = OOP_DoSuperMethodA(cl, o, msg);
388 hd = OOP_INST_DATA(cl, retval);
392 struct TagItem *list = ((struct opSet *)msg)->ops_AttrList;
393 hd->hd_Type = GetTagData(aHidd_Type, 0, list);
394 hd->hd_SubType = GetTagData(aHidd_SubType, 0, list);
395 hd->hd_Producer = GetTagData(aHidd_Producer, 0, list);
396 hd->hd_Name = (STRPTR)GetTagData(aHidd_Name, (IPTR)unknown, list);
397 hd->hd_HWName = (STRPTR)GetTagData(aHidd_HardwareName, (IPTR)unknown, list);
398 hd->hd_Active = TRUE;
399 hd->hd_Status = GetTagData(aHidd_Status, HIDDV_StatusUnknown, list);
400 hd->hd_ErrorCode = GetTagData(aHidd_ErrorCode, 0, list);
401 hd->hd_Locking = GetTagData(aHidd_Locking, HIDDV_LockShared, list);
406 struct TagItem *tstate = ((struct opSet *)msg)->ops_AttrList;
409 while((tag = NextTagItem(&tstate)))
414 hd->hd_Active = tag->ti_Data;
424 switch(((struct opGet *)msg)->opg_AttrID)
427 *((struct opGet *)msg)->opg_Storage = hd->hd_Type;
431 *((struct opGet *)msg)->opg_Storage = hd->hd_SubType;
435 *((struct opGet *)msg)->opg_Storage = hd->hd_Producer;
439 *((struct opGet *)msg)->opg_Storage = (IPTR)hd->hd_Name;
442 case aHidd_HardwareName:
443 *((struct opGet *)msg)->opg_Storage = (IPTR)hd->hd_HWName;
447 *((struct opGet *)msg)->opg_Storage = hd->hd_Active;
451 *((struct opGet *)msg)->opg_Storage = hd->hd_Status;
454 case aHidd_ErrorCode:
455 *((struct opGet *)msg)->opg_Storage = hd->hd_ErrorCode;
459 *((struct opGet *)msg)->opg_Storage = hd->hd_Locking;
467 /* These are the "hiddclass" methods. */
469 /* These two are invalid, since we don't have anything to get
470 from a class, so the superclass should handle these.
472 This is especially the case since the only place that we can
473 get the information for these methods is from an object, but
474 we don't have any objects if this method is called.
476 /* case HIDDM_Meta_Get:
477 case HIDDM_Meta_MGet:
481 /* Yet to determine the semantics of these so we just let
482 them return 0 for now.
484 /* case HIDDM_BeginIO:
489 case HIDDM_LoadConfigPlugin:
498 Class *hc = ((hmAdd *)msg)->hma_Class;
500 if( (hc->cl_Flags & CLF_INLIST) == 0 )
503 ObtainSemaphore(&((struct HCD *)cl->cl_UserData)->listLock);
505 (struct List *)&((struct HCD *)cl->cl_UserData)->hiddList,
508 ReleaseSemaphore(&((struct HCD *)cl->cl_UserData)->listLock);
510 hc->cl_Flags |= CLF_INLIST;
516 case HIDDM_RemoveHIDD:
518 struct IClass *hc = ((hmAdd *)msg)->hma_Class;
520 if( hc->cl_Flags & CLF_INLIST )
522 ObtainSemaphore(&((struct HCD *)cl->cl_UserData)->listLock);
523 Remove((struct Node *)hc);
524 ReleaseSemaphore(&((struct HCD *)cl->cl_UserData)->listLock);
525 hc->cl_Flags &= ~CLF_INLIST;
532 retval = OOP_DoSuperMethod(cl, o, msg);
541 /*************************** Classes *****************************/
545 static int init_hiddclass(LIBBASETYPEPTR lh
)
547 struct Library
*OOPBase
= GM_OOPBASE_FIELD(lh
);
548 struct class_static_data
*csd
;
551 EnterFunc(bug("HIDD::Init()\n"));
553 /* If you are not running from ROM, don't use Alert() */
556 csd
->cs_UtilityBase
= OpenLibrary("utility.library", 36);
557 if (!csd
->cs_UtilityBase
)
560 NEWLIST(&csd
->hiddList
);
561 InitSemaphore(&csd
->listLock
);
563 HiddAttrBase
= OOP_ObtainAttrBase(IID_Hidd
);
566 D(bug("Got HiddAttrBase\n"));
568 } /* if(HiddAttrBase) */
571 /* If you are not running from ROM, don't use Alert() */
573 Alert(AT_DeadEnd
| AN_Unknown
| AO_Unknown
);
576 ReturnInt("HIDD::Init", ULONG
, ok
);
580 static int free_hiddclass(LIBBASETYPEPTR lh
)
582 struct Library
*OOPBase
= GM_OOPBASE_FIELD(lh
);
583 struct class_static_data
*csd
= &lh
->hd_csd
;
585 EnterFunc(bug("HIDD::Free()\n"));
587 if(csd
->hiddAttrBase
)
589 OOP_ReleaseAttrBase(IID_Hidd
);
590 csd
->hiddAttrBase
= 0;
593 CloseLibrary(csd
->cs_UtilityBase
);
595 ReturnInt("HIDD::Free", ULONG
, TRUE
);
598 ADD2INITLIB(init_hiddclass
, 0)
599 ADD2EXPUNGELIB(free_hiddclass
, 0)