whitespace
[AROS.git] / rom / hidds / mouse / subsystem.c
bloba391c02c2db5e4949be1944abc4323875be2c1c8
1 /*
2 Copyright (C) 2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define __OOP_NOATTRBASES__
8 #include <aros/debug.h>
9 #include <hidd/hidd.h>
10 #include <hidd/mouse.h>
11 #include <oop/oop.h>
12 #include <utility/hooks.h>
13 #include <utility/tagitem.h>
15 #include "mouse.h"
17 /*****************************************************************************************
19 NAME
20 --background_subsystem--
22 LOCATION
23 CLID_Hidd_Mouse
25 NOTES
26 This class represents a "hub" for collecting input from various
27 pointing devices (mice, tablets, touchscreens, etc) in the
28 system. Events from all pointing devices are merged into a
29 single stream and propagated to all clients.
31 In order to get an access to pointing input subsystem you need to
32 create an object of CLID_Hidd_Mouse class. The actual returned
33 object is a singletone, you do not have to dispose it, and every
34 call will return the same object pointer. After getting this object
35 you can, for example, register your driver using moHW_AddDriver
36 method, or enumerate drivers using moHW_EnumDrivers.
38 If you wish to receive keyboard events, use objects of CLID_Hidd_Mouse
39 class. This class implements the same interface as driver class, but
40 represents receiver's side and is responsible for registering user's
41 interrupt handler in the listeners chain. These objects are not real
42 drivers and do not need to me registered within the subsystem.
44 *****************************************************************************************/
46 /*****************************************************************************************
48 NAME
49 --hardware_drivers--
51 LOCATION
52 CLID_HW_Mouse
54 NOTES
55 A hardware driver should be a subclass of CLID_Hidd and implement IID_Hidd_Mouse
56 interface according to the following rules:
58 1. A single object of driver class represents a single hardware unit.
59 2. A single driver object maintains a single callback address (passed to it
60 using aoHidd_Mouse_IrqHandler). Under normal conditions this callback is
61 supplied by CLID_HW_Mouse class.
63 *****************************************************************************************/
65 OOP_Object *MouseHW__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
67 struct mouse_staticdata *csd = CSD(cl);
69 if (!csd->hwObject)
71 struct TagItem new_tags[] =
73 {aHW_ClassName, (IPTR)"Pointing devices"},
74 {TAG_DONE , 0 }
76 struct pRoot_New new_msg =
78 .mID = msg->mID,
79 .attrList = new_tags
82 csd->hwObject = (OOP_Object *)OOP_DoSuperMethod(cl, o, &new_msg.mID);
84 return csd->hwObject;
87 VOID MouseHW__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
92 OOP_Object *MouseHW__HW__AddDriver(OOP_Class *cl, OOP_Object *o, struct pHW_AddDriver *Msg)
95 * Instantiate a proxy object instead of driver. The proxy object
96 * will create driver itself.
97 * Since driver object creation/disposition is handled by proxy,
98 * we do not have to use Setup/Cleanup methods in this class.
100 struct TagItem tags[] =
102 {aHidd_DriverData_ClassPtr, (IPTR)Msg->driverClass},
103 {TAG_MORE , (IPTR)Msg->tags }
105 struct pHW_AddDriver add_msg =
107 .mID = Msg->mID,
108 .driverClass = CSD(cl)->dataClass,
109 .tags = tags
112 return (OOP_Object *)OOP_DoSuperMethod(cl, o, &add_msg.mID);
116 * For simplicity and speed our hooks access fields of DriverNode class
117 * directly. OOP_Object * is directly cast to struct driver Node *.
118 * This is perfectly OK becuase:
119 * a) This is our private class, nobody is going to mess with it.
120 * b) It does not have any base classes, and is derived directly from rootclass.
121 * In C++ terminology it's our friend class.
123 AROS_UFH3(static BOOL, searchFunc,
124 AROS_UFHA(struct Hook *, h, A0),
125 AROS_UFHA(struct driverNode *, dn, A2),
126 AROS_UFHA(OOP_Object *, wanted, A1))
128 AROS_USERFUNC_INIT
130 if (dn->drv == wanted)
132 h->h_Data = dn;
133 return TRUE;
136 return FALSE;
138 AROS_USERFUNC_EXIT
141 BOOL MouseHW__HW__RemoveDriver(OOP_Class *cl, OOP_Object *o, struct pHW_RemoveDriver *Msg)
144 * We are given driver object, and now we need to look up
145 * its proxy. We use moHW_EnumDrivers method for this purpose.
146 * Our hook's h_Data will be filled in with proxy pointer.
147 * This double traversing objects list is what i really dislike
148 * in this design. An alternative would be to add some means
149 * to extend struct DriverNode in hidd/hwclass.c, however this
150 * would be also ugly, since it's private data.
151 * Looks like we are not going to have this problem anywhere else.
152 * Other subsystems (PCI, I2C) have base class for its drivers, and
153 * the needed data can be simply encapsulated there.
156 struct Hook searchHook =
158 .h_Entry = (HOOKFUNC)searchFunc,
159 .h_Data = NULL
162 HW_EnumDrivers(o, &searchHook, Msg->driverObject);
164 if (searchHook.h_Data)
166 struct pHW_RemoveDriver rem_msg =
168 .mID = Msg->mID,
169 .driverObject = searchHook.h_Data
172 return OOP_DoSuperMethod(cl, o, &rem_msg.mID);
174 return FALSE;
177 AROS_UFH3(static void, enumFunc,
178 AROS_UFHA(struct Hook *, h, A0),
179 AROS_UFHA(struct driverNode *, dn, A2),
180 AROS_UFHA(OOP_Object *, hookMsg, A1))
182 AROS_USERFUNC_INIT
184 struct Hook *user_hook = h->h_Data;
186 D(bug("[Mouse] Enum: node 0x%p driver 0x%p\n", dn, dn->drv));
187 CALLHOOKPKT(user_hook, dn->drv, hookMsg);
189 AROS_USERFUNC_EXIT
192 void MouseHW__HW__EnumDrivers(OOP_Class *cl, OOP_Object *o, struct pHW_EnumDrivers *Msg)
194 struct Hook enumHook =
196 .h_Entry = (HOOKFUNC)enumFunc,
197 .h_Data = Msg->callback
199 struct pHW_EnumDrivers enum_msg =
201 .mID = Msg->mID,
202 .callback = &enumHook,
203 .hookMsg = Msg->hookMsg
206 OOP_DoSuperMethod(cl, o, &enum_msg.mID);