2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
5 Desc: Task used for wainting on events from linux
15 #include <proto/exec.h>
16 #include <proto/oop.h>
17 #include <proto/arossupport.h>
19 #include <exec/memory.h>
20 #include <exec/tasks.h>
21 #include <exec/lists.h>
26 #include <hidd/unixio.h>
27 #include <hidd/mouse.h>
29 #include "linux_intern.h"
31 #define INPUTTASK_PRIORITY 50
33 #define INPUTTASK_STACKSIZE (AROS_STACKSIZE)
34 #define INPUTTASK_NAME "Linux input event task"
36 /* this task should wait for mouse and keyboard events */
38 struct inputtask_params
{
43 struct linux_staticdata
*lsd
;
57 static void update_mouse_state( struct mouse_state
*oldstate
58 , struct mouse_state
*newstate
59 , struct pHidd_Mouse_Event
*mev
)
68 /* Discover the difference between the old and the new state */
69 for (i
= 0; i
< 3; i
++) {
70 if (oldstate
->buts
[i
] != newstate
->buts
[i
]) {
71 mev
->button
= hidd2but
[i
];
72 mev
->type
= ( oldstate
->buts
[i
] ? vHidd_Mouse_Release
: vHidd_Mouse_Press
);
78 if ( (oldstate
->dx
!= newstate
->dx
)
79 || (oldstate
->dy
!= newstate
->dy
) ) {
81 mev
->x
= newstate
->dx
;
82 mev
->y
= newstate
->dy
;
83 mev
->type
= vHidd_Mouse_Motion
;
88 static void free_unixio_message(struct MsgPort
*msgport
, struct linux_staticdata
*lsd
)
92 msg
= GetMsg(msgport
);
94 kprintf("!!! linux input task: NO MSG FROM UNIXIO !!!\n");
96 FreeMem(msg
, sizeof (struct uioMessage
));
100 static VOID
inputtask_entry(struct inputtask_params
*inputparams
)
102 struct linux_staticdata
*lsd
;
103 struct inputtask_params itp
;
104 UBYTE lastcode
= 0xFF;
106 struct MsgPort
*kbd_port
= NULL
;
107 struct MsgPort
*mouse_port
= NULL
;
109 struct mouse_state oldstate
= { { 0, 0, 0 }, 0, 0 };
110 struct pHidd_Mouse_Event mouse_event
;
113 ULONG kbdsig
, mousesig
, sigs
;
114 /* We must copy the parameter struct because they are allocated
115 on the parent's stack */
116 kprintf("INSIDE INPUT TASK\n");
119 kprintf("in inputtask: lsd = %p\n", lsd
);
121 kprintf("CREATING UNIXIO,,, OOPBase=%p\n", OOPBase
);
123 unixio
= (HIDD
)New_UnixIO(OOPBase
, SysBase
);
124 kprintf("UNIXIO %p\n", unixio
);
125 if (NULL
== unixio
) {
129 kbd_port
= CreateMsgPort();
130 mouse_port
= CreateMsgPort();
132 if (NULL
== kbd_port
|| NULL
== mouse_port
)
135 Signal(itp
.parent
, itp
.ok_signal
);
137 kbdsig
= 1L << kbd_port
->mp_SigBit
;
138 mousesig
= 1L << mouse_port
->mp_SigBit
;
139 kprintf("SIGS: %p, %p\n", kbdsig
, mousesig
);
140 kprintf("FDS: %d, %d\n", lsd
->kbdfd
, lsd
->mousefd
);
142 Hidd_UnixIO_AsyncIO(unixio
, lsd
->kbdfd
, vHidd_UnixIO_Terminal
, kbd_port
, vHidd_UnixIO_Read
, SysBase
);
143 Hidd_UnixIO_AsyncIO(unixio
, lsd
->mousefd
, vHidd_UnixIO_Terminal
, mouse_port
, vHidd_UnixIO_Read
, SysBase
);
146 LONG err_kbd
, err_mouse
;
148 //kprintf("GETTING INPUT FROM UNIXIO\n");
149 /* Turn on kbd support */
153 // ret = (int)Hidd_UnixIO_Wait( unixio, lsd->kbdfd, vHidd_UnixIO_Read, NULL, NULL);
155 // kprintf("GOT INPUT FROM UNIXIO\n");
157 sigs
= Wait( kbdsig
| mousesig
);
161 //kprintf("---------- GOT KBD INPUT --------------------\n");
167 bytesread
= read(lsd
->kbdfd
, &code
, 1);
168 if (-1 == bytesread
) {
169 kprintf("!!! COULD NOT READ FROM LINUX KBD DEVICE: %s\n"
174 /* Let the kbd hidd handle it */
177 //kprintf("## code %d\n", code);
178 if (code
== lastcode
)
181 // if (!(code & 0x80)) kprintf("GOT SCANCODE %d from kbd hidd\n", code);
182 if (code
== 88) /* F12 */
184 kill(getpid(), SIGTERM
);
187 /* Send code to the application */
188 ObtainSemaphore(&lsd
->sema
);
189 if (lsd
->kbdhidd
) HIDD_LinuxKbd_HandleEvent(lsd
->kbdhidd
, code
);
190 ReleaseSemaphore(&lsd
->sema
);
197 free_unixio_message(kbd_port
, lsd
);
199 err_kbd
= Hidd_UnixIO_AsyncIO(unixio
, lsd
->kbdfd
, vHidd_UnixIO_Terminal
, kbd_port
, vHidd_UnixIO_Read
, SysBase
);
201 } /* if (sigs & kbdsig) */
209 struct mouse_state newstate
;
211 /* Got mouse event */
212 //kprintf("------------- MOUSE EVENT ------------\n");
213 for (i
= 0; i
< 4; i
++) {
214 bytesread
= read(lsd
->mousefd
, &buf
[i
], 1);
222 kprintf("!!! linux input task: Could not read from mouse device: %s\n", strerror(errno
));
223 goto end_mouse_event
;
226 if ((buf
[0] & 8) != 8) i
--;
229 //kprintf("%02x: %02x: %02x\n", buf[0], buf[1], buf[2]);
230 /* Get button states */
231 newstate
.buts
[0] = (buf
[0] & 0x01) ? 1 : 0;
232 newstate
.buts
[1] = (buf
[0] & 0x02) ? 1 : 0;
233 newstate
.buts
[2] = (buf
[0] & 0x04) ? 1 : 0;
236 dx
= (buf
[0] & 0x10) ? buf
[1] - 256 : buf
[1];
240 dy
= (buf
[0] & 0x20) ? buf
[2] - 256 : buf
[2];
246 //kprintf("EVENT: STATE 1:%d, 2:%d, 3:%d, dx:%d, dy:%d\n"
247 // , newstate.buts[0], newstate.buts[1], newstate.buts[2]
248 // , newstate.dx, newstate.dy);
250 ObtainSemaphore(&lsd
->sema
);
253 mouse_event
.x
= newstate
.dx
;
254 mouse_event
.y
= newstate
.dy
;
256 if (newstate
.dx
|| newstate
.dy
)
258 mouse_event
.button
= vHidd_Mouse_NoButton
;
259 mouse_event
.type
= vHidd_Mouse_Motion
;
261 HIDD_LinuxMouse_HandleEvent(lsd
->mousehidd
, &mouse_event
);
264 if (newstate
.buts
[0] != oldstate
.buts
[0])
266 mouse_event
.button
= vHidd_Mouse_Button1
;
267 mouse_event
.type
= newstate
.buts
[0] ? vHidd_Mouse_Press
: vHidd_Mouse_Release
;
269 HIDD_LinuxMouse_HandleEvent(lsd
->mousehidd
, &mouse_event
);
272 if (newstate
.buts
[1] != oldstate
.buts
[1])
274 mouse_event
.button
= vHidd_Mouse_Button2
;
275 mouse_event
.type
= newstate
.buts
[1] ? vHidd_Mouse_Press
: vHidd_Mouse_Release
;
277 HIDD_LinuxMouse_HandleEvent(lsd
->mousehidd
, &mouse_event
);
280 if (newstate
.buts
[2] != oldstate
.buts
[2])
282 mouse_event
.button
= vHidd_Mouse_Button3
;
283 mouse_event
.type
= newstate
.buts
[2] ? vHidd_Mouse_Press
: vHidd_Mouse_Release
;
285 HIDD_LinuxMouse_HandleEvent(lsd
->mousehidd
, &mouse_event
);
288 ReleaseSemaphore(&lsd
->sema
);
293 free_unixio_message(mouse_port
, lsd
);
295 err_mouse
= Hidd_UnixIO_AsyncIO(unixio
, lsd
->mousefd
, vHidd_UnixIO_Terminal
, mouse_port
, vHidd_UnixIO_Read
, SysBase
);
303 if (NULL
!= kbd_port
)
304 DeleteMsgPort(kbd_port
);
306 if (NULL
!= mouse_port
)
307 DeleteMsgPort(mouse_port
);
310 OOP_DisposeObject((OOP_Object
*)unixio
);
312 Signal(itp
.parent
, itp
.fail_signal
);
318 static struct Task
*create_inputtask( struct inputtask_params
*params
, struct ExecBase
*SysBase
)
323 task
= AllocMem(sizeof (struct Task
), MEMF_PUBLIC
|MEMF_CLEAR
);
325 NEWLIST(&task
->tc_MemEntry
);
326 task
->tc_Node
.ln_Type
=NT_TASK
;
327 task
->tc_Node
.ln_Name
= INPUTTASK_NAME
;
328 task
->tc_Node
.ln_Pri
= INPUTTASK_PRIORITY
;
330 stack
=AllocMem(INPUTTASK_STACKSIZE
, MEMF_PUBLIC
);
332 task
->tc_SPLower
=stack
;
333 task
->tc_SPUpper
=(BYTE
*)stack
+ INPUTTASK_STACKSIZE
;
335 #if AROS_STACK_GROWS_DOWNWARDS
336 task
->tc_SPReg
= (BYTE
*)task
->tc_SPUpper
-SP_OFFSET
-sizeof(APTR
);
337 ((APTR
*)task
->tc_SPUpper
)[-1] = params
;
339 task
->tc_SPReg
=(BYTE
*)task
->tc_SPLower
-SP_OFFSET
+ sizeof(APTR
);
340 *(APTR
*)task
->tc_SPLower
= params
;
342 /* You have to clear signals first. */
343 SetSignal(0, params
->ok_signal
| params
->fail_signal
);
345 if(AddTask(task
, inputtask_entry
, NULL
) != NULL
) {
346 /* Everything went OK. Wait for task to initialize */
349 kprintf("WAITING FOR SIGNAL\n");
351 sigset
= Wait( params
->ok_signal
| params
->fail_signal
);
352 kprintf("GOT SIGNAL\n");
353 if (sigset
& params
->ok_signal
) {
357 FreeMem(stack
, INPUTTASK_STACKSIZE
);
359 FreeMem(task
,sizeof(struct Task
));
364 struct Task
*init_linuxinput_task(struct linux_staticdata
*lsd
)
366 struct inputtask_params p
;
367 p
.ok_signal
= AllocSignal(-1L);
368 p
.fail_signal
= AllocSignal(-1L);
369 p
.kill_signal
= SIGBREAKF_CTRL_C
;
371 p
.parent
= FindTask(NULL
);
373 kprintf("init_input_task: p.lsd = %p\n", p
.lsd
);
375 kprintf("SIGNALS ALLOCATED\n");
377 lsd
->input_task
= create_inputtask(&p
, SysBase
);
378 kprintf("INPUTTASK CREATED\n");
380 /* No need for these anymore */
381 FreeSignal(p
.ok_signal
);
382 FreeSignal(p
.fail_signal
);
384 return lsd
->input_task
;
387 VOID
kill_linuxinput_task(struct linux_staticdata
*lsd
)
389 #warning This will not work since the task does not Wait() for this signal.
390 #warning Also we should wait for the child task to exit
391 Signal(lsd
->input_task
, SIGBREAKF_CTRL_C
);