2 Copyright (C) 2004-2010, The AROS Development Team. All rights reserved.
6 #define __OOP_NOATTRBASES__
8 #include <aros/debug.h>
9 #include <aros/symbolsets.h>
10 #include <hidd/keyboard.h>
12 #include <utility/tagitem.h>
13 #include <proto/alib.h>
14 #include <proto/exec.h>
15 #include <proto/utility.h>
16 #include <proto/oop.h>
18 #include LC_LIBDEFS_FILE
21 #define HiddKbdAB (CSD(cl)->hiddKbdAB)
23 #include <hidd/keyboard.h>
25 /*****************************************************************************************
34 This class represents a "hub" for collecting input from various
35 keyboard devices in the system and sending them to clients.
37 In order to get an access to keyboard input subsystem you need to
38 create an object of CLID_Hidd_Kbd class. There can be two use
39 scenarios: driver mode and client mode.
41 If you wish to run in client mode (receive keyboard events), you
42 have to supply a callback using aoHidd_Kbd_IrqHandler attribute.
43 After this your callback will be called every time the event arrives
44 until you dispose your object.
46 Events from all keyboard devices are merged into a single stream
47 and propagated to all clients.
49 In driver mode you don't need to supply a callback (however it's not
50 forbidden). Instead you use the master object for registering your
51 hardware driver using HIDD_Kbd_AddHardwareDriver(). It is safe to
52 dispose the master object after adding a driver, the driver will
53 be internally kept in place.
55 *****************************************************************************************/
57 /*****************************************************************************************
66 A hardware driver should implement the same interface according to the following
69 1. A single object of driver class represents a single hardware unit.
70 2. A single driver object maintains a single callback address (passed to it
71 using aoHidd_Kbd_IrqHandler). Under normal conditions this callback is supplied
72 by CLID_Hidd_Kbd class.
73 3. HIDD_Kbd_AddHardwareDriver() and HIDD_Kbd_RemHardwareDriver() on a driver object
74 itself do not make sense, so there's no need to implement them.
76 A hardware driver class should be a subclass of CLID_Hidd in order to ensure
77 compatibility in future.
79 *****************************************************************************************/
81 static void GlobalCallback(struct kbd_staticdata
*csd
, UWORD code
)
83 struct kbd_data
*data
;
85 for (data
= (struct kbd_data
*)csd
->callbacks
.mlh_Head
; data
->node
.mln_Succ
;
86 data
= (struct kbd_data
*)data
->node
.mln_Succ
)
87 data
->callback(data
->callbackdata
, code
);
90 /*****************************************************************************************
102 Specifies a keyboard event handler. The handler will called be every time a
103 keyboard event happens. A "C" calling convention is used, declare the handler
104 functions as follows:
106 void KeyboardIRQ(APTR data, UWORD keyCode)
108 Handler parameters are:
109 data - Anything you specify using aoHidd_Kbd_IrqHandlerData
110 keyCode - A raw key code as specified in devices/rawkeycodes.h.
111 Key release event is indicated by ORing this value
112 with IECODE_UP_PREFIX (defined in devices/inputevent.h)
114 The handler is called inside interrupts, so usual restrictions apply to it.
121 Not all hosted drivers provide this attribute.
124 aoHidd_Kbd_IrqHandlerData
128 *****************************************************************************************/
130 /*****************************************************************************************
133 aoHidd_Kbd_IrqHandlerData
142 Specifies a user-defined value that will be passed to IRQ handler as a first
143 parameter. The purpose of this is to pass some static data to the handler.
144 The system will not assume anything about this value.
146 Defaults to NULL if not specified.
155 aoHidd_Kbd_IrqHandler
159 ******************************************************************************************/
161 OOP_Object
*KBD__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
163 struct kbd_data
*data
;
164 struct TagItem
*tag
, *tstate
;
166 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
170 data
= OOP_INST_DATA(cl
, o
);
171 data
->callback
= NULL
;
172 data
->callbackdata
= NULL
;
174 tstate
= msg
->attrList
;
175 D(bug("tstate: %p\n", tstate
));
177 while ((tag
= NextTagItem((const struct TagItem
**)&tstate
)))
181 D(bug("Got tag %d, data %x\n", tag
->ti_Tag
, tag
->ti_Data
));
183 if (IS_HIDDKBD_ATTR(tag
->ti_Tag
, idx
))
185 D(bug("Kbd hidd tag\n"));
188 case aoHidd_Kbd_IrqHandler
:
189 data
->callback
= (APTR
)tag
->ti_Data
;
190 D(bug("Got callback %p\n", (APTR
)tag
->ti_Data
));
193 case aoHidd_Kbd_IrqHandlerData
:
194 data
->callbackdata
= (APTR
)tag
->ti_Data
;
195 D(bug("Got data %p\n", (APTR
)tag
->ti_Data
));
199 } /* while (tags to process) */
201 /* Add to interrupts list if we have a callback */
202 if (data
->callback
) {
204 AddTail((struct List
*)&CSD(cl
)->callbacks
, (struct Node
*)data
);
211 VOID
KBD__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
213 struct kbd_data
*data
= OOP_INST_DATA(cl
, o
);
215 if (data
->callback
) {
217 Remove((struct Node
*)data
);
220 OOP_DoSuperMethod(cl
, o
, msg
);
224 * The following two methods are small stubs providing means for future expansion.
225 * In future we could support enumeration of devices and specifying
226 * which device we wish to read events from (in case if we want to implement
227 * amigainput.library or something like it)
230 /*****************************************************************************************
233 moHidd_Kbd_AddHardwareDriver
236 OOP_Object *OOP_DoMethod(OOP_Object *obj, struct pHidd_Kbd_AddHardwareDriver *Msg);
238 OOP_Object *HIDD_Kbd_AddHardwareDriver(OOP_Object *obj, OOP_Class *driverClass,
239 struct TagItem *tags);
245 Creates a hardware driver object and registers it in the system.
247 It does not matter on which instance of CLID_Hidd_Kbd class this method is
248 used. Hardware driver objects are shared between all of them.
251 obj - Any object of CLID_Hidd_Kbd class.
252 driverClass - A pointer to OOP class of the driver. In order to create an object
253 of some previously registered public class, use
254 oop.library/OOP_FindClass().
255 tags - An optional taglist which will be passed to driver class' New() method.
258 A pointer to driver object.
261 Do not dispose the returned object yourself, use HIDD_Kbd_RemHardwareDriver() for it.
268 moHidd_Kbd_RemHardwareDriver
271 This method supplies own interrupt handler to the driver, do not override this.
273 *****************************************************************************************/
275 OOP_Object
*KBD__Hidd_Kbd__AddHardwareDriver(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Kbd_AddHardwareDriver
*Msg
)
277 struct TagItem tags
[] = {
278 { aHidd_Kbd_IrqHandler
, (IPTR
)GlobalCallback
},
279 { aHidd_Kbd_IrqHandlerData
, (IPTR
)CSD(cl
) },
280 { TAG_MORE
, (IPTR
)Msg
->tags
}
283 return OOP_NewObject(Msg
->driverClass
, NULL
, tags
);
286 /*****************************************************************************************
289 moHidd_Kbd_RemHardwareDriver
292 void OOP_DoMethod(OOP_Object *obj, struct pHidd_Kbd_RemHardwareDriver *Msg);
294 void HIDD_Kbd_RemHardwareDriver(OOP_Object *obj, OOP_Object *driver);
300 Unregisters and disposes keyboard hardware driver object.
302 It does not matter on which instance of CLID_Hidd_Kbd class this method is
303 used. Hardware driver objects are shared between all of them.
306 obj - Any object of CLID_Hidd_Kbd class.
307 driver - A pointer to a driver object, returned by HIDD_Kbd_AddHardwareDriver().
319 moHidd_Kbd_AddHardwareDriver
323 *****************************************************************************************/
325 void KBD__Hidd_Kbd__RemHardwareDriver(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Kbd_RemHardwareDriver
*Msg
)
327 OOP_DisposeObject(Msg
->driverObject
);
330 /* Class initialization and destruction */
332 static int KBD_ExpungeClass(LIBBASETYPEPTR LIBBASE
)
334 D(bug("[KBD] Base Class destruction\n"));
336 OOP_ReleaseAttrBase(IID_Hidd_Kbd
);
341 static int KBD_InitClass(LIBBASETYPEPTR LIBBASE
)
343 D(bug("[KBD] base class initialization\n"));
345 LIBBASE
->csd
.hiddKbdAB
= OOP_ObtainAttrBase(IID_Hidd_Kbd
);
347 if (LIBBASE
->csd
.hiddKbdAB
)
349 NewList((struct List
*)&LIBBASE
->csd
.callbacks
);
350 D(bug("[KBD] Everything OK\n"));
357 ADD2INITLIB(KBD_InitClass
, 0)
358 ADD2EXPUNGELIB(KBD_ExpungeClass
, 0)