2 Copyright � 1995-2014, The AROS Development Team. All rights reserved.
5 Desc: console.device function CDInputHandler()
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"
23 #include <aros/debug.h>
26 static Object
*obtainconunit(struct ConsoleBase
*ConsoleDevice
);
27 static VOID
releaseconunit(Object
*o
, struct ConsoleBase
*ConsoleDevice
);
29 /*************************************************************************
32 AROS_LH2I(struct InputEvent
*, CDInputHandler
,
35 AROS_LHA(struct InputEvent
*, events
, A0
),
36 AROS_LHA(APTR
, _cdihdata
, A1
),
39 struct Library
*, ConsoleDevice
, 7, Console
)
57 *****************************************************************************/
61 struct cdihData
*cdihdata
= _cdihdata
;
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 ? */
88 D(bug("Got some event\n"));
89 /* find and prevent deletion of unit */
90 unit
= obtainconunit(ConsoleDevice
);
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) */
106 D(bug("Ignoring event of ie_Class %d\n", ie
->ie_Class
));
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
);
125 /* Remove it from the replyport's msgqueue */
128 send_message
= FALSE
;
130 } /* for (each event in the chain) */
132 ReturnPtr("CDInputHandler", struct InputEvent
*, events
);
135 } /* CDInputHandler */
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
;
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
;
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
;
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
;
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
);
224 ReleaseSemaphore(&ConsoleDevice
->unitListLock
);
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
));
242 AllocMem(sizeof(struct Interrupt
), MEMF_PUBLIC
| MEMF_CLEAR
);
246 AllocMem(sizeof(struct cdihData
), MEMF_PUBLIC
| MEMF_CLEAR
);
249 cdihdata
->inputPort
= CreateMsgPort();
250 if (cdihdata
->inputPort
)
252 struct cdihMessage
*msg
;
255 AllocMem(sizeof(struct cdihMessage
),
256 MEMF_PUBLIC
| MEMF_CLEAR
);
259 struct MsgPort
*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
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
,
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
*,
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
);
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
));