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
;
261 AllocMem(sizeof(struct MsgPort
),
262 MEMF_PUBLIC
| MEMF_CLEAR
);
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
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
,
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
*,
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
);
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
));