use the standard AROS cause
[AROS.git] / test / serialmousetest.c
blob1884f000fdaf2cb4bf0707dcde9b2bd640462097
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 1
7 #include <aros/debug.h>
9 #include <exec/memory.h>
10 #include <dos/dos.h>
11 #include <dos/exall.h>
12 #include <dos/datetime.h>
13 #include <proto/dos.h>
14 #include <proto/utility.h>
15 #include <utility/tagitem.h>
16 #include <utility/utility.h>
17 #include <devices/serial.h>
19 #include <proto/alib.h>
20 #include <proto/exec.h>
21 #include <proto/dos.h>
22 #include <proto/commodities.h>
24 #include <devices/serial.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
30 #define ARG_TEMPLATE "KILL/S,UNIT/N,PROBE/S"
32 enum
34 ARG_KILL = 0,
35 ARG_UNIT,
36 ARG_PROBE,
37 NOOFARGS
40 static UBYTE mousebuffer[3];
41 static ULONG bufptr;
44 struct mouse_action {
45 BYTE dx;
46 BYTE dy;
47 ULONG flags;
50 struct protocol {
51 const char * signature;
52 ULONG signature_length;
53 ULONG packet_length;
54 void (*handler)(char *, ULONG, struct mouse_action *);
55 const char * name;
60 * The following flags are defined:
62 #define MOUSE_LEFT_BUTTON 0x01
63 #define MOUSE_RIGHT_BUTTON 0x02
64 #define MOUSE_MIDDLE_BUTTON 0x04
66 #define MOUSE_DATA_VALID 0x8000
68 const char ms_mouse[] =
70 0x4d,0x40,0x00,
71 0x00,0x08,0x01,
72 0x24,0x30,0x2e,
73 0x30,0x10,0x26,
74 0x10,0x21,0x3c,
75 0x10,0x10,0x10,
76 0x15,0x10,0x12,
77 0x10,0x10,0x3c,
78 0x2d,0x2f,0x35,
79 0x33,0x25,0x3c,
80 0x30,0x2e,0x30,
81 0x10,0x26,0x10,
82 0x21,0x3c,0x2d,
83 0x29,0x23,0x32,
84 0x2f,0x33,0x2f,
85 0x26,0x34,0x00,
86 0x33,0x25,0x32,
87 0x29,0x21,0x2c,
88 0x00,0x2d,0x2f,
89 0x35,0x33,0x25,
90 0x00,0x12,0x0e,
91 0x11,0x21,0x15,
92 0x11,0x09
95 static void ms_mouse_protocol(char *, ULONG, struct mouse_action * );
99 * All known protocols and their handlers
101 const struct protocol protocols[] = {
102 {ms_mouse, sizeof(ms_mouse), 3, ms_mouse_protocol, "ms-mouse"},
103 {NULL , 0 , 0, NULL , NULL}
107 static struct NewBroker nb =
109 NB_VERSION,
110 NULL,
111 NULL,
112 NULL,
113 NBU_NOTIFY | NBU_UNIQUE,
116 NULL,
120 static CxObj * cxbroker;
125 static void ms_mouse_protocol(char * buffer,
126 ULONG len,
127 struct mouse_action * ma)
129 ULONG i = 0;
131 #if 1
132 ULONG j = 0;
133 while (j < len) {
134 printf("0x%02x,",buffer[j++]);
136 printf("\n");
137 #endif
139 while (len > 0) {
140 switch (bufptr) {
141 case 0:
142 case 1:
143 if (0 == (buffer[i] & 0x40)) {
144 mousebuffer[bufptr++] = buffer[i];
146 break;
148 case 2:
149 mousebuffer[bufptr] = buffer[i];
151 bufptr = 0;
153 if ((mousebuffer[2] & 0x40)) {
154 ma->flags = MOUSE_DATA_VALID;
155 if ((mousebuffer[2] & 0x20))
156 ma->flags |= MOUSE_LEFT_BUTTON;
157 if ((mousebuffer[2] & 0x10))
158 ma->flags |= MOUSE_RIGHT_BUTTON;
159 ma->dy = (mousebuffer[1] & 0x20)
160 ? (mousebuffer[1]-0x40)
161 : (mousebuffer[1]);
162 ma->dx = (mousebuffer[0] & 0x20)
163 ? (mousebuffer[0]-0x40)
164 : (mousebuffer[0]);
167 break;
169 default:
170 bufptr = 0;
172 i++;
173 len--;
177 static void check_mouse_action(struct mouse_action * old_action,
178 struct mouse_action * cur_action)
180 if (cur_action->flags & MOUSE_DATA_VALID &&
181 old_action->flags & MOUSE_DATA_VALID) {
183 * Check buttons
185 if (old_action->flags & MOUSE_LEFT_BUTTON) {
186 if (0 == (cur_action->flags & MOUSE_LEFT_BUTTON)) {
187 printf("Left mouse button released!\n");
189 } else
190 if (0 == (old_action->flags & MOUSE_LEFT_BUTTON)) {
191 if (cur_action->flags & MOUSE_LEFT_BUTTON) {
192 printf("Left mouse button pressed!\n");
196 if (old_action->flags & MOUSE_RIGHT_BUTTON) {
197 if (0 == (cur_action->flags & MOUSE_RIGHT_BUTTON)) {
198 printf("Right mouse button released!\n");
200 } else
201 if (0 == (old_action->flags & MOUSE_RIGHT_BUTTON)) {
202 if (cur_action->flags & MOUSE_RIGHT_BUTTON) {
203 printf("Right mouse button pressed!\n");
207 if (old_action->flags & MOUSE_MIDDLE_BUTTON) {
208 if (0 == (cur_action->flags & MOUSE_MIDDLE_BUTTON)) {
209 printf("Middle mouse button released!\n");
211 } else
212 if (0 == (old_action->flags & MOUSE_MIDDLE_BUTTON)) {
213 if (cur_action->flags & MOUSE_MIDDLE_BUTTON) {
214 printf("Middle mouse button pressed!\n");
218 if (cur_action->dx) {
219 printf("Mouse movement left/right: %d\n",cur_action->dx);
221 if (cur_action->dy) {
222 printf("Mouse movement up/down: %d\n",cur_action->dy);
227 static void read_input(struct IOExtSer * IORequest,
228 struct MsgPort * notifport,
229 struct MsgPort * cxport,
230 void (*handler)(char *, ULONG, struct mouse_action *))
232 struct mouse_action old_action, cur_action;
233 BOOL end = FALSE;
234 old_action.flags = 0;
235 cur_action.flags = 0;
236 int n = 3;
237 while (FALSE == end) {
238 BYTE buf[10];
239 struct Message * msg;
240 BOOL IODone = FALSE;
241 ULONG sigs;
242 ULONG cxsig = (NULL != cxport) ? (1 << cxport->mp_SigBit)
243 : 0;
245 memset(buf, 0x00, 10);
246 IORequest->IOSer.io_Command = CMD_READ;
247 IORequest->IOSer.io_Flags = IOF_QUICK;
248 IORequest->IOSer.io_Length = n;
249 IORequest->IOSer.io_Data = buf;
250 SendIO((struct IORequest *)IORequest);
251 sigs = Wait((1 << ((struct IORequest *)IORequest)->io_Message.mn_ReplyPort->mp_SigBit) |
252 (1 << notifport->mp_SigBit) |
253 cxsig |
254 SIGBREAKF_CTRL_C );
255 if (NULL != CheckIO((struct IORequest *)IORequest)) {
257 if (NULL == handler) {
258 printf("No handler given. Calling def. handler!\n");
259 ms_mouse_protocol(buf, n, &cur_action);
260 } else {
261 handler(buf, n, &cur_action);
264 check_mouse_action(&old_action, &cur_action);
266 if (cur_action.flags & MOUSE_DATA_VALID)
267 old_action = cur_action;
269 IODone = TRUE;
272 if (sigs & cxsig) {
273 CxMsg * cxmsg;
274 printf("Got a signal for me as commodity.\n");
275 while (NULL != (cxmsg = (CxMsg *)GetMsg(cxport))) {
276 switch (CxMsgType(cxmsg)) {
277 case CXM_COMMAND:
278 switch (CxMsgID(cxmsg)) {
279 case CXCMD_DISABLE:
280 ActivateCxObj(cxbroker, FALSE);
281 break;
283 case CXCMD_ENABLE:
284 ActivateCxObj(cxbroker, TRUE);
285 break;
287 case CXCMD_KILL:
288 end = TRUE;
289 break;
291 break;
293 ReplyMsg((struct Message *)cxmsg);
297 if (NULL != (msg = GetMsg(notifport))) {
298 printf("Serial mouse driver ends.\n");
299 if (FALSE == IODone)
300 AbortIO((struct IORequest *)IORequest);
301 FreeMem(msg, sizeof(struct Message));
302 end = TRUE;
305 if (sigs & SIGBREAKF_CTRL_C) {
306 end = TRUE;
308 } /* while (FALSE == end) */
309 } /* read_input */
312 static const struct protocol * probe_protocol(struct IOExtSer * IORequest, struct MsgPort * notifport)
314 const struct protocol * p = NULL;
315 ULONG n;
316 Delay(50);
317 printf("Supposed to probe for protocol!\n");
318 IORequest->IOSer.io_Command = SDCMD_QUERY;
319 DoIO((struct IORequest *)IORequest);
320 printf("Number of bytes in buffer: %d\n",(int)IORequest->IOSer.io_Actual);
321 if (0 != (n = IORequest->IOSer.io_Actual)) {
322 UBYTE * buffer = AllocMem(n, MEMF_CLEAR);
323 if (NULL != buffer) {
324 ULONG i = 0;
325 IORequest->IOSer.io_Command = CMD_READ;
326 IORequest->IOSer.io_Flags = IOF_QUICK;
327 IORequest->IOSer.io_Length = n;
328 IORequest->IOSer.io_Data = buffer;
329 DoIO((struct IORequest *)IORequest);
331 while (protocols[i].signature) {
332 printf("Possible: %s, sign_length=%ld\n",
333 protocols[i].name,
334 (long)protocols[i].signature_length);
336 if (n >= protocols[i].signature_length) {
337 ULONG d = n - protocols[i].signature_length;
338 ULONG k = 0;
339 while (k <= d) {
340 if (0 == memcmp(&buffer[k],
341 protocols[i].signature,
342 protocols[i].signature_length)) {
343 printf("Found signature for %s.\n",protocols[i].name);
344 p = &protocols[i];
345 break;
347 k++;
350 i++;
353 FreeMem(buffer, n);
356 return p;
359 static void mouse_driver(ULONG unit, BOOL probe_proto,struct MsgPort * notifport,struct MsgPort *cxport)
361 struct MsgPort * SerPort;
362 ULONG unitnum = unit;
364 SerPort = CreatePort(NULL,0);
365 if (NULL != SerPort) {
366 struct IOExtSer * IORequest;
367 IORequest = (struct IOExtSer *)CreateExtIO(SerPort, sizeof(struct IOExtSer));
368 if (NULL != IORequest) {
369 BYTE err = OpenDevice("serial.device", unitnum, (struct IORequest *)IORequest, 0);
370 if (0 == err) {
372 * Set parameters to read from mouse.
374 IORequest->IOSer.io_Command = SDCMD_SETPARAMS;
375 IORequest->io_Baud = 1200;
376 IORequest->io_ReadLen = 7;
377 IORequest->io_WriteLen = 7;
378 IORequest->io_StopBits = 1;
379 IORequest->io_RBufLen = 512;
380 IORequest->io_ExtFlags = 0;
381 IORequest->IOSer.io_Flags = 0;
382 DoIO((struct IORequest *)IORequest);
385 if (0 == ((struct IORequest *)IORequest)->io_Error) {
386 void (*handler) (char*,ULONG,struct mouse_action *) = NULL;
387 if (TRUE == probe_proto) {
388 const struct protocol * p;
389 p = probe_protocol(IORequest, notifport);
390 if (p) {
391 handler = p->handler;
392 } else {
393 printf("Could not detect mouse protocol!\n");
394 goto probe_fail;
397 read_input(IORequest, notifport, cxport, handler);
398 } else {
399 printf("Could not set parameters for serial port.\n");
400 printf("Error code: %d\n",((struct IORequest *)IORequest)->io_Error);
402 probe_fail:
403 CloseDevice((struct IORequest *)IORequest);
405 DeleteExtIO((struct IORequest *)IORequest);
407 DeletePort(SerPort);
413 static BOOL InitCommodity(void)
415 BOOL rc = FALSE;
417 if (NULL != CxBase) {
419 nb.nb_Name = strdup("Mouse Driver");
420 nb.nb_Title = strdup("Mouse Driver");
421 nb.nb_Descr = strdup("Mouse Driver for serial mice.");
423 if (NULL != (nb.nb_Port = CreateMsgPort())) {
424 if (NULL != (cxbroker = CxBroker(&nb, 0))) {
425 ActivateCxObj(cxbroker, TRUE);
426 rc = TRUE;
427 } else {
428 DeleteMsgPort(nb.nb_Port);
429 nb.nb_Port = NULL;
433 return rc;
437 static void CleanupCommodity(void)
439 if (NULL != CxBase) {
440 if (NULL != cxbroker)
441 DeleteCxObjAll(cxbroker);
442 if (NULL != nb.nb_Port) {
443 struct Message * msg;
444 while (NULL != (msg = GetMsg(nb.nb_Port))) {
445 ReplyMsg(msg);
447 DeleteMsgPort(nb.nb_Port);
448 nb.nb_Port = NULL;
453 #define MSGPORT_NAME "serial_mouse_driver"
455 int main(int argc, char **argv)
457 IPTR args[NOOFARGS] = {FALSE, // ARG_KILL
458 0, // ARG_UNIT
459 FALSE // ARG_PROBE
461 struct RDArgs *rda;
462 rda = ReadArgs(ARG_TEMPLATE, args, NULL);
463 if (NULL != rda) {
464 if (TRUE == args[ARG_KILL]) {
465 struct MsgPort * mport = FindPort(MSGPORT_NAME);
466 if (NULL == mport) {
467 printf("Program seems not to be running. Cannot kill it.\n");
469 } else {
470 struct Message * msg = AllocMem(sizeof(struct Message), MEMF_CLEAR);
471 if (NULL != msg) {
473 * Just send a message to the port.
474 * The content does not matter so far.
476 PutMsg(mport, msg);
479 } else {
480 struct MsgPort * mport = FindPort(MSGPORT_NAME);
481 if (NULL != mport) {
482 printf("Program already running!\n");
483 } else {
484 BOOL have_cx = InitCommodity();
485 struct MsgPort * notifport = CreatePort(MSGPORT_NAME, 0);
486 if (NULL != notifport) {
487 mouse_driver(args[ARG_UNIT],
488 args[ARG_PROBE],
489 notifport,
490 nb.nb_Port);
491 DeletePort(notifport);
492 if (TRUE == have_cx) {
493 CleanupCommodity();
495 } else {
496 printf("Could not create notification port!\n");
500 FreeArgs(rda);
502 return 0;