Test initialisation of MUIA_List_AdjustWidth and MUIA_List_AdjustHeight, and
[AROS.git] / arch / all-mingw32 / hidd / wingdi / gdimouse.c
blob334a3e77390354fd42251daf0dc998ed6349e579
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: GDI hidd handling mouse events.
6 Lang: English.
7 */
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>
16 #include <oop/oop.h>
17 #include <hidd/hidd.h>
18 #include <hidd/mouse.h>
20 #include LC_LIBDEFS_FILE
21 #include "gdi.h"
23 /****************************************************************************************/
25 static OOP_AttrBase HiddMouseAB;
27 static struct OOP_ABDescr attrbases[] =
29 { IID_Hidd_Mouse, &HiddMouseAB },
30 { NULL , NULL }
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;
39 state &= mask;
40 if (old == state)
41 return FALSE;
43 e->button = arosbutton;
44 e->type = state ? vHidd_Mouse_Press : vHidd_Mouse_Release;
45 data->mouse_callback(data->callbackdata, e);
47 return TRUE;
50 static VOID MouseIntHandler(struct gdimouse_data *data, volatile struct GDI_Control *MOUSEDATA)
52 struct pHidd_Mouse_Event e;
53 UWORD new_buttons;
54 BOOL button;
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
62 * as possible.
64 switch(MOUSEDATA->MouseEvent)
66 case WM_MOUSEWHEEL:
67 /* Wheel delta comes only with WM_MOUSEWHEEL, otherwise it's zero */
68 e.y = -MOUSEDATA->WheelDelta; /* Windows gives us inverted data */
69 e.x = 0;
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);
81 break;
83 default:
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);
93 if (button)
94 data->buttons = new_buttons;
95 else {
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"));
125 if (o)
127 struct gdimouse_data *data = OOP_INST_DATA(cl, o);
128 struct GDI_Control *ctl = XSD(cl)->ctl;
129 struct TagItem *tag, *tstate;
131 data->buttons = 0;
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)))
138 ULONG idx;
140 if (IS_HIDDMOUSE_ATTR(tag->ti_Tag, idx)) {
141 switch (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;
145 break;
146 case aoHidd_Mouse_IrqHandlerData:
147 D(bug("[GDIMouse] Callback data 0x%p\n", tag->ti_Data));
148 data->callbackdata = (APTR)tag->ti_Data;
149 break;
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);
158 return o;
160 OOP_MethodID disp_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
161 OOP_CoerceMethod(cl, o, (OOP_Msg) &disp_mid);
162 return NULL;
164 return o;
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);
190 return TRUE;
193 ADD2INITLIB(GDIMouse_Init, 0)
194 ADD2EXPUNGELIB(GDIMouse_Expunge, 0)