2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: GDI hidd handling mouse events.
9 #define __OOP_NOATTRBASES__
11 #include <aros/debug.h>
12 #include <aros/symbolsets.h>
13 #include <proto/kernel.h>
14 #include <proto/utility.h>
15 #include <proto/oop.h>
17 #include <hidd/hidd.h>
18 #include <hidd/mouse.h>
20 #include LC_LIBDEFS_FILE
23 /****************************************************************************************/
25 static OOP_AttrBase HiddMouseAB
;
27 static struct OOP_ABDescr attrbases
[] =
29 { IID_Hidd_Mouse
, &HiddMouseAB
},
33 /****************************************************************************************/
35 static BOOL
check_button(UWORD state
, UWORD mask
, UWORD arosbutton
, struct pHidd_Mouse_Event
*e
, struct gdimouse_data
*data
)
37 UWORD old
= data
->buttons
& mask
;
43 e
->button
= arosbutton
;
44 e
->type
= state
? vHidd_Mouse_Press
: vHidd_Mouse_Release
;
45 data
->mouse_callback(data
->callbackdata
, e
);
50 static VOID
MouseIntHandler(struct gdimouse_data
*data
, volatile struct GDI_Control
*MOUSEDATA
)
52 struct pHidd_Mouse_Event e
;
56 D(bug("[GDIMouse] Interrupt\n"));
59 * Due to asynchronous nature of host-side window service thread GDI_Control structure acts like hardware registers.
60 * There can be many pending events before we get here and the structure will hold a summary of all states, however
61 * MouseEvent will contain only last event. Because of this we read it ASAP and pay as little attention to MouseEvent
64 switch(MOUSEDATA
->MouseEvent
)
67 /* Wheel delta comes only with WM_MOUSEWHEEL, otherwise it's zero */
68 e
.y
= -MOUSEDATA
->WheelDelta
; /* Windows gives us inverted data */
72 * This signals that we have read all data from MouseEvent, and
73 * the structure can be reused for the next event. Do it ASAP after
74 * reading data from the control structure.
76 native_func
->GDI_MouseAck();
78 e
.type
= vHidd_Mouse_WheelMotion
;
79 e
.button
= vHidd_Mouse_NoButton
;
80 data
->mouse_callback(data
->callbackdata
, &e
);
84 e
.x
= MOUSEDATA
->MouseX
;
85 e
.y
= MOUSEDATA
->MouseY
;
86 new_buttons
= MOUSEDATA
->Buttons
;
88 native_func
->GDI_MouseAck();
90 button
= check_button(new_buttons
, MK_LBUTTON
, vHidd_Mouse_Button1
, &e
, data
);
91 button
|= check_button(new_buttons
, MK_RBUTTON
, vHidd_Mouse_Button2
, &e
, data
);
92 button
|= check_button(new_buttons
, MK_MBUTTON
, vHidd_Mouse_Button3
, &e
, data
);
94 data
->buttons
= new_buttons
;
96 e
.button
= vHidd_Mouse_NoButton
;
97 e
.type
= vHidd_Mouse_Motion
;
98 data
->mouse_callback(data
->callbackdata
, &e
);
103 /****************************************************************************************/
105 OOP_Object
* GDIMouse__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
107 BOOL has_mouse_hidd
= FALSE
;
109 D(EnterFunc("[GDIMouse] hidd.mouse.gdi::New()\n"));
111 ObtainSemaphoreShared( &XSD(cl
)->sema
);
113 if (XSD(cl
)->mousehidd
)
114 has_mouse_hidd
= TRUE
;
116 ReleaseSemaphore( &XSD(cl
)->sema
);
118 if (has_mouse_hidd
) { /* Cannot open twice */
119 D(bug("[GDIMouse] Attempt to create a second instance\n"));
120 return NULL
; /* Should have some error code here */
123 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
124 D(bug("[GDIMouse] Object created by superclass: 0x%p\n"));
127 struct gdimouse_data
*data
= OOP_INST_DATA(cl
, o
);
128 struct GDI_Control
*ctl
= XSD(cl
)->ctl
;
129 struct TagItem
*tag
, *tstate
;
132 data
->interrupt
= KrnAddIRQHandler(ctl
->MouseIrq
, MouseIntHandler
, data
, ctl
);
133 D(bug("[GDIMouse] Mouse interrupt object: 0x%p\n", data
->interrupt
));
134 if (data
->interrupt
) {
135 tstate
= msg
->attrList
;
136 while ((tag
= NextTagItem(&tstate
)))
140 if (IS_HIDDMOUSE_ATTR(tag
->ti_Tag
, idx
)) {
142 case aoHidd_Mouse_IrqHandler
:
143 D(bug("[GDIMouse] Callback address 0x%p\n", tag
->ti_Data
));
144 data
->mouse_callback
= (VOID (*)())tag
->ti_Data
;
146 case aoHidd_Mouse_IrqHandlerData
:
147 D(bug("[GDIMouse] Callback data 0x%p\n", tag
->ti_Data
));
148 data
->callbackdata
= (APTR
)tag
->ti_Data
;
152 } /* while (tags to process) */
154 /* Install the mouse hidd */
155 ObtainSemaphore( &XSD(cl
)->sema
);
156 XSD(cl
)->mousehidd
= o
;
157 ReleaseSemaphore( &XSD(cl
)->sema
);
160 OOP_MethodID disp_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
161 OOP_CoerceMethod(cl
, o
, (OOP_Msg
) &disp_mid
);
167 /****************************************************************************************/
169 VOID
GDIMouse__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
171 struct gdimouse_data
*data
= OOP_INST_DATA(cl
, o
);
173 KrnRemIRQHandler(data
->interrupt
);
174 ObtainSemaphore( &XSD(cl
)->sema
);
175 XSD(cl
)->mousehidd
= NULL
;
176 ReleaseSemaphore( &XSD(cl
)->sema
);
177 OOP_DoSuperMethod(cl
, o
, msg
);
180 /****************************************************************************************/
182 static int GDIMouse_Init(LIBBASETYPEPTR LIBBASE
)
184 return OOP_ObtainAttrBases(attrbases
);
187 static int GDIMouse_Expunge(LIBBASETYPEPTR LIBBASE
)
189 OOP_ReleaseAttrBases(attrbases
);
193 ADD2INITLIB(GDIMouse_Init
, 0)
194 ADD2EXPUNGELIB(GDIMouse_Expunge
, 0)