2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
9 /****************************************************************************************/
11 #include <devices/inputevent.h>
12 #include <devices/input.h>
13 #include <devices/newstyle.h>
14 #include <proto/exec.h>
15 #include <proto/input.h>
16 #include <exec/memory.h>
17 #include <exec/errors.h>
18 #include <exec/initializers.h>
19 #include <aros/symbolsets.h>
21 #include LC_LIBDEFS_FILE
23 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
24 # include "input_intern.h"
28 #include <aros/debug.h>
30 /****************************************************************************************/
32 #define NEWSTYLE_DEVICE 1
34 /****************************************************************************************/
36 extern UWORD
AROS_SLIB_ENTRY(PeekQualifier
,Input
) ();
37 extern void AROS_SLIB_ENTRY(AddNullEvent
,Input
) ();
41 #include <devices/newstyle.h>
42 static const UWORD SupportedCommands
[] =
56 /****************************************************************************************/
58 static int GM_UNIQUENAME(Init
)(LIBBASETYPEPTR InputDevice
)
60 NEWLIST( &(InputDevice
->HandlerList
) );
63 These defaults are in terms of 50 Hz ticks. The real VBlank frequency
66 InputDevice
->KeyRepeatThreshold
.tv_secs
= DEFAULT_KEY_REPEAT_THRESHOLD
/ 50;
67 InputDevice
->KeyRepeatThreshold
.tv_micro
68 = (DEFAULT_KEY_REPEAT_THRESHOLD
% 50) * 1000000 / 50;
70 InputDevice
->KeyRepeatInterval
.tv_secs
= DEFAULT_KEY_REPEAT_INTERVAL
/ 50;
71 InputDevice
->KeyRepeatInterval
.tv_micro
72 = (DEFAULT_KEY_REPEAT_INTERVAL
% 50) * 1000000 / 50;
74 /* Initialise the input.device task. */
75 InputDevice
->InputTask
= AllocMem(sizeof(struct Task
), MEMF_PUBLIC
| MEMF_CLEAR
);
76 if(InputDevice
->InputTask
)
78 struct Task
*task
= InputDevice
->InputTask
;
81 NEWLIST(&task
->tc_MemEntry
);
82 task
->tc_Node
.ln_Type
= NT_TASK
;
83 task
->tc_Node
.ln_Name
= "input.device";
84 task
->tc_Node
.ln_Pri
= IDTASK_PRIORITY
;
86 /* Initialise CommandPort now we have the task */
87 InputDevice
->CommandPort
.mp_SigTask
= task
;
88 InputDevice
->CommandPort
.mp_Flags
= PA_SIGNAL
;
89 NEWLIST(&InputDevice
->CommandPort
.mp_MsgList
);
92 * This is always safe, nobody else knows about our task yet.
93 * Both the AROS and AmigaOS AddTask() initialise zeroed fields,
94 * otherwise we have to do it ourselves.
96 InputDevice
->CommandPort
.mp_SigBit
= 16;
97 task
->tc_SigAlloc
= 1L<<16 | SysBase
->TaskSigAlloc
;
99 stack
= AllocMem(IDTASK_STACKSIZE
, MEMF_CLEAR
|MEMF_PUBLIC
);
103 struct TagItem tags
[] =
105 {TASKTAG_ARG1
, (IPTR
)InputDevice
},
109 task
->tc_SPLower
= stack
;
110 task
->tc_SPUpper
= (UBYTE
*)stack
+ IDTASK_STACKSIZE
;
112 #if AROS_STACK_GROWS_DOWNWARDS
113 task
->tc_SPReg
= (UBYTE
*)task
->tc_SPUpper
- SP_OFFSET
;
115 task
->tc_SPReg
= (UBYTE
*)task
->tc_SPLower
+ SP_OFFSET
;
118 if(NewAddTask(task
, ProcessEvents
, NULL
, tags
) != NULL
)
123 task
->tc_SPLower
= stack
;
124 task
->tc_SPUpper
= (UBYTE
*)stack
+ IDTASK_STACKSIZE
;
126 #if AROS_STACK_GROWS_DOWNWARDS
127 task
->tc_SPReg
= (UBYTE
*)task
->tc_SPUpper
- SP_OFFSET
- sizeof(APTR
);
128 ((APTR
*)task
->tc_SPUpper
)[-1] = InputDevice
;
130 task
->tc_SPReg
= (UBYTE
*)task
->tc_SPLower
+ SP_OFFSET
+ sizeof(APTR
);
131 ((APTR
*)task
->tc_SPLower
)[0] = InputDevice
;
134 if(AddTask(task
, ProcessEvents
, NULL
) != NULL
)
142 Alert(AT_DeadEnd
| AG_NoMemory
| AO_Unknown
| AN_Unknown
);
147 /****************************************************************************************/
149 static int GM_UNIQUENAME(Open
)
151 LIBBASETYPEPTR InputDevice
,
152 struct IORequest
*ioreq
,
157 D(bug("id: open()\n"));
159 if (ioreq
->io_Message
.mn_Length
< sizeof(struct IOStdReq
))
161 bug("[InputDev] Open: IORequest structure passed to OpenDevice is too small\n");
162 ioreq
->io_Error
= IOERR_OPENFAIL
;
169 ADD2INITLIB(GM_UNIQUENAME(Init
),0)
170 ADD2OPENDEV(GM_UNIQUENAME(Open
),0)
172 /****************************************************************************************/
174 #define ioStd(x) ((struct IOStdReq *)x)
175 AROS_LH1(void, beginio
,
176 AROS_LHA(struct IOStdReq
*, ioreq
, A1
),
177 struct inputbase
*, InputDevice
, 5, Input
)
182 BOOL done_quick
= TRUE
;
184 D(bug("id: beginio(ioreq=%p)\n", ioreq
));
186 /* WaitIO will look into this */
187 ioreq
->io_Message
.mn_Node
.ln_Type
=NT_MESSAGE
;
189 switch (ioreq
->io_Command
)
192 case NSCMD_DEVICEQUERY
:
193 if(ioStd(ioreq
)->io_Length
< ((LONG
)OFFSET(NSDeviceQueryResult
, SupportedCommands
)) + sizeof(UWORD
*))
195 ioreq
->io_Error
= IOERR_BADLENGTH
;
199 struct NSDeviceQueryResult
*d
;
201 d
= (struct NSDeviceQueryResult
*)ioStd(ioreq
)->io_Data
;
203 d
->DevQueryFormat
= 0;
204 d
->SizeAvailable
= sizeof(struct NSDeviceQueryResult
);
205 d
->DeviceType
= NSDEVTYPE_INPUT
;
206 d
->DeviceSubType
= 0;
207 d
->SupportedCommands
= (UWORD
*)SupportedCommands
;
209 ioStd(ioreq
)->io_Actual
= sizeof(struct NSDeviceQueryResult
);
230 /* Mark IO request to be done non-quick */
231 ioreq
->io_Flags
&= ~IOF_QUICK
;
232 /* Send to input device task */
233 PutMsg(&InputDevice
->CommandPort
, (struct Message
*)ioreq
);
238 /* If the quick bit is not set but the IO request was done quick,
239 ** reply the message to tell we're throgh
241 ioreq
->io_Error
= error
;
242 if (!(ioreq
->io_Flags
& IOF_QUICK
))
243 ReplyMsg (&ioreq
->io_Message
);
246 D(bug("id: Return from BeginIO()\n"));
251 /****************************************************************************************/
253 AROS_LH1(LONG
, abortio
,
254 AROS_LHA(struct IORequest
*, ioreq
, A1
),
255 struct inputbase
*, InputDevice
, 6, Input
)
259 /* Everything already done. */
265 /****************************************************************************************/
267 static const char end
=0;
269 /****************************************************************************************/