Updated PCI IDs to latest snapshot.
[tangerine.git] / rom / devs / console / consoletask.c
blobab98f75e7925a1d753f922a586db9000001aba59
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Code executed by the console.device task.
6 Lang: english
7 */
11 #include <exec/lists.h>
13 #include <proto/exec.h>
14 #include <proto/intuition.h>
15 #include <proto/console.h>
16 #include <exec/io.h>
17 #include <exec/alerts.h>
18 #include <dos/dos.h>
21 #include <devices/input.h>
23 #include "console_gcc.h"
24 #include "consoleif.h"
26 /* #define DEBUG 1 */
27 #include <aros/debug.h>
29 /* Protos */
30 static BOOL checkconunit(Object *unit, struct ConsoleBase *ConsoleDevice);
31 static void answer_read_request(struct IOStdReq *req, struct ConsoleBase *ConsoleDevice);
33 VOID consoleTaskEntry(struct ConsoleBase *ConsoleDevice)
35 BOOL success = FALSE;
36 LONG waitsigs = 0L, wakeupsig, commandsig, inputsig;
39 /* CD input handler puts data into this port */
40 struct MsgPort *inputport;
43 /* Used for input.device */
44 struct MsgPort *inputmp;
46 /* Add the CDInputHandler to input.device's list of input handlers */
47 inputmp = CreateMsgPort();
48 if (inputmp)
50 struct IOStdReq *inputio;
51 inputio = (struct IOStdReq *)CreateIORequest(inputmp, sizeof (struct IOStdReq));
52 if (inputio)
54 /* Open the input.device */
55 if (!OpenDevice("input.device", -1, (struct IORequest *)inputio, 0UL))
57 /* Initialize the inputhandler itself */
58 ConsoleDevice->inputHandler = initCDIH(ConsoleDevice);
59 if (ConsoleDevice->inputHandler)
61 inputio->io_Data = ConsoleDevice->inputHandler;
62 inputio->io_Command = IND_ADDHANDLER;
64 DoIO((struct IORequest *)inputio);
65 success = TRUE;
67 CloseDevice((struct IORequest *)inputio);
71 DeleteIORequest((struct IORequest *)inputio);
74 DeleteMsgPort(inputmp);
77 NEWLIST(&ConsoleDevice->readRequests);
79 /* if not successfull, throw an alert */
80 if (!success)
82 Alert(AT_DeadEnd | AN_ConsoleDev | AG_OpenDev | AO_Unknown);
85 D(bug("Console task initialized\n"));
88 /* Get console.device input handler's port */
89 inputport = ((struct cdihData *)ConsoleDevice->inputHandler->is_Data)->inputPort;
91 inputsig = 1 << inputport->mp_SigBit;
92 commandsig = 1 << ConsoleDevice->commandPort.mp_SigBit;
94 waitsigs = inputsig|commandsig|SIGBREAKF_CTRL_C;
96 for (;;)
98 wakeupsig = Wait(waitsigs);
100 /* Anyone wanting to kill us ? */
101 if (wakeupsig & SIGBREAKF_CTRL_C)
103 break;
106 ObtainSemaphore(&ConsoleDevice->consoleTaskLock);
108 if (wakeupsig & inputsig)
110 /* A message from the console device input handler */
111 struct cdihMessage *cdihmsg;
113 while ( (cdihmsg = (struct cdihMessage *)GetMsg(inputport)) )
116 D(bug("GOT MESSAGE FROM CONSOLE INPUT HANDLER: "));
117 /* Check that the ConUnit has not been disposed,
118 while the message was passed
120 if (checkconunit(cdihmsg->unit, ConsoleDevice))
122 switch(cdihmsg->ie.ie_Class)
124 case IECLASS_CLOSEWINDOW:
125 #warning this is a hack. It would actually be up to the
126 #warning console.device user (CON: handler for example) to
127 #warning activate CLOSEWINDOW raw events (SET RAW EVENTS cmd)
128 #warning and then look out for this in the input stream (CMD_READ)
129 /* fall through */
131 case IECLASS_RAWKEY:
133 #define MAPRAWKEY_BUFSIZE 80
135 struct IOStdReq *req, *nextreq;
136 UBYTE inputBuf[MAPRAWKEY_BUFSIZE + 1];
137 LONG actual;
138 ULONG tocopy;
140 /* Convert it to ANSI chars */
142 if (cdihmsg->ie.ie_Class == IECLASS_CLOSEWINDOW)
144 /* HACK */
145 inputBuf[0] = 28; /* CTRL-\ */
146 actual = 1;
147 /* HACK */
149 else
151 actual = RawKeyConvert(&cdihmsg->ie
152 ,inputBuf
153 ,MAPRAWKEY_BUFSIZE
154 ,NULL);
157 D(bug("RawKeyConvert returned %ld\n", actual));
160 if (actual > 0)
162 /* Copy received characters to the console unit input buffer.
163 If the buffer is full, then console input will be lost
165 tocopy = MIN(actual, CON_INPUTBUF_SIZE - ICU(cdihmsg->unit)->numStoredChars);
166 /* Copy the input over to the unit's buffer */
167 CopyMem(inputBuf
168 , ICU(cdihmsg->unit)->inputBuf + ICU(cdihmsg->unit)->numStoredChars
169 , tocopy
172 ICU(cdihmsg->unit)->numStoredChars += tocopy;
174 /* See if there are any queued io read requests that wants to be replied */
175 ForeachNodeSafe(&ConsoleDevice->readRequests, req, nextreq)
178 if ((APTR)req->io_Unit == (APTR)cdihmsg->unit)
180 /* Paranoia */
181 if (0 != ICU(req->io_Unit)->numStoredChars)
183 Remove((struct Node *)req);
184 answer_read_request(req, ConsoleDevice);
188 } /* if (actual > 0) */
190 } /* IECLASS_RAWKEY */
191 break;
193 case IECLASS_SIZEWINDOW:
195 Console_NewWindowSize(cdihmsg->unit);
196 } /* IECLASS_NEWSIZE */
197 break;
199 } /* switch(cdihmsg->ie.ie_Class) */
202 } /* if (checkconunit(cdihmsg->unit, ConsoleDevice)) */
204 /* Tell the input handler we're done */
205 ReplyMsg((struct Message *)cdihmsg);
207 } /* while ( (cdihmsg = (struct cdihMessage *)GetMsg(inputport)) ) */
209 } /* if (wakeupsig & inputsig) */
211 if (wakeupsig & commandsig)
213 /* We got a command from the outside. Investigate it */
214 struct IOStdReq *req;
217 while ((req = (struct IOStdReq *)GetMsg(&ConsoleDevice->commandPort)))
219 switch (req->io_Command)
221 case CMD_READ:
222 if (0 != ICU(req->io_Unit)->numStoredChars)
224 answer_read_request(req, ConsoleDevice);
226 else
228 /* Not enough bytes in the buffer to fill the request, put it on hold */
230 /* ioReq allready removed from the queue qith GetMsg() */
232 AddTail((struct List *)&ConsoleDevice->readRequests, (struct Node *)req);
234 break;
236 default:
237 kprintf("!!! UNKNOWN COMMAND RECEIVED BY CONSOLE TASK !!!\n");
238 kprintf("!!! THIS SHOULD NEVER HAPPEN !!!\n");
239 break;
242 } /* while ((req = (struct IOStdReq *)GetMsg(ConsoleDevice->commandPort))) */
244 } /* if (wakeupsig & commandsig) */
246 ReleaseSemaphore(&ConsoleDevice->consoleTaskLock);
248 } /* forever */
250 #warning FIXME: Do cleanup here
254 /********** checkconunit() *******************************/
256 /* Checks that the supplied unit has not been disposed */
257 static BOOL checkconunit(Object *unit, struct ConsoleBase *ConsoleDevice)
259 Object *o, *ostate;
260 BOOL found = FALSE;
262 ObtainSemaphoreShared(&ConsoleDevice->unitListLock);
264 ostate = (Object *)ConsoleDevice->unitList.mlh_Head;
265 while ( (o = NextObject(&ostate)) && (!found) )
267 if (o == unit)
269 found = TRUE;
273 ReleaseSemaphore(&ConsoleDevice->unitListLock);
274 return found;
277 /******** answer_read_request() ***************************/
279 static void answer_read_request(struct IOStdReq *req, struct ConsoleBase *ConsoleDevice)
281 Object *unit;
283 D(bug("answer_read_request\n"));
284 /* This function assumes that there are at least one character
285 available in the unitsinput buffer
288 unit = (Object *)req->io_Unit;
290 req->io_Actual = MIN(ICU(unit)->numStoredChars, req->io_Length);
292 /* Copy characters from the buffer into the request */
293 CopyMem( (APTR)ICU(unit)->inputBuf
294 , req->io_Data
295 , req->io_Actual
298 if (ICU(unit)->numStoredChars > req->io_Length)
300 ULONG i;
302 ICU(unit)->numStoredChars -= req->io_Actual;
304 /* We have to move the rest of the bytes to the start
305 of the buffer.
307 NOTE: we could alternatively use a circular buffer
310 for (i = 0; i < ICU(unit)->numStoredChars; i ++)
312 ICU(unit)->inputBuf[i] = ICU(unit)->inputBuf[i + req->io_Actual];
315 else
317 /* No more unread characters in the buffer */
318 ICU(unit)->numStoredChars = 0;
322 req->io_Error = 0;
323 /* All done. Just reply the request */
325 /* stegerg: the caller of answer_read_request is responsible for the Remove,
326 because the Remove must be used only if the req was in
327 the readrequests list
328 Remove((struct Node *)req);
333 /* kprintf("receiving task=%s, sigbit=%d\n, mode=%d"
334 , ((struct Task *)req->io_Message.mn_ReplyPort->mp_SigTask)->tc_Node.ln_Name
335 , req->io_Message.mn_ReplyPort->mp_SigBit
336 , req->io_Message.mn_ReplyPort->mp_Flags
339 ReplyMsg((struct Message *)req);
341 return;