revert between 56095 -> 55830 in arch
[AROS.git] / rom / devs / console / cdinputhandler.c
blob5eddb144b4e7fbc41252ff6e112e0aae4ffc4736
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 CreateMsgPort();
262 if (port)
264 /* Free the signal allocated for msgport by exec */
265 FreeSignal(port->mp_SigBit);
267 /* Initialize port */
268 port->mp_Flags = PA_SIGNAL;
269 port->mp_SigBit = SIGB_INTUITION;
271 /* The task of the replyport must be initialized each
272 time used, because the CDInputHandler might be
273 called by an app
275 cdihdata->cdihReplyPort = port;
277 /* Initialize Message struct */
278 cdihdata->cdihMsg = msg;
279 msg->msg.mn_ReplyPort = cdihdata->cdihReplyPort;
280 msg->msg.mn_Length = sizeof(struct cdihMessage);
282 /* Initialize Interrupt struct */
283 cdihandler->is_Code =
284 (VOID_FUNC) AROS_SLIB_ENTRY(CDInputHandler,
285 Console, 7);
286 cdihandler->is_Data = cdihdata;
287 cdihandler->is_Node.ln_Pri = 50;
288 cdihandler->is_Node.ln_Name =
289 "console.device InputHandler";
291 cdihdata->consoleDevice = ConsoleDevice;
293 ReturnPtr("initCDIH", struct Interrupt *,
294 cdihandler);
296 FreeMem(cdihdata->cdihMsg, sizeof(struct cdihMessage));
298 DeleteMsgPort(cdihdata->inputPort);
300 FreeMem(cdihdata, sizeof(struct cdihData));
302 FreeMem(cdihandler, sizeof(struct Interrupt));
304 ReturnPtr("initCDIH", struct Interrupt *, NULL);
307 /****************
308 ** CleanupIIH **
309 ****************/
311 VOID cleanupCDIH(struct Interrupt *cdihandler,
312 struct ConsoleBase *ConsoleDevice)
314 struct cdihData *cdihdata;
316 cdihdata = (struct cdihData *)cdihandler->is_Data;
318 /* Reset mp_SigBit, since we were not using it */
319 cdihdata->cdihReplyPort->mp_SigBit = -1;
320 DeleteMsgPort(cdihdata->cdihReplyPort);
322 FreeMem(cdihdata->cdihMsg, sizeof(struct cdihMessage));
324 DeleteMsgPort(cdihdata->inputPort);
326 FreeMem(cdihandler->is_Data, sizeof(struct cdihData));
327 FreeMem(cdihandler, sizeof(struct Interrupt));
329 return;