Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / arch / i386-pc / drivers / mouse.hidd / mouseclass.c
blobfba6080f2136ae7f0840d31be713a17e333eaa89
1 /*
2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: The main mouse class.
6 Lang: English.
7 */
9 /*
10 This is the native-i386 hidd maintaining all available mouse types. It
11 maintains all COM/PS2 mouses available. USB is in a way (we need pci.hidd
12 working, then usb.hidd).
14 Please keep code clean from all .bss and .data sections. .rodata may exist
15 as it will be connected together with .text section during linking. In near
16 future this driver will be compiled as elf executable (instead of object)
17 with -fPIC flag.
20 #include <proto/exec.h>
21 #include <proto/utility.h>
22 #include <proto/oop.h>
23 #include <oop/oop.h>
25 #include <exec/alerts.h>
26 #include <exec/memory.h>
28 #include <hidd/hidd.h>
29 #include <hidd/mouse.h>
31 #include <devices/inputevent.h>
32 #include <string.h>
34 #include <aros/symbolsets.h>
36 #include "mouse.h"
38 #include LC_LIBDEFS_FILE
40 #define DEBUG 0
41 #include <aros/debug.h>
43 #warning "TODO: Remove all .data from file !"
45 #ifdef HiddMouseAB
46 #undef HiddMouseAB
47 #endif
48 #define HiddMouseAB (MSD(cl)->hiddMouseAB)
50 /* Prototypes */
52 int test_mouse_usb(OOP_Class *, OOP_Object *);
53 int test_mouse_ps2(OOP_Class *, OOP_Object *);
54 int test_mouse_com(OOP_Class *, OOP_Object *);
55 void dispose_mouse_usb(OOP_Class *, OOP_Object *);
56 void dispose_mouse_ps2(OOP_Class *, OOP_Object *);
57 void dispose_mouse_seriell(OOP_Class *, OOP_Object *);
58 void getps2State(OOP_Class *, OOP_Object *, struct pHidd_Mouse_Event *);
60 /* defines for buttonstate */
62 #define LEFT_BUTTON 1
63 #define RIGHT_BUTTON 2
64 #define MIDDLE_BUTTON 4
66 /***** Mouse::New() ***************************************/
67 OOP_Object * PCMouse__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
69 BOOL has_mouse_hidd = FALSE;
71 EnterFunc(bug("_Mouse::New()\n"));
73 ObtainSemaphoreShared( &MSD(cl)->sema);
75 if (MSD(cl)->mousehidd)
76 has_mouse_hidd = TRUE;
78 ReleaseSemaphore( &MSD(cl)->sema);
80 if (has_mouse_hidd) /* Cannot open twice */
81 ReturnPtr("_Mouse::New", OOP_Object *, NULL); /* Should have some error code here */
83 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
84 if (o)
86 struct mouse_data *data = OOP_INST_DATA(cl, o);
87 struct TagItem *tag, *tstate;
89 tstate = msg->attrList;
91 /* Search for all mouse attrs */
93 while ((tag = NextTagItem((const struct TagItem **)&tstate)))
95 ULONG idx;
97 if (IS_HIDDMOUSE_ATTR(tag->ti_Tag, idx))
99 switch (idx)
101 case aoHidd_Mouse_IrqHandler:
102 data->mouse_callback = (APTR)tag->ti_Data;
103 break;
105 case aoHidd_Mouse_IrqHandlerData:
106 data->callbackdata = (APTR)tag->ti_Data;
107 break;
111 } /* while (tags to process) */
113 /* Search for mouse installed. As USB is the fastest to test, do it
114 first, if not found search for PS/2 mouse. If failure then check every
115 COM port in the system - the las chance to see... */
117 data->type = MDT_USB;
118 if (!test_mouse_usb(cl, o))
120 memset(&data->u.com, 0, sizeof(data->u.com));
121 data->type = MDT_SERIELL;
123 if (!test_mouse_com(cl, o))
125 memset(&data->u.ps2, 0, sizeof(data->u.ps2));
126 data->type = MDT_PS2;
128 if (!test_mouse_ps2(cl, o))
130 /* No mouse found. What we can do now is just Dispose() :( */
131 OOP_MethodID disp_mid;
132 data->type = MDT_UNKNOWN;
133 disp_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
134 OOP_CoerceMethod(cl, o, (OOP_Msg) &disp_mid);
136 o = NULL;
141 ObtainSemaphore( &MSD(cl)->sema);
142 MSD(cl)->mousehidd = o;
143 ReleaseSemaphore( &MSD(cl)->sema);
146 return o;
149 VOID PCMouse__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
151 struct mouse_data *data = OOP_INST_DATA(cl, o);
153 ObtainSemaphore( &MSD(cl)->sema);
154 MSD(cl)->mousehidd = NULL;
155 ReleaseSemaphore( &MSD(cl)->sema);
157 switch (data->type)
159 case MDT_USB:
160 dispose_mouse_usb(cl, o);
161 break;
163 case MDT_SERIELL:
164 dispose_mouse_seriell(cl, o);
165 break;
167 case MDT_PS2:
168 dispose_mouse_ps2(cl, o);
169 break;
172 OOP_DoSuperMethod(cl, o, msg);
175 /***** Mouse::Get() ***************************************/
176 VOID PCMouse__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
178 struct mouse_data *data = OOP_INST_DATA(cl, o);
179 ULONG idx;
181 if (IS_HIDDMOUSE_ATTR(msg->attrID, idx))
183 switch (idx)
185 case aoHidd_Mouse_IrqHandler:
186 *msg->storage = (IPTR)data->mouse_callback;
187 return;
189 case aoHidd_Mouse_IrqHandlerData:
190 *msg->storage = (IPTR)data->callbackdata;
191 return;
193 case aoHidd_Mouse_State:
194 if (data->type == MDT_PS2)
195 getps2State(cl, o, (struct pHidd_Mouse_Event *)msg->storage);
196 return;
198 case aoHidd_Mouse_RelativeCoords:
199 *msg->storage = TRUE;
200 return;
205 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
208 /***** Mouse::HandleEvent() ***************************************/
210 VOID PCMouse__Hidd_Mouse__HandleEvent(OOP_Class *cl, OOP_Object *o, struct pHidd_Mouse_HandleEvent *msg)
212 struct mouse_data * data;
214 EnterFunc(bug("_mouse_handleevent()\n"));
216 data = OOP_INST_DATA(cl, o);
218 /* Nothing done yet */
220 ReturnVoid("_Mouse::HandleEvent");
223 /******************** init_kbdclass() *********************************/
225 static int PCMouse_InitAttrs(LIBBASETYPEPTR LIBBASE)
227 struct OOP_ABDescr attrbases[] =
229 { IID_Hidd_Mouse, &LIBBASE->msd.hiddMouseAB },
230 { NULL , NULL }
233 EnterFunc(bug("PCMouse_InitAttrs\n"));
235 ReturnInt("PCMouse_InitAttr", ULONG, OOP_ObtainAttrBases(attrbases));
238 /*************** free_kbdclass() **********************************/
239 static int PCMouse_ExpungeAttrs(LIBBASETYPEPTR LIBBASE)
241 struct OOP_ABDescr attrbases[] =
243 { IID_Hidd_Mouse, &LIBBASE->msd.hiddMouseAB },
244 { NULL , NULL }
247 EnterFunc(bug("PCMouse_InitClass\n"));
249 OOP_ReleaseAttrBases(attrbases);
251 return TRUE;
254 ADD2INITLIB(PCMouse_InitAttrs, 0)
255 ADD2EXPUNGELIB(PCMouse_ExpungeAttrs, 0)