disable debug
[AROS.git] / rom / devs / console / cdinputhandler.c
blobd7ec94bff7119eba4b1e7e535b6c815b23883983
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: console.device function CDInputHandler()
6 Lang: english
7 */
9 #include <proto/exec.h>
10 #include <exec/libraries.h>
11 #include <exec/memory.h>
12 #include <proto/console.h>
13 #include <proto/intuition.h>
14 #include <intuition/intuitionbase.h>
16 #include <aros/asmcall.h>
18 #include <devices/inputevent.h>
20 #include "console_gcc.h"
22 #define DEBUG 0
23 #include <aros/debug.h>
25 /* protos */
26 static Object *obtainconunit(struct ConsoleBase *ConsoleDevice);
27 static VOID releaseconunit(Object *o, struct ConsoleBase *ConsoleDevice);
29 /*************************************************************************
31 NAME */
32 AROS_LH2I(struct InputEvent *, CDInputHandler,
34 /* SYNOPSIS */
35 AROS_LHA(struct InputEvent *, events, A0),
36 AROS_LHA(APTR, _cdihdata, A1),
38 /* LOCATION */
39 struct Library *, ConsoleDevice, 7, Console)
41 /* FUNCTION
43 INPUTS
45 RESULT
47 NOTES
49 EXAMPLE
51 BUGS
53 SEE ALSO
55 INTERNALS
57 *****************************************************************************/
59 AROS_LIBFUNC_INIT
61 struct cdihData *cdihdata = _cdihdata;
63 #undef ConsoleDevice
64 #define ConsoleDevice (cdihdata->consoleDevice)
66 struct InputEvent *ie;
67 BOOL send_message = FALSE;
69 struct cdihMessage *message = cdihdata->cdihMsg;
70 D(bug("CDInputHandler(events=%p, cdihdata=%p)\n", events, cdihdata));
72 for (ie = events; ie; ie = ie->ie_NextEvent)
74 /* A rawkey event ? */
75 if ((ie->ie_Class == IECLASS_RAWKEY
76 && !(ie->ie_Code & IECODE_UP_PREFIX))
77 || (ie->ie_Class == IECLASS_SIZEWINDOW)
78 || (ie->ie_Class == IECLASS_CLOSEWINDOW)
79 || (ie->ie_Class == IECLASS_REFRESHWINDOW)
80 || (ie->ie_Class == IECLASS_GADGETDOWN)
81 || (ie->ie_Class == IECLASS_GADGETUP)
82 || (ie->ie_Class == IECLASS_RAWMOUSE)
83 || (ie->ie_Class == IECLASS_TIMER))
85 /* What console do we send it to ? */
86 Object *unit;
88 D(bug("Got some event\n"));
89 /* find and prevent deletion of unit */
90 unit = obtainconunit(ConsoleDevice);
91 if (unit)
93 message->unit = unit;
94 message->ie = *ie;
95 send_message = TRUE;
97 D(bug("Event should be passed to unit %p\n", unit));
99 /* deletion of unit is now allowed */
100 releaseconunit(unit, ConsoleDevice);
102 } /* if (RAWKEY event was meant for a console window) */
104 else
106 D(bug("Ignoring event of ie_Class %d\n", ie->ie_Class));
109 if (send_message)
111 /* This function might be called by any task, not only
112 by the input.device, so it is important that
113 we initialize the replyport's task each time.
115 struct MsgPort *replyport;
117 replyport = message->msg.mn_ReplyPort;
119 replyport->mp_SigTask = FindTask(NULL);
120 PutMsg(cdihdata->inputPort, (struct Message *)message);
122 /* Wait for reply */
123 WaitPort(replyport);
125 /* Remove it from the replyport's msgqueue */
126 GetMsg(replyport);
128 send_message = FALSE;
130 } /* for (each event in the chain) */
132 ReturnPtr("CDInputHandler", struct InputEvent *, events);
134 AROS_LIBFUNC_EXIT
135 } /* CDInputHandler */
139 #undef ConsoleDevice
140 #undef IntuitionBase
142 /***********************
143 ** Support funtions **
144 ***********************/
146 /* Obtains a conunit object, and locks it, so that it's
147 not deleted while we work on it
150 static Object *obtainconunit(struct ConsoleBase *ConsoleDevice)
152 struct IntuitionBase *IntuitionBase =
153 (APTR) ConsoleDevice->cb_IntuitionBase;
154 struct Window *activewin;
155 Object *o, *ostate;
156 ULONG lock;
157 struct Node *node;
159 D(bug("obtainconunit()\n"));
161 ForeachNode(&ConsoleDevice->unitList, node)
163 D(bug("Node: %p\n", node));
166 /* Lock the console list */
167 ObtainSemaphoreShared(&ConsoleDevice->unitListLock);
169 /* What is the currently active window ? */
170 D(bug("Obtaining IBase\n"));
171 lock = LockIBase(0UL);
173 activewin = IntuitionBase->ActiveWindow;
175 UnlockIBase(lock);
176 D(bug("Released IBase, active win=%p\n", activewin));
178 /* Try to find the correct unit object for taht window */
179 ostate = (Object *) ConsoleDevice->unitList.mlh_Head;
181 D(bug("Searching for con unit\n"));
182 while ((o = NextObject(&ostate)))
184 D(bug("Trying unit %p, win=%p\n", o, CU(o)->cu_Window));
185 /* Is this console the currently active window ? */
186 if (CU(o)->cu_Window == activewin)
188 D(bug("Unit found: %p\n", o));
189 /* Delay deltion of this console object */
190 ICU(o)->conFlags |= CF_DELAYEDDISPOSE;
191 break;
195 /* Unlock the console list */
196 ReleaseSemaphore(&ConsoleDevice->unitListLock);
198 ReturnPtr("obtainconunit", Object *, o);
201 static VOID releaseconunit(Object *o, struct ConsoleBase *ConsoleDevice)
203 struct IntuitionBase *IntuitionBase =
204 (APTR) ConsoleDevice->cb_IntuitionBase;
206 /* Lock all units */
207 ObtainSemaphore(&ConsoleDevice->unitListLock);
209 /* Needn't prevent the unit from being disposed anymore */
210 ICU(o)->conFlags &= ~CF_DELAYEDDISPOSE;
212 /* If unit is scheduled for deletion, then delete it */
213 if (ICU(o)->conFlags & CF_DISPOSE)
215 ULONG mID = OM_REMOVE;
217 /* Remove from list */
218 DoMethodA(o, (Msg) &mID);
220 /* Delete it */
221 DisposeObject(o);
224 ReleaseSemaphore(&ConsoleDevice->unitListLock);
227 /****************
228 ** initCDIH() **
229 ****************/
230 /* This function should be executed on the console.device task's context only,
231 so that the inputport is set correctly
234 struct Interrupt *initCDIH(struct ConsoleBase *ConsoleDevice)
236 struct Interrupt *cdihandler;
237 struct cdihData *cdihdata;
239 D(bug("initCDIH(ConsoleDevice=%p)\n", ConsoleDevice));
241 cdihandler =
242 AllocMem(sizeof(struct Interrupt), MEMF_PUBLIC | MEMF_CLEAR);
243 if (cdihandler)
245 cdihdata =
246 AllocMem(sizeof(struct cdihData), MEMF_PUBLIC | MEMF_CLEAR);
247 if (cdihdata)
249 cdihdata->inputPort = CreateMsgPort();
250 if (cdihdata->inputPort)
252 struct cdihMessage *msg;
254 msg =
255 AllocMem(sizeof(struct cdihMessage),
256 MEMF_PUBLIC | MEMF_CLEAR);
257 if (msg)
259 struct MsgPort *port;
260 port =
261 AllocMem(sizeof(struct MsgPort),
262 MEMF_PUBLIC | MEMF_CLEAR);
263 if (port)
265 /* Initialize port */
266 port->mp_Flags = PA_SIGNAL;
267 port->mp_SigBit = SIGB_INTUITION;
269 /* The task of the replyport must be initialized each
270 time used, because the CDInputHandler might be
271 called by an app
274 NEWLIST(&(port->mp_MsgList));
276 cdihdata->cdihReplyPort = port;
278 /* Initialize Message struct */
279 cdihdata->cdihMsg = msg;
280 msg->msg.mn_ReplyPort = cdihdata->cdihReplyPort;
281 msg->msg.mn_Length = sizeof(struct cdihMessage);
283 /* Initialize Interrupt struct */
284 cdihandler->is_Code =
285 (VOID_FUNC) AROS_SLIB_ENTRY(CDInputHandler,
286 Console, 7);
287 cdihandler->is_Data = cdihdata;
288 cdihandler->is_Node.ln_Pri = 50;
289 cdihandler->is_Node.ln_Name =
290 "console.device InputHandler";
292 cdihdata->consoleDevice = ConsoleDevice;
294 ReturnPtr("initCDIH", struct Interrupt *,
295 cdihandler);
297 FreeMem(cdihdata->cdihMsg, sizeof(struct cdihMessage));
299 DeleteMsgPort(cdihdata->inputPort);
301 FreeMem(cdihdata, sizeof(struct cdihData));
303 FreeMem(cdihandler, sizeof(struct Interrupt));
305 ReturnPtr("initCDIH", struct Interrupt *, NULL);
308 /****************
309 ** CleanupIIH **
310 ****************/
312 VOID cleanupCDIH(struct Interrupt *cdihandler,
313 struct ConsoleBase *ConsoleDevice)
315 struct cdihData *cdihdata;
317 cdihdata = (struct cdihData *)cdihandler->is_Data;
319 FreeMem(cdihdata->cdihReplyPort, sizeof(struct MsgPort));
321 FreeMem(cdihdata->cdihMsg, sizeof(struct cdihMessage));
323 DeleteMsgPort(cdihdata->inputPort);
325 FreeMem(cdihandler->is_Data, sizeof(struct cdihData));
326 FreeMem(cdihandler, sizeof(struct Interrupt));
328 return;