2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
5 Desc: Task used for wainting on events from linux
9 #include <proto/exec.h>
10 #include <proto/oop.h>
11 #include <proto/arossupport.h>
13 #include <exec/memory.h>
14 #include <exec/tasks.h>
15 #include <exec/lists.h>
18 #include <hidd/mouse.h>
19 #include <hidd/unixio.h>
22 #include <aros/debug.h>
24 #include "linuxinput_intern.h"
26 #include <linux/input.h>
28 #define INPUTTASK_PRIORITY 50
30 #define INPUTTASK_STACKSIZE (AROS_STACKSIZE)
31 #define INPUTTASK_NAME "LinuxInput event task"
33 struct inputtask_params
38 struct EventHandler
* eh
;
41 #define BUFF_SIZE (64 * sizeof(struct input_event))
43 #define vHidd_Mouse_NoMotion (23839)
45 static VOID
HIDD_LinuxInput_HandleMouseEvent(struct EventHandler
* eh
, struct pHidd_Mouse_Event
*mouse_event
)
47 if ((eh
->capabilities
& CAP_MOUSE
) && eh
->mousehidd
)
48 HIDD_LinuxMouse_HandleEvent((OOP_Object
*)eh
->mousehidd
, mouse_event
);
51 static VOID
HIDD_LinuxInput_HandleKbdEvent(struct EventHandler
* eh
, UBYTE scanCode
)
53 if ((eh
->capabilities
& CAP_KEYBOARD
) && eh
->kbdhidd
)
54 HIDD_LinuxKbd_HandleEvent((OOP_Object
*)eh
->kbdhidd
, scanCode
);
57 static VOID
process_input_event(struct input_event
* event
, struct EventHandler
* eh
)
60 if (event
->type
== EV_REL
)
62 struct pHidd_Mouse_Event mouse_event
;
63 mouse_event
.button
= vHidd_Mouse_NoButton
;
64 mouse_event
.type
= vHidd_Mouse_NoMotion
;
66 if (event
->code
== REL_X
)
68 mouse_event
.type
= vHidd_Mouse_Motion
;
69 mouse_event
.x
= event
->value
;
73 if (event
->code
== REL_Y
)
75 mouse_event
.type
= vHidd_Mouse_Motion
;
77 mouse_event
.y
= event
->value
;
80 if (event
->code
== REL_WHEEL
)
82 mouse_event
.type
= vHidd_Mouse_WheelMotion
;
84 mouse_event
.y
= -event
->value
;
87 if (mouse_event
.type
!= vHidd_Mouse_NoMotion
)
88 HIDD_LinuxInput_HandleMouseEvent(eh
, &mouse_event
);
91 if (event
->type
== EV_KEY
)
93 struct pHidd_Mouse_Event mouse_event
;
94 mouse_event
.button
= vHidd_Mouse_NoButton
;
97 case(BTN_LEFT
): mouse_event
.button
= vHidd_Mouse_Button1
; break;
98 case(BTN_RIGHT
): mouse_event
.button
= vHidd_Mouse_Button2
; break;
99 case(BTN_MIDDLE
): mouse_event
.button
= vHidd_Mouse_Button3
; break;
102 if (mouse_event
.button
!= vHidd_Mouse_NoButton
)
104 mouse_event
.type
= event
->value
== 1 ? vHidd_Mouse_Press
: vHidd_Mouse_Release
;
105 HIDD_LinuxInput_HandleMouseEvent(eh
, &mouse_event
);
108 if ((event
->code
>= KEY_RESERVED
) && (event
->code
<= KEY_COMPOSE
))
110 UBYTE scanCode
= (UBYTE
)event
->code
;
111 if (event
->value
== 0) scanCode
|= 0x80;
112 HIDD_LinuxInput_HandleKbdEvent(eh
, scanCode
);
117 static VOID
inputtask_entry()
119 struct EventHandler
* eh
;
120 struct inputtask_params itp
;
123 LONG bytesread
= 0, items
= 0, i
;
126 /* We must copy the parameter struct because they are allocated
127 on the parent's stack */
129 D(bug("INSIDE INPUT TASK\n"));
130 itp
= *((struct inputtask_params
*)FindTask(NULL
)->tc_UserData
);
132 D(bug("in inputtask: lsd = %p\n", lsd
));
133 D(bug("FDS: %d\n", lsd
->mousedev
));
135 buff
= AllocMem(BUFF_SIZE
, MEMF_PUBLIC
);
139 Signal(itp
.creator
, itp
.ok_signal
);
143 /* TODO: wait for SIGBREAKF_CTRL_C and then signal "caller" task */
145 Hidd_UnixIO_Wait(eh
->unixio
, eh
->eventdev
, vHidd_UnixIO_Read
);
146 bytesread
= Hidd_UnixIO_ReadFile(eh
->unixio
, eh
->eventdev
, buff
, BUFF_SIZE
, &ioerr
);
147 items
= bytesread
/ sizeof(struct input_event
);
151 for (i
= 0; i
< items
; i
++)
153 process_input_event((struct input_event
*)ptr
, eh
);
154 ptr
+= sizeof(struct input_event
);
158 FreeMem(buff
, BUFF_SIZE
);
165 FreeMem(buff
, BUFF_SIZE
);
167 Signal(itp
.creator
, itp
.nok_signal
);
173 static struct Task
*create_inputtask( struct inputtask_params
*params
)
178 task
= AllocMem(sizeof (struct Task
), MEMF_PUBLIC
|MEMF_CLEAR
);
181 NEWLIST(&task
->tc_MemEntry
);
182 task
->tc_Node
.ln_Type
=NT_TASK
;
183 task
->tc_Node
.ln_Name
= INPUTTASK_NAME
;
184 task
->tc_Node
.ln_Pri
= INPUTTASK_PRIORITY
;
186 stack
=AllocMem(INPUTTASK_STACKSIZE
, MEMF_PUBLIC
);
189 task
->tc_SPLower
=stack
;
190 task
->tc_SPUpper
=(BYTE
*)stack
+ INPUTTASK_STACKSIZE
;
191 task
->tc_UserData
=params
;
193 #if AROS_STACK_GROWS_DOWNWARDS
194 task
->tc_SPReg
=(BYTE
*)task
->tc_SPUpper
-SP_OFFSET
-sizeof(APTR
);
196 task
->tc_SPReg
=(BYTE
*)task
->tc_SPLower
-SP_OFFSET
+sizeof(APTR
);
198 /* You have to clear signals first. */
199 SetSignal(0, params
->ok_signal
| params
->nok_signal
);
201 if(AddTask(task
, inputtask_entry
, NULL
) != NULL
)
203 /* Everything went OK. Wait for task to initialize */
206 D(bug("WAITING FOR SIGNAL\n"));
208 sigset
= Wait( params
->ok_signal
| params
->nok_signal
);
209 D(bug("GOT SIGNAL\n"));
210 if (sigset
& params
->ok_signal
)
214 FreeMem(stack
, INPUTTASK_STACKSIZE
);
217 FreeMem(task
,sizeof(struct Task
));
223 VOID
Init_LinuxInput_inputtask(struct EventHandler
* eh
)
225 struct inputtask_params p
;
226 p
.ok_signal
= AllocSignal(-1L);
227 p
.nok_signal
= AllocSignal(-1L);
229 p
.creator
= FindTask(NULL
);
231 D(bug("init_input_task: p.lsd = %p, p.creator = %p\n", p
.lsd
, p
.creator
));
233 D(bug("SIGNALS ALLOCATED\n"));
235 eh
->inputtask
= create_inputtask(&p
);
237 D(bug("INPUTTASK CREATED\n"));
239 /* No need for these anymore */
240 FreeSignal(p
.ok_signal
);
241 FreeSignal(p
.nok_signal
);
244 VOID
Kill_LinuxInput_inputtask(struct EventHandler
* eh
)
246 /* TODO: Create signal in this task and pass it somehow to input_task */
247 Signal(eh
->inputtask
, SIGBREAKF_CTRL_C
);
248 /* TODO: wait input task to mark previously crated signal */