2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
7 /****************************************************************************************/
9 #include <proto/exec.h>
10 #include <proto/intuition.h>
11 #include <proto/alib.h>
12 #include <proto/layers.h>
13 #include <proto/graphics.h>
14 #include <proto/keymap.h>
15 #include <proto/utility.h>
16 #include <proto/input.h>
17 #include <proto/timer.h>
18 #include <exec/memory.h>
19 #include <exec/alerts.h>
20 #include <exec/interrupts.h>
21 #include <exec/ports.h>
22 #include <intuition/intuition.h>
23 #include <intuition/intuitionbase.h>
24 #include <intuition/gadgetclass.h>
25 #include <intuition/pointerclass.h>
26 #include <intuition/cghooks.h>
27 #include <intuition/sghooks.h>
28 #include <devices/inputevent.h>
29 #include <devices/rawkeycodes.h>
30 #include <clib/macros.h>
31 #include "inputhandler.h"
33 #include "boopsigadgets.h"
34 #include "boolgadgets.h"
35 #include "propgadgets.h"
36 #include "strgadgets.h"
38 #include "intuition_intern.h" /* EWFLG_xxx */
39 #include "inputhandler_support.h"
40 #include "inputhandler_actions.h"
42 #include "monitorclass_private.h"
45 # include "smallmenu.h"
46 # include "intuition_customizesupport.h"
51 #include <aros/debug.h>
53 #define DEBUG_HANDLER(x) ;
54 #define DEBUG_KEY(x) ;
55 #define DEBUG_SCREENKEY(x) ;
56 #define DEBUG_AUTOSCROLL(x)
57 #define DEBUG_CLICK(x)
59 #define DEBUG_GADGET(x)
60 #define DEBUG_MONITOR(x)
61 #define DEBUG_MOUSE(x)
62 #define DEBUG_WINDOW(x)
64 /****************************************************************************************/
66 struct Interrupt
*InitIIH(struct IntuitionBase
*IntuitionBase
)
68 struct Interrupt
*iihandler
;
70 D(bug("InitIIH(IntuitionBase=%p)\n", IntuitionBase
));
72 iihandler
= AllocMem(sizeof (struct Interrupt
), MEMF_PUBLIC
| MEMF_CLEAR
);
75 struct IIHData
*iihdata
;
77 iihdata
= AllocMem(sizeof (struct IIHData
), MEMF_PUBLIC
| MEMF_CLEAR
);
82 port
= AllocMem(sizeof (struct MsgPort
), MEMF_PUBLIC
| MEMF_CLEAR
);
85 if ((iihdata
->InputEventMemPool
= CreatePool(MEMF_PUBLIC
| MEMF_CLEAR
,
86 sizeof(struct GeneratedInputEvent
) * 10,
87 sizeof(struct GeneratedInputEvent
) * 10)) &&
88 (iihdata
->ActionsMemPool
= CreatePool(MEMF_SEM_PROTECTED
,
91 const struct TagItem dragtags
[] =
93 {GA_SysGadget
, TRUE
},
94 {GA_SysGType
, GTYP_WDRAGGING
},
98 const struct TagItem sizetags
[] =
100 {GA_SysGadget
, TRUE
},
101 {GA_SysGType
, GTYP_SIZING
},
105 iihdata
->MasterDragGadget
= (struct Gadget
*)NewObjectA(GetPrivIBase(IntuitionBase
)->dragbarclass
,
107 (struct TagItem
*)dragtags
);
109 iihdata
->MasterSizeGadget
= (struct Gadget
*)NewObjectA(GetPrivIBase(IntuitionBase
)->sizebuttonclass
,
111 (struct TagItem
*)sizetags
);
113 if (iihdata
->MasterDragGadget
&& iihdata
->MasterSizeGadget
)
117 /* We do not want to be woken up by message replies.
118 We are anyway woken up about 10 times a second by
121 port
->mp_Flags
= PA_IGNORE
;
123 NEWLIST( &(port
->mp_MsgList
) );
124 iihdata
->IntuiReplyPort
= port
;
126 NEWLIST((struct List
*) &iihdata
->IntuiActionQueue
);
127 NEWLIST((struct List
*)&iihdata
->NewAllocatedInputEventList
);
128 NEWLIST((struct List
*)&iihdata
->AllocatedInputEventList
);
129 iihdata
->EndInputEventChain
= &iihdata
->ReturnInputEvent
;
130 iihdata
->FreeInputEvents
= NULL
;
132 iihdata
->ActQualifier
= IEQUALIFIER_RELATIVEMOUSE
;
134 /* Note: there are several routines like CloseWindow, which
135 expect is_Data to point to the IIHData structure, so don't
138 iihandler
->is_Code
= (VOID_FUNC
)AROS_ASMSYMNAME(IntuiInputHandler
);
139 iihandler
->is_Data
= iihdata
;
140 iihandler
->is_Node
.ln_Pri
= 50;
141 iihandler
->is_Node
.ln_Name
= "Intuition InputHandler";
143 lock
= LockIBase(0UL);
145 iihdata
->IntuitionBase
= IntuitionBase
;
149 GetPrivIBase(IntuitionBase
)->IntuiReplyPort
= iihdata
->IntuiReplyPort
;
150 GetPrivIBase(IntuitionBase
)->IntuiActionQueue
= &iihdata
->IntuiActionQueue
;
152 ReturnPtr ("InitIIH", struct Interrupt
*, iihandler
);
153 } /* f (iihdata->MasterDragGadget && iihdata->MasterSizeGadget) */
155 DisposeObject((Object
*)iihdata
->MasterDragGadget
);
156 DisposeObject((Object
*)iihdata
->MasterSizeGadget
);
158 DeletePool(iihdata
->ActionsMemPool
);
159 DeletePool(iihdata
->InputEventMemPool
);
161 } /* if (iihdata->InputEventMemPool = ... */
162 FreeMem(port
, sizeof(struct MsgPort
));
165 FreeMem(iihdata
, sizeof (struct IIHData
));
166 iihdata
->MouseBoundsActiveFlag
= FALSE
;
169 FreeMem(iihandler
, sizeof (struct Interrupt
));
171 } /* if (iihandler) */
173 ReturnPtr ("InitIIH", struct Interrupt
*, NULL
);
176 /****************************************************************************************/
178 VOID
CleanupIIH(struct Interrupt
*iihandler
, struct IntuitionBase
*IntuitionBase
)
180 struct IIHData
*iihdata
= (struct IIHData
*)iihandler
->is_Data
;
182 DisposeObject((Object
*)iihdata
->MasterDragGadget
);
183 DisposeObject((Object
*)iihdata
->MasterSizeGadget
);
185 FreeGeneratedInputEvents(iihdata
);
186 DeletePool(iihdata
->InputEventMemPool
);
187 DeletePool(iihdata
->ActionsMemPool
);
189 /* One might think that this port is still in use by the inputhandler.
190 ** However, if intuition is closed for the last time, there should be no
191 ** windows that IntuiMessage can be sent to.
193 FreeMem(iihdata
->IntuiReplyPort
, sizeof (struct MsgPort
));
195 FreeMem(iihdata
, sizeof (struct IIHData
));
196 FreeMem(iihandler
, sizeof (struct Interrupt
));
201 /****************************************************************************************/
203 static void HandleIntuiReplyPort(struct IIHData
*iihdata
, struct IntuitionBase
*IntuitionBase
)
205 struct Library
*TimerBase
= GetPrivIBase(IntuitionBase
)->TimerBase
;
206 struct IntuiMessage
*im
;
208 while ((im
= (struct IntuiMessage
*)GetMsg(iihdata
->IntuiReplyPort
)))
210 if (im
->IDCMPWindow
&& ResourceExisting(im
->IDCMPWindow
, RESOURCE_WINDOW
, IntuitionBase
))
212 struct IntWindow
*win
= (struct IntWindow
*)im
->IDCMPWindow
;
215 GetSysTime(&win
->lastmsgreplied
);
220 case IDCMP_MOUSEMOVE
:
221 IW(im
->IDCMPWindow
)->num_mouseevents
--;
224 case IDCMP_INTUITICKS
:
225 AROS_ATOMIC_AND(im
->IDCMPWindow
->Flags
, ~WFLG_WINDOWTICKED
);
228 #if USE_IDCMPUPDATE_MESSAGECACHE
229 case IDCMP_IDCMPUPDATE
:
230 IW(im
->IDCMPWindow
)->num_idcmpupdate
--;
232 if (!(IW(im
->IDCMPWindow
)->num_idcmpupdate
) && IW(im
->IDCMPWindow
)->messagecache
)
234 SendIntuiMessage(im
->IDCMPWindow
,IW(im
->IDCMPWindow
)->messagecache
);
235 IW(im
->IDCMPWindow
)->messagecache
= 0;
240 case IDCMP_MENUVERIFY
:
242 struct Window
*w
= im
->IDCMPWindow
;
243 struct IntScreen
*scr
= 0;
245 scr
= GetPrivScreen(w
->WScreen
);
247 if (scr
!= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
||
248 scr
->MenuVerifySeconds
> im
->Seconds
||
249 (scr
->MenuVerifySeconds
== im
->Seconds
&&
250 scr
->MenuVerifyMicros
> im
->Micros
))
252 /* The timeout has expired, just ignore. */
256 --scr
->MenuVerifyMsgCount
;
257 if (w
== scr
->MenuVerifyActiveWindow
&&
258 im
->Code
== MENUCANCEL
)
260 ULONG lock
= LockIBase(0);
263 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
265 if (w1
->IDCMPFlags
& IDCMP_MENUVERIFY
&& w1
!= scr
->MenuVerifyActiveWindow
)
267 ih_fire_intuimessage(w1
,
277 scr
->MenuVerifyActiveWindow
= NULL
;
278 scr
->MenuVerifyTimeOut
= 0;
279 scr
->MenuVerifyMsgCount
= 0;
280 scr
->MenuVerifySeconds
= 0;
281 scr
->MenuVerifyMicros
= 0;
282 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
284 else if (scr
->MenuVerifyMsgCount
== 0)
286 struct InputEvent ie
;
288 /* currently we ONLY need the menu open time ! */
289 ie
.ie_TimeStamp
.tv_secs
= im
->Seconds
;
290 ie
.ie_TimeStamp
.tv_micro
= im
->Micros
;
292 if (FireMenuMessage(MMCODE_START
, scr
->MenuVerifyActiveWindow
, &ie
, IntuitionBase
))
294 /* This lock will be released only when the user is
295 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
296 event arrives (generated by MenuHandler task) */
298 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
299 iihdata
->MenuWindow
= scr
->MenuVerifyActiveWindow
;
303 scr
->MenuVerifyActiveWindow
= NULL
;
304 scr
->MenuVerifyTimeOut
= 0;
305 scr
->MenuVerifyMsgCount
= 0;
306 scr
->MenuVerifySeconds
= 0;
307 scr
->MenuVerifyMicros
= 0;
308 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
314 case IDCMP_SIZEVERIFY
:
316 struct GadgetInfo
*gi
= &iihdata
->GadgetInfo
;
317 struct Window
*w
= im
->IDCMPWindow
;
318 struct Gadget
*gadget
= im
->IAddress
;
319 struct InputEvent ie
;
322 PrepareGadgetInfo(gi
, IntuitionBase
->ActiveScreen
, w
, NULL
);
323 SetGadgetInfoGadget(gi
, gadget
, IntuitionBase
);
325 if (IS_BOOPSI_GADGET(gadget
))
327 ie
.ie_NextEvent
= NULL
;
328 ie
.ie_Class
= IECLASS_RAWMOUSE
;
330 ie
.ie_Code
= IECODE_LBUTTON
;
331 ie
.ie_Qualifier
= im
->Qualifier
;
332 ie
.ie_X
= im
->MouseX
;
333 ie
.ie_Y
= im
->MouseY
;
334 ie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
335 ie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
344 /* For compatibility, send a GM_HANDLEINPUT too */
345 ie
.ie_Class
= IECLASS_RAWMOUSE
;
346 ie
.ie_Code
= IECODE_NOBUTTON
;
350 gadget
= DoGPInput(gi
,
358 /* From now on the master drag/size gadget takes over */
360 iihdata
->ActiveSysGadget
= gadget
;
361 gadget
= iihdata
->MasterSizeGadget
;
362 iihdata
->ActiveGadget
= gadget
;
364 ie
.ie_Class
= IECLASS_RAWMOUSE
;
365 ie
.ie_Code
= IECODE_LBUTTON
;
366 ie
.ie_X
= im
->MouseX
;
367 ie
.ie_Y
= im
->MouseY
;
378 case IDCMP_REQVERIFY
:
380 struct Window
*w
= im
->IDCMPWindow
;
382 EndRequest(w
->DMRequest
, w
);
384 ih_fire_intuimessage(w
,
392 case IDCMP_WBENCHMESSAGE
:
393 DEBUG_WORKBENCH(dprintf("HandleIntuiReplyPort: code 0x%lx\n",
397 } /* switch(im->Class) */
399 if (im
->Qualifier
& IEQUALIFIER_REPEAT
)
401 /* IDCMP_IDCMPUPDATE messages can also be sent from app task, therefore
402 it would be better if there was an ATOMIC_DEC macro or something */
404 if (IW(im
->IDCMPWindow
)->num_repeatevents
)
406 IW(im
->IDCMPWindow
)->num_repeatevents
--;
410 FreeIntuiMessage(im
);
412 } /* while ((im = (struct IntuiMessage *)GetMsg(iihdata->IntuiReplyPort))) */
414 /****************************************************************************************/
416 struct Window
*GetToolBoxWindow(struct InputEvent
*ie
, struct Screen
*scr
, struct IntuitionBase
*IntuitionBase
)
418 /* The caller has checked that the input event is a IECLASS_RAWMOUSE, SELECTDOWN event */
419 /* NOTE: may be called with NULL ie ptr! */
420 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
422 struct Window
*new_w
= NULL
;
426 D(bug("GetToolBoxWindow: Click at (%d,%d)\n",scr
->MouseX
,scr
->MouseY
));
429 LockLayerInfo(&scr
->LayerInfo
);
431 l
= WhichLayer(&scr
->LayerInfo
, scr
->MouseX
, scr
->MouseY
);
433 UnlockLayerInfo(&scr
->LayerInfo
);
438 D(bug("GetToolBoxWindow: Click not inside layer\n"));
440 else if (l
== scr
->BarLayer
)
445 new_w
= (struct Window
*)l
->Window
;
448 if ((new_w
->Flags
& WFLG_TOOLBOX
) == 0) new_w
= NULL
;
452 D(bug("GetToolBoxWindow: Selected layer is not a ToolBox window\n"));
456 D(bug("GetToolBoxWindow: Found layer %p\n", l
));
461 D(bug("GetToolBoxWindow: New window %p\n", new_w
));
465 /****************************************************************************************/
467 #define KEY_QUALIFIERS (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT | \
468 IEQUALIFIER_CAPSLOCK | IEQUALIFIER_CONTROL | \
469 IEQUALIFIER_LALT | IEQUALIFIER_RALT | \
470 IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND | \
471 IEQUALIFIER_NUMERICPAD)
473 #define BUTTON_QUALIFIERS (IEQUALIFIER_MIDBUTTON | IEQUALIFIER_RBUTTON | IEQUALIFIER_LEFTBUTTON)
475 static struct Gadget
*Process_RawMouse(struct InputEvent
*ie
, struct IIHData
*iihdata
, struct Screen
*screen
,
476 struct Window
*w
, struct Gadget
*gadget
, struct GadgetInfo
*gi
,
477 ULONG stitlebarhit
, BOOL new_active_window
, BOOL IsToolbox
,
478 struct InputEvent
*orig_ie
, BOOL
*keep_event
, BOOL
*reuse_event
,
479 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
480 BOOL
*call_setpointerpos
,
482 struct IntuitionBase
*IntuitionBase
)
484 struct Library
*InputBase
= GetPrivIBase(IntuitionBase
)->InputBase
;
485 struct Requester
*req
= w
? w
->FirstRequest
: NULL
;
487 switch (ie
->ie_Code
) {
490 BOOL new_gadget
= FALSE
;
491 BOOL sizeverify
= FALSE
;
492 UWORD MetaDrag
= GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_MetaDrag
;
494 DEBUG_CLICK(bug("[Inputhandler] Screen 0x%p, Window 0x%p, Gadget 0x%p, screen titlebar %d, new active window %d\n", screen
, w
, gadget
, stitlebarhit
, new_active_window
));
495 DEBUG_CLICK(if (screen
) bug("[Inputhandler] Coordinates: (%d, %d)\n", screen
->MouseX
, screen
->MouseY
));
497 iihdata
->ActQualifier
|= IEQUALIFIER_LEFTBUTTON
;
499 /* Enter screen dragging mode if LButton + MetaDrag are pressed. */
500 if (MetaDrag
&& ((iihdata
->ActQualifier
& KEY_QUALIFIERS
) == MetaDrag
)) {
501 iihdata
->ScreenDrag
= screen
;
502 iihdata
->ScreenDragPointX
= screen
->MouseX
;
503 iihdata
->ScreenDragPointY
= screen
->MouseY
;
509 iihdata
->TitlebarAppearTime
= 0;
513 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
521 struct Gadget
* draggadget
= 0;
523 if ((!(w
->FirstRequest
)) && (w
->Flags
& WFLG_DRAGBAR
) && MatchHotkey(ie
,IA_ACTIVEWINDOWMOVE
,IntuitionBase
))
525 if (w
->MouseX
< IW(w
)->sizeimage_width
|| w
->MouseX
> w
->Width
- IW(w
)->sizeimage_width
- 1 || w
->MouseY
< ((IW(w
)->sizeimage_height
> w
->BorderTop
) ? IW(w
)->sizeimage_height
: w
->BorderTop
) || w
->MouseY
> w
->Height
- IW(w
)->sizeimage_height
- 1)
527 for (draggadget
= w
->FirstGadget
; draggadget
; draggadget
= draggadget
->NextGadget
)
529 if ((draggadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
)
539 if ((!(w
->FirstRequest
)) && (w
->Flags
& WFLG_SIZEGADGET
) && MatchHotkey(ie
,IA_ACTIVEWINDOWSIZE
,IntuitionBase
))
541 if (w
->MouseX
< IW(w
)->sizeimage_width
|| w
->MouseX
> w
->Width
- IW(w
)->sizeimage_width
- 1 || w
->MouseY
< ((IW(w
)->sizeimage_height
> w
->BorderTop
) ? IW(w
)->sizeimage_height
: w
->BorderTop
) || w
->MouseY
> w
->Height
- IW(w
)->sizeimage_height
- 1)
543 for (draggadget
= w
->FirstGadget
; draggadget
; draggadget
= draggadget
->NextGadget
)
545 if ((draggadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
)
559 /* use the *current* screen rather than active one when searching
560 for sdepth gadget! */
562 gadget
= FindGadget (screen
, stitlebarhit
? NULL
: w
, stitlebarhit
? NULL
: req
,
563 screen
->MouseX
, screen
->MouseY
, gi
, FALSE
, IntuitionBase
);
564 DEBUG_CLICK(bug("Click on gadget %p\n", gadget
));
569 /* If we clicked screen titlebar outside of any gadget, enter drag mode */
570 if ((!gadget
) && stitlebarhit
) {
571 DEBUG_CLICK(bug("[Inputhandler] Entering drag state for screen 0x%p\n", screen
));
572 iihdata
->ScreenDrag
= screen
;
573 iihdata
->ScreenDragPointX
= screen
->MouseX
;
574 iihdata
->ScreenDragPointY
= screen
->MouseY
;
580 if (!gadget
&& stitlebarhit
)
582 struct Window
*ww
= 0;
584 ww
= FindDesktopWindow(screen
, IntuitionBase
);
585 DEBUG_CLICK(bug("[Inputhandler] Clicked on backdrop window 0x%p\n", ww
));
592 if (!stitlebarhit
&& !new_active_window
&& DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
593 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
595 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= SELECTDOWN
)
597 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
598 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= SELECTDOWN
;
602 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
607 DEBUG_CLICK(bug("[Inputhandler] Resetting doubleclick counter\n"));
608 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= SELECTDOWN
;
609 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
612 /* update last click time for doubleclicktofront */
613 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
614 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
621 if (!(gadget
&& ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
)))
622 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
625 if (result
== RUNHOTREUSE
)
637 if (gadget
&& new_gadget
)
639 DEBUG_GADGET(bug("[Inputhandler] Activate gadget: 0x%p\n", gadget
));
640 if (w
&& (w
->IDCMPFlags
& IDCMP_SIZEVERIFY
) &&
641 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
/*||
642 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WZOOM*/)
644 ih_fire_intuimessage(w
,
654 BOOL is_draggad
, is_sizegad
;
657 /* Whenever the active gadget changes the gi must be updated
658 because it is cached in iidata->GadgetInfo!!!! Don't
659 forget to do this if somewhere else the active
660 gadget is changed, for example in ActivateGadget!!! */
662 PrepareGadgetInfo(gi
, screen
, w
, req
);
663 SetGadgetInfoGadget(gi
, gadget
, IntuitionBase
);
665 gsystype
= gadget
->GadgetType
& GTYP_SYSTYPEMASK
;
666 is_draggad
= ((gsystype
== GTYP_WDRAGGING
)
668 || (gsystype
== GTYP_WDRAGGING2
)
671 is_sizegad
= (gsystype
== GTYP_SIZING
);
673 /* jDc: intui68k sends IDCMPs for GACT_IMMEDIATE drag&sizegads! */
674 if (gadget
->Activation
& GACT_IMMEDIATE
)
676 ih_fire_intuimessage(w
,
683 if (is_draggad
|| is_sizegad
)
685 if (IS_BOOPSI_GADGET(gadget
))
694 /* Ignoring retval of dispatcher above is what
695 AmigaOS does too for boopsi drag/resize
700 /* From now on the master drag/size gadget takes over */
701 if ((w
->MoreFlags
& WMFLG_IAMMUI
) && (w
->Flags
& WFLG_BORDERLESS
))
702 iihdata
->ActiveSysGadget
= is_draggad
? gadget
: 0;
704 iihdata
->ActiveSysGadget
= gadget
;
705 gadget
= is_draggad
? iihdata
->MasterDragGadget
: iihdata
->MasterSizeGadget
;
713 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
715 case GTYP_BOOLGADGET
:
716 /* Only set the GFLG_SELECTED flag for RELVERIFY and
717 * TOGGLESELECT gadget. It's for the user to do it if
718 * he wants for other GADGIMMEDIATE ones.
719 * Only RELVERIFY gadgets stay active.
722 if (gadget
->Activation
& (GACT_TOGGLESELECT
| GACT_RELVERIFY
))
724 gadget
->Flags
^= GFLG_SELECTED
;
725 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
728 if (gadget
->Activation
& GACT_RELVERIFY
)
730 gadget
->Activation
|= GACT_ACTIVEGADGET
;
731 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
739 case GTYP_PROPGADGET
:
740 HandlePropSelectDown(gadget
,
743 w
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
744 w
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
751 /* If the click was inside the active strgad,
752 ** then let it update cursor pos,
753 ** else deactivate stringadget and reuse event.
756 if (InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
757 gi
->gi_Requester
, gadget
,
758 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
))
762 HandleStrInput(gadget
, gi
, ie
, &imsgcode
,
767 gadget
->Flags
&= ~GFLG_SELECTED
;
769 RefreshStrGadget(gadget
, w
, req
, IntuitionBase
);
770 /* Gadget not active anymore */
776 case GTYP_CUSTOMGADGET
:
777 gadget
= DoGPInput(gi
,
780 (new_gadget
? GM_GOACTIVE
: GM_HANDLEINPUT
),
783 D(bug("new_gadget %d, goactive %p\n", new_gadget
, gadget
));
785 if (gadget
&& new_gadget
&& (!(gadget
->GadgetType
& GTYP_SIZING
)))
787 /* For compatibility, send a GM_HANDLEINPUT too */
788 struct InputEvent newie
;
791 newie
.ie_NextEvent
= NULL
;
792 newie
.ie_Class
= IECLASS_RAWMOUSE
;
793 newie
.ie_SubClass
= 0;
794 newie
.ie_Code
= IECODE_NOBUTTON
;
795 newie
.ie_Qualifier
= ie
->ie_Qualifier
;
798 newie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
799 newie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
801 gadget
= DoGPInput(gi
,
807 D(bug("handleinput %p\n", gadget
));
811 case 0: //orig gadtools / some 1.3 gadgets
812 if (IS_SYS_GADGET(gadget
))
814 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
818 if (gadget
->Activation
& GACT_RELVERIFY
)
820 gadget
->Activation
|= GACT_ACTIVEGADGET
;
821 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
822 if (gadget
->Flags
& GFLG_GADGHIMAGE
)
824 gadget
->Flags
^= GFLG_SELECTED
;
825 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
830 /* jDc: this is what original intuition does, before crashing after a while ;)*/
831 DEBUG_CLICK(bug("[Inputhandler] Sending SELECTDOWN (old gadget), window 0x%p\n", w
));
832 ih_fire_intuimessage(w
,
840 } /* switch (GadgetType) */
842 } /* if (a gadget is active) */
843 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && !sizeverify
&& !stitlebarhit
)
845 DEBUG_CLICK(bug("[Inputhandler] Sending SELECTDOWN, window 0x%p\n", w
));
846 ih_fire_intuimessage(w
,
853 } /* case SELECTDOWN */
857 iihdata
->ActQualifier
&= ~IEQUALIFIER_LEFTBUTTON
;
859 /* Ignore this event if screen drag qualifier is pressed */
860 if (iihdata
->ScreenDrag
) {
861 iihdata
->ScreenDrag
= NULL
;
867 iihdata
->TitlebarAppearTime
= 0;
871 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
878 BOOL inside
= InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
879 gi
->gi_Requester
, gadget
,
880 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
);
882 /*int selected = (gadget->Flags & GFLG_SELECTED) != 0;*/
884 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
886 case GTYP_BOOLGADGET
:
887 /* Must be a RELVERIFY gadget */
889 if (!(gadget
->Activation
& GACT_TOGGLESELECT
) && inside
)
891 gadget
->Flags
^= GFLG_SELECTED
;
892 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
897 if (IS_SYS_GADGET(gadget
))
899 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
903 if (req
&& gadget
->Activation
& GACT_ENDGADGET
)
907 req
= w
->FirstRequest
;
910 ih_fire_intuimessage(w
,
920 ih_fire_intuimessage(w
,
927 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
931 case GTYP_PROPGADGET
:
932 HandlePropSelectUp(gadget
, w
, req
, IntuitionBase
);
933 if (gadget
->Activation
& GACT_RELVERIFY
)
935 ih_fire_intuimessage(w
,
945 /* Intuition string gadgets don't care about SELECTUP */
947 case GTYP_CUSTOMGADGET
:
948 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
951 case 0: //orig gadtools / some 1.3 gadgets
952 /* jDc: adding a gadget with gtyp field set to NULL crashes intui68k
953 ** seems we don't need compatibility on this field ;) anyway we should
954 ** handle the case of GTYP_CLOSE, etc, set by some "cod3r"
956 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
957 if (gadget
->Activation
& GACT_RELVERIFY
)
959 if (gadget
->Flags
& GFLG_GADGHIMAGE
)
963 gadget
->Flags
^= GFLG_SELECTED
;
964 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
970 ih_fire_intuimessage(w
,
977 ih_fire_intuimessage(w
,
986 } /* switch GadgetType */
988 } /* if (a gadget is currently active) */
989 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
))
991 ih_fire_intuimessage(w
,
998 break; /* case SELECTUP */
1001 iihdata
->ActQualifier
|= IEQUALIFIER_RBUTTON
;
1004 iihdata
->TitlebarAppearTime
= 0;
1008 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1009 *keep_event
= FALSE
;
1013 if (DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
1014 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
1016 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= MENUDOWN
)
1018 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1019 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MENUDOWN
;
1023 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
1028 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MENUDOWN
;
1029 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1032 /* update last click time for doubleclicktofront */
1033 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
1034 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
1040 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
1042 if (result
== RUNHOTREUSE
)
1044 *reuse_event
= TRUE
;
1048 *keep_event
= FALSE
;
1052 w
= IntuitionBase
->ActiveWindow
;
1057 if ((!MENUS_ACTIVE
) && (!gadget
) && (!(iihdata
->ActQualifier
& (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_MIDBUTTON
))))
1060 struct GadgetInfo ginf
;
1062 struct Window
*wind
= FindActiveWindow(0, screen
, &hit
,IntuitionBase
);
1066 gad
= FindGadget (screen
,
1068 IntuitionBase
->ActiveScreen
->MouseX
,
1069 IntuitionBase
->ActiveScreen
->MouseY
,
1070 &ginf
, TRUE
, IntuitionBase
);
1072 if (gad
&& ((gad
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
))
1074 CreateSmallMenuTask(wind
,SMALLMENU_TYPE_WINDOWDEPTH
,IntuitionBase
);
1075 *keep_event
= FALSE
;
1079 if (gad
&& ((gad
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SDEPTH
))
1081 CreateSmallMenuTask(0,SMALLMENU_TYPE_SCREENDEPTH
,IntuitionBase
);
1082 *keep_event
= FALSE
;
1089 if (w
&& !req
&& w
->DMRequest
&& !(w
->Flags
& WFLG_RMBTRAP
))
1091 if (!MENUS_ACTIVE
&&
1092 DoubleClick(GetPrivIBase(IntuitionBase
)->DMStartSecs
,
1093 GetPrivIBase(IntuitionBase
)->DMStartMicro
,
1094 ie
->ie_TimeStamp
.tv_secs
,
1095 ie
->ie_TimeStamp
.tv_micro
))
1097 if (w
->IDCMPFlags
& IDCMP_REQVERIFY
)
1099 ih_fire_intuimessage(w
,
1105 else if (Request(w
->DMRequest
, w
))
1109 ih_fire_intuimessage(w
,
1115 *keep_event
= FALSE
;
1119 GetPrivIBase(IntuitionBase
)->DMStartSecs
= ie
->ie_TimeStamp
.tv_secs
;
1120 GetPrivIBase(IntuitionBase
)->DMStartMicro
= ie
->ie_TimeStamp
.tv_micro
;
1125 if (!(w
->Flags
& WFLG_RMBTRAP
) && !req
)
1127 struct IntScreen
*scr
= GetPrivScreen(w
->WScreen
);
1130 BOOL mouseon
= TRUE
;
1132 scr
->MenuVerifyMsgCount
= 0;
1134 if (w
->MouseX
< 0 || w
->MouseY
< 0) mouseon
= FALSE
;
1135 if (w
->MouseX
> w
->Width
|| w
->MouseY
> w
->Height
) mouseon
= FALSE
;
1137 if (w
->IDCMPFlags
& IDCMP_MENUVERIFY
&& (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
1139 ih_fire_intuimessage(w
,
1141 mouseon
? MENUHOT
: MENUWAITING
,
1144 scr
->MenuVerifyMsgCount
++;
1147 lock
= LockIBase(0);
1149 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
1151 if ((w1
->IDCMPFlags
& IDCMP_MENUVERIFY
) && (w1
!= w
) && (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
1153 ih_fire_intuimessage(w1
,
1158 ++scr
->MenuVerifyMsgCount
;
1164 /* FIXME: when a window is opened with IDCMP_MENUVERIFY
1165 * (or this event is requested via ModifyIDCMP), and a
1166 * verify operation is pending, the window should get
1167 * a verify message too. Oh well.
1170 if (scr
->MenuVerifyMsgCount
)
1172 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= scr
;
1173 scr
->MenuVerifyActiveWindow
= w
;
1174 scr
->MenuVerifyTimeOut
= 2;
1175 scr
->MenuVerifySeconds
= IntuitionBase
->Seconds
;
1176 scr
->MenuVerifyMicros
= IntuitionBase
->Micros
;
1178 else if (FireMenuMessage(MMCODE_START
, w
, NULL
/*ie*/, IntuitionBase
))
1180 /* This lock will be released only when the user is
1181 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
1182 event arrives (generated by MenuHandler task) */
1184 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
1185 iihdata
->MenuWindow
= w
;
1186 MENUS_ACTIVE
= TRUE
;
1196 switch(ie
->ie_Code
) {
1198 iihdata
->ActQualifier
&= ~IEQUALIFIER_RBUTTON
;
1199 if (GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
)
1202 struct IntScreen
*scr
= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
;
1203 ULONG lock
= LockIBase(0);
1205 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
1207 if (w1
->IDCMPFlags
& IDCMP_MENUVERIFY
&& w1
->IDCMPFlags
& IDCMP_MOUSEBUTTONS
)
1209 ih_fire_intuimessage(w1
,
1219 /* FIXME: when the active window replies the verifymessage,
1220 * it should get a IDCMP_MENUPICK/MENUNULL message.
1222 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
1223 scr
->MenuVerifyActiveWindow
= NULL
;
1224 scr
->MenuVerifyMsgCount
= 0;
1225 scr
->MenuVerifyTimeOut
= 0;
1226 scr
->MenuVerifySeconds
= 0;
1227 scr
->MenuVerifyMicros
= 0;
1232 iihdata
->ActQualifier
|= IEQUALIFIER_MIDBUTTON
;
1233 if (DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
1234 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
1236 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= MIDDLEDOWN
)
1238 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1239 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
1241 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
1243 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
1244 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1246 /* update last click time for doubleclicktofront */
1247 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
1248 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
1252 iihdata
->ActQualifier
&= ~IEQUALIFIER_MIDBUTTON
;
1257 iihdata
->TitlebarAppearTime
= 0;
1261 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1262 *keep_event
= FALSE
;
1267 if (ie
->ie_Code
== MIDDLEDOWN
)
1271 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
1273 if (result
== RUNHOTREUSE
)
1275 *reuse_event
= TRUE
;
1279 *keep_event
= FALSE
;
1283 w
= IntuitionBase
->ActiveWindow
;
1288 if (IS_BOOPSI_GADGET(gadget
))
1290 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
1293 } /* if (there is an active gadget) */
1294 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && w
!= GetPrivScreen(w
->WScreen
)->MenuVerifyActiveWindow
)
1296 ih_fire_intuimessage(w
,
1303 break; /* case MENUDOWN */
1305 case IECODE_NOBUTTON
: /* MOUSEMOVE */
1308 UWORD DWidth
, DHeight
;
1310 if (ie
->ie_Qualifier
& IEQUALIFIER_RELATIVEMOUSE
) {
1313 /* Add delta information lost in previous mousemove event. See below. */
1314 iihdata
->DeltaMouseX
= ie
->ie_X
+ iihdata
->DeltaMouseX_Correction
;
1315 iihdata
->DeltaMouseY
= ie
->ie_Y
+ iihdata
->DeltaMouseY_Correction
;
1317 #define ACCELERATOR_THRESH 2
1318 #define ACCELERATOR_MULTI 2
1320 if (GetPrivIBase(IntuitionBase
)->ActivePreferences
.EnableCLI
& MOUSE_ACCEL
)
1323 if (ABS(iihdata
->DeltaMouseX
) > ACCELERATOR_THRESH
)
1324 iihdata
->DeltaMouseX
*= ACCELERATOR_MULTI
;
1325 if (ABS(iihdata
->DeltaMouseY
) > ACCELERATOR_THRESH
)
1326 iihdata
->DeltaMouseY
*= ACCELERATOR_MULTI
;
1329 switch (GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
)
1332 iihdata
->DeltaMouseX_Correction
= 0;
1333 iihdata
->DeltaMouseX_Correction
= 0;
1337 /* Remember the delta information which gets lost because of division by PointerTicks.
1338 Will be added to prescaled deltas of next mousemove event. If this is not done, moving
1339 the mouse very slowly would cause it to not move at all */
1341 iihdata
->DeltaMouseX_Correction
= iihdata
->DeltaMouseX
% GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1342 iihdata
->DeltaMouseY_Correction
= iihdata
->DeltaMouseY
% GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1344 iihdata
->DeltaMouseX
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1345 iihdata
->DeltaMouseY
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1350 ie
->ie_X
= iihdata
->DeltaMouseX
+ IntuitionBase
->MouseX
;
1351 ie
->ie_Y
= iihdata
->DeltaMouseY
+ IntuitionBase
->MouseY
;
1353 DEBUG_MOUSE(bug("[Inputhandler] Last mouse position: (%d, %d), new mouse position: (%d, %d)\n",
1354 IntuitionBase
->MouseX
, IntuitionBase
->MouseY
, ie
->ie_X
, ie
->ie_Y
));
1355 iihdata
->DeltaMouseX
= ie
->ie_X
- IntuitionBase
->MouseX
;
1356 iihdata
->DeltaMouseY
= ie
->ie_Y
- IntuitionBase
->MouseY
;
1357 DEBUG_MOUSE(bug("[InputHandler] Delta is (%d, %d)\n", iihdata
->DeltaMouseX
, iihdata
->DeltaMouseY
));
1360 /* Calculate current display size.
1361 It's determined by the first screen on this monitor.
1362 TODO: perhaps we should just ask display driver about its current display mode? */
1363 scr
= FindFirstScreen(GetPrivIBase(IntuitionBase
)->ActiveMonitor
, IntuitionBase
);
1366 DWidth
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxX
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinX
+ 1;
1367 DHeight
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxY
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinY
+ 1;
1371 /* If there's no active screen, we take 160x160 as a limit */
1376 scr
= iihdata
->ScreenDrag
;
1378 WORD dx
= iihdata
->DeltaMouseX
;
1379 WORD dy
= iihdata
->DeltaMouseY
;
1381 UWORD spFlags
= GetPrivScreen(scr
)->SpecialFlags
;
1382 UWORD DragMode
= GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_VDragModes
[0];
1384 DEBUG_DRAG(bug("[InputHandler] Screen drag, delta is (%d, %d)\n", dx
, dy
));
1386 /* Restrict dragging to a physical display area if the driver does not allow composition or if the user wants it*/
1387 if (((spFlags
& SF_HorCompose
) != SF_HorCompose
) || (DragMode
& ICVDM_HBOUND
)) {
1388 /* Calculate limits */
1389 if (scr
->Width
> DWidth
) {
1390 min
= DWidth
- scr
->Width
;
1394 max
= DWidth
- scr
->Width
;
1396 /* The purpose of the following complex check is to prevent jumping if the
1397 screen was positioned out of user drag limits by the program itself using
1398 ScreenPosition() or OpenScreen(). We apply restrictions in parts depending
1399 on the dragging direction.
1400 Maybe the user should also be able to drag the screen back off-display in such
1402 Calculate the position we would go to */
1403 val
= scr
->LeftEdge
+ dx
;
1404 /* Determine the direction */
1405 if ((dx
< 0) && ((!(spFlags
& SF_ComposeRight
)) || (DragMode
& ICVDM_LBOUND
))) {
1406 /* Can we move at all in this direction ? */
1407 if (scr
->LeftEdge
> min
) {
1408 /* If too far, restrict it */
1410 dx
= min
- scr
->LeftEdge
;
1412 /* Just don't move if we can't */
1414 } else if ((!(spFlags
& SF_ComposeLeft
)) || (DragMode
& ICVDM_RBOUND
)) {
1415 if (scr
->LeftEdge
< max
) {
1417 dx
= max
- scr
->LeftEdge
;
1422 if (((spFlags
& SF_VertCompose
) != SF_VertCompose
) || (DragMode
& ICVDM_VBOUND
)) {
1423 DEBUG_DRAG(bug("[Inputhandler] Restricting vertical drag\n"));
1424 DEBUG_DRAG(bug("[Inputhandler] Screen size: %d, display size: %d\n", scr
->Height
, DHeight
));
1425 if (scr
->Height
> DHeight
) {
1426 min
= DHeight
- scr
->Height
;
1430 max
= DHeight
- scr
->Height
;
1432 DEBUG_DRAG(bug("[Inputhandler] Limits: min %d max %d\n", min
, max
));
1433 val
= scr
->TopEdge
+ dy
;
1434 DEBUG_DRAG(bug("[Inputhandler] New position would be %d\n", val
));
1435 if ((dy
< 0) && ((!(spFlags
& SF_ComposeBelow
)) || (DragMode
& ICVDM_TBOUND
))) {
1436 if (scr
->TopEdge
> min
) {
1438 dy
= min
- scr
->TopEdge
;
1441 } else if ((!(spFlags
& SF_ComposeAbove
)) || (DragMode
& ICVDM_BBOUND
)) {
1442 if (scr
->TopEdge
< max
) {
1444 dy
= max
- scr
->TopEdge
;
1448 DEBUG_DRAG(bug("[Inputhandler] Restricted delta will be %d\n", dy
));
1450 ScreenPosition(scr
, SPOS_RELATIVE
, dx
, dy
, 0, 0);
1453 /* Autoscroll the active screen */
1454 scr
= IntuitionBase
->ActiveScreen
;
1455 if (scr
&& (scr
->Flags
& AUTOSCROLL
) &&
1456 (GetPrivScreen(scr
)->IMonitorNode
== GetPrivIBase(IntuitionBase
)->ActiveMonitor
))
1458 WORD xval
= scr
->LeftEdge
;
1459 WORD yval
= scr
->TopEdge
;
1462 DEBUG_AUTOSCROLL(bug("[Inputhandler] Autoscroll screen 0x%p, event at (%d, %d)\n",
1463 scr
, ie
->ie_X
, ie
->ie_Y
));
1465 if ((ie
->ie_X
< 0) || (ie
->ie_X
>= DWidth
)) {
1466 DEBUG_AUTOSCROLL(bug("[InputHandler] X delta: %d pixels\n", iihdata
->DeltaMouseX
));
1467 xval
-= iihdata
->DeltaMouseX
;
1472 } else if (ie
->ie_X
>= DWidth
) {
1473 min
= DWidth
- scr
->Width
;
1479 if ((ie
->ie_Y
< 0) || (ie
->ie_Y
>= DHeight
)) {
1480 yval
-= iihdata
->DeltaMouseY
;
1483 /* If screen is dragged down and user touched upper screen
1484 boundary, do nothing */
1485 if (scr
->TopEdge
>= 0)
1486 yval
= scr
->TopEdge
;
1488 /* If scrolled down screen is being scrolled up, make sure it
1489 does not go over 0 */
1492 } else if (ie
->ie_Y
>= DHeight
) {
1493 min
= DHeight
- scr
->Height
;
1499 if ((xval
!= scr
->LeftEdge
) || (yval
!= scr
->TopEdge
))
1500 ScreenPosition(scr
, SPOS_ABSOLUTE
, xval
, yval
, 0, 0);
1503 /* Restrict mouse coordinates to the physical display area */
1504 if (ie
->ie_X
>= DWidth
) ie
->ie_X
= DWidth
- 1;
1505 if (ie
->ie_Y
>= DHeight
) ie
->ie_Y
= DHeight
- 1;
1506 if (ie
->ie_X
< 0) ie
->ie_X
= 0;
1507 if (ie
->ie_Y
< 0) ie
->ie_Y
= 0;
1510 if (gadget
== iihdata
->MasterDragGadget
) {
1514 gpi
.MethodID
= GM_MOVETEST
;
1516 gpi
.gpi_Mouse
.X
= ie
->ie_X
- gi
->gi_Window
->WScreen
->LeftEdge
;
1517 gpi
.gpi_Mouse
.Y
= ie
->ie_Y
- gi
->gi_Window
->WScreen
->TopEdge
;
1518 gpi
.gpi_IEvent
= ie
;
1520 retval
= Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpi
, IntuitionBase
);
1521 if (retval
== MOVETEST_ADJUSTPOS
)
1523 ie
->ie_X
= gpi
.gpi_Mouse
.X
+ gi
->gi_Window
->WScreen
->LeftEdge
;
1524 ie
->ie_Y
= gpi
.gpi_Mouse
.Y
+ gi
->gi_Window
->WScreen
->TopEdge
;
1529 /* Do Mouse Bounding - mouse will be most restrictive of screen size or mouse bounds */
1530 if (iihdata
->MouseBoundsActiveFlag
) {
1531 if (ie
->ie_X
< iihdata
->MouseBoundsLeft
)
1532 ie
->ie_X
= iihdata
->MouseBoundsLeft
;
1533 else if (ie
->ie_X
> iihdata
->MouseBoundsRight
)
1534 ie
->ie_X
= iihdata
->MouseBoundsRight
;
1536 if (ie
->ie_Y
< iihdata
->MouseBoundsTop
)
1537 ie
->ie_Y
= iihdata
->MouseBoundsTop
;
1538 else if (ie
->ie_Y
> iihdata
->MouseBoundsBottom
)
1539 ie
->ie_Y
= iihdata
->MouseBoundsBottom
;
1542 /* Prevent mouse going above all screens */
1543 scr
= FindHighestScreen(IntuitionBase
);
1545 if (ie
->ie_Y
< scr
->TopEdge
)
1546 ie
->ie_Y
= scr
->TopEdge
;
1549 /* Store new mouse coords. If a screen is being dragged, lock drag point */
1550 scr
= iihdata
->ScreenDrag
;
1552 IntuitionBase
->MouseX
= scr
->LeftEdge
+ iihdata
->ScreenDragPointX
;
1553 IntuitionBase
->MouseY
= scr
->TopEdge
+ iihdata
->ScreenDragPointY
;
1555 IntuitionBase
->MouseX
= ie
->ie_X
;
1556 IntuitionBase
->MouseY
= ie
->ie_Y
;
1558 notify_mousemove_screensandwindows(IntuitionBase
);
1559 #if !SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1560 MySetPointerPos(IntuitionBase
);
1562 *call_setpointerpos
= TRUE
;
1565 screen
= FindActiveScreen(IntuitionBase
); /* The mouse was moved, so current screen may have changed */
1569 if (iihdata
->TitlebarOnTop
)
1571 if (screen
->MouseY
> screen
->BarHeight
&& GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
)
1573 iihdata
->TitlebarOnTop
= FALSE
;
1574 iihdata
->TitlebarAppearTime
= 0;
1576 LOCK_REFRESH(screen
);
1578 MoveLayer(0, screen
->BarLayer
, 0, -(screen
->BarHeight
+ 1));
1579 CheckLayers(screen
, IntuitionBase
);
1581 UNLOCK_REFRESH(screen
);
1586 if (screen
->MouseY
== 0 && GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
&& !MENUS_ACTIVE
&& !(PeekQualifier() & (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_RBUTTON
|IEQUALIFIER_MIDBUTTON
)))
1588 if (!(iihdata
->TitlebarAppearTime
))
1590 iihdata
->TitlebarAppearTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1591 iihdata
->TitlebarAppearTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1596 iihdata
->TitlebarAppearTime
= 0;
1602 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1603 *keep_event
= FALSE
;
1608 *keep_event
= FALSE
;
1610 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
1612 case GTYP_BOOLGADGET
:
1613 case 0: //fallback for sucky gadgets
1614 /* Must be a RELVERIFY gadget */
1618 inside
= InsideGadget(gi
->gi_Screen
,
1622 gi
->gi_Screen
->MouseX
,
1623 gi
->gi_Screen
->MouseY
);
1625 if (inside
!= iihdata
->MouseWasInsideBoolGadget
) {
1626 iihdata
->MouseWasInsideBoolGadget
= inside
;
1628 gadget
->Flags
^= GFLG_SELECTED
;
1629 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
1634 case GTYP_PROPGADGET
:
1635 HandlePropMouseMove(gadget
,
1638 w
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
1639 w
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
1644 case GTYP_CUSTOMGADGET
:
1645 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
1648 } /* switch GadgetType */
1650 } /* if (a gadget is currently active) */
1652 *keep_event
= FALSE
;
1657 if (IW(w
)->helpflags
& HELPF_GADGETHELP
&& (!(PeekQualifier() & (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_RBUTTON
|IEQUALIFIER_MIDBUTTON
)))) {
1661 hw
= FindActiveWindow(ie
, screen
, 0, IntuitionBase
);
1664 (!hw
|| !(IW(w
)->helpflags
& HELPF_ISHELPGROUP
) ||
1665 !(IW(hw
)->helpflags
& HELPF_ISHELPGROUP
) ||
1666 IW(w
)->helpgroup
!= IW(hw
)->helpgroup
))
1669 if (iihdata
->LastHelpWindow
)
1671 fire_intuimessage(w
,
1677 iihdata
->LastHelpGadget
= NULL
;
1678 iihdata
->LastHelpWindow
= NULL
;
1679 iihdata
->HelpGadgetFindTime
= 0;
1684 g
= FindHelpGadget (hw
,
1685 IntuitionBase
->ActiveScreen
->MouseX
,
1686 IntuitionBase
->ActiveScreen
->MouseY
,
1688 if (g
&& g
!= iihdata
->LastHelpGadget
)
1690 if (!iihdata
->LastHelpGadget
)
1692 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1693 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1695 if (hw
== iihdata
->LastHelpWindow
)
1697 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1698 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1699 iihdata
->HelpGadgetFindTime
+= 25;//smaller delay
1703 else if (g
!= iihdata
->LastHelpGadget
||
1704 hw
!= iihdata
->LastHelpWindow
)
1706 fire_intuimessage(hw
,
1708 0, /* Don't know what it should be */
1713 iihdata
->LastHelpGadget
= g
;
1714 iihdata
->LastHelpWindow
= hw
;
1717 iihdata
->LastHelpGadget
= NULL
;
1718 iihdata
->LastHelpWindow
= NULL
;
1719 iihdata
->HelpGadgetFindTime
= 0;
1722 if (!(w
->IDCMPFlags
& IDCMP_MOUSEMOVE
))
1725 /* Send IDCMP_MOUSEMOVE if WFLG_REPORTMOUSE is set
1726 and/or active gadget has GACT_FOLLOWMOUSE set */
1728 /* jDc: do NOT send when sizegad is pressed */
1729 if (!(w
->Flags
& WFLG_REPORTMOUSE
)) {
1732 if (!(gadget
->Activation
& GACT_FOLLOWMOUSE
))
1735 if (gadget
&& (gadget
->GadgetType
& (GTYP_SIZING
|GTYP_WDRAGGING
)))
1739 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
1741 /* Limit the number of IDCMP_MOUSEMOVE messages sent to intuition.
1742 note that this comes after handling gadgets, because gadgets should get all events.
1745 if (IW(w
)->num_mouseevents
>= IW(w
)->mousequeue
) {
1746 BOOL old_msg_found
= FALSE
;
1748 /* Mouse Queue is full, so try looking for a not
1749 yet GetMsg()ed IntuiMessage in w->UserPort
1750 trying to modify that. */
1755 struct IntuiMessage
*im
;
1757 for (im
= (struct IntuiMessage
*)w
->UserPort
->mp_MsgList
.lh_TailPred
;
1758 im
->ExecMessage
.mn_Node
.ln_Pred
;
1759 im
= (struct IntuiMessage
*)im
->ExecMessage
.mn_Node
.ln_Pred
)
1761 if ((im
->Class
== IDCMP_MOUSEMOVE
) &&
1762 (im
->IDCMPWindow
== w
))
1764 im
->Qualifier
= iihdata
->ActQualifier
;
1766 if (w
->IDCMPFlags
& IDCMP_DELTAMOVE
)
1768 im
->MouseX
= iihdata
->DeltaMouseX
;
1769 im
->MouseY
= iihdata
->DeltaMouseY
;
1773 im
->MouseX
= w
->MouseX
;
1774 im
->MouseY
= w
->MouseY
;
1776 CurrentTime(&im
->Seconds
, &im
->Micros
);
1778 old_msg_found
= TRUE
;
1782 } /* if (w->UserPort) */
1785 /* no need to send a new message if we modified
1786 an existing one ... */
1788 if (old_msg_found
) break;
1790 /* ... otherwise we are in a strange situation. The mouse
1791 queue is full, but we did not find an existing MOUSEMOVE
1792 imsg in w->UserPort. So the app probably has removed
1793 an imsg from the UserPort with GetMsg but we did not get
1794 the ReplyMsg, yet. In this case we do send a new message */
1796 HandleIntuiReplyPort(iihdata
, IntuitionBase
);
1800 /* MouseQueue is not full, so we can send a message. We increase
1801 IntWindow->num_mouseevents which will later be decreased after
1802 the Intuition InputHandler gets the ReplyMessage from the app
1803 and handles it in HandleIntuiReplyPort() */
1805 if (ih_fire_intuimessage(w
, IDCMP_MOUSEMOVE
, IECODE_NOBUTTON
, w
, IntuitionBase
))
1806 IW(w
)->num_mouseevents
++;
1810 } /* case IECODE_NOBUTTON */
1811 } /* switch (ie->ie_Code) (what button was pressed ?) */
1816 /****************************************************************************************/
1818 AROS_UFH2(struct InputEvent
*, IntuiInputHandler
,
1819 AROS_UFHA(struct InputEvent
*, oldchain
, A0
),
1820 AROS_UFHA(struct IIHData
*, iihdata
, A1
)
1825 struct InputEvent
*ie
, *orig_ie
, *next_ie
, stackie
;
1826 struct Gadget
*gadget
= NULL
;
1827 struct IntuitionBase
*IntuitionBase
= iihdata
->IntuitionBase
;
1828 struct Library
*KeymapBase
= GetPrivIBase(IntuitionBase
)->KeymapBase
;
1829 struct Screen
*screen
;
1831 struct GadgetInfo
*gi
= &iihdata
->GadgetInfo
;
1832 BOOL reuse_event
, ie_used
;
1834 struct Requester
*req
;
1835 ULONG stitlebarhit
= 0;
1836 #if 0 /* Toolbox is broken-as-designed */
1837 struct Window
*toolbox
;
1838 struct GadgetInfo
*boxgi
= &iihdata
->BoxGadgetInfo
;
1839 struct Gadget
*boxgadget
= NULL
;
1841 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1842 BOOL call_setpointerpos
= FALSE
;
1845 D(bug("Inside intuition inputhandler, active window=%p\n", IntuitionBase
->ActiveWindow
));
1846 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->InputHandlerLock
);
1848 if (!iihdata
->InputDeviceTask
) iihdata
->InputDeviceTask
= FindTask(NULL
);
1850 /* Then free generated InputEvents done in the previous round */
1852 FreeGeneratedInputEvents(iihdata
);
1854 /* First handle IntuiMessages which were replied back to the IntuiReplyPort
1857 HandleIntuiReplyPort(iihdata
, IntuitionBase
);
1859 /* Handle action messages */
1861 HandleIntuiActions(iihdata
, IntuitionBase
);
1863 /* Now handle the input events */
1866 reuse_event
= FALSE
;
1869 /* shut up the compiler */
1873 gadget
= iihdata
->ActiveGadget
;
1875 while (reuse_event
|| next_ie
)
1877 struct Window
*old_w
;
1878 BOOL keep_event
= TRUE
;
1879 BOOL new_active_window
= FALSE
;
1880 Object
*newmonitor
= GetPrivIBase(IntuitionBase
)->NewMonitor
;
1882 /* Process hosted display activation event (if any).
1883 This is experimental. If this works badly, we'll possibly have to put it into
1884 input events queue */
1886 DEBUG_MONITOR(bug("[Inputhandler] Activating monitor 0x%p\n", newmonitor
));
1887 GetPrivIBase(IntuitionBase
)->NewMonitor
= NULL
;
1888 ActivateMonitor(newmonitor
, -1, -1, IntuitionBase
);
1889 iihdata
->SwitchedMonitor
= TRUE
;
1896 next_ie
= ie
->ie_NextEvent
;
1900 D(bug("iih: Handling event of class %d, code %d\n", ie
->ie_Class
, ie
->ie_Code
));
1901 reuse_event
= FALSE
;
1903 /* If the monitor has been changed, this possibly happened because of mouse click in
1904 its display window. In such a case we have to update current mouse coordinates
1905 from the first absolute mouse event. Otherwise input will misbehave. */
1906 if (iihdata
->SwitchedMonitor
&& (ie
->ie_Class
== IECLASS_RAWMOUSE
)) {
1907 iihdata
->SwitchedMonitor
= FALSE
;
1908 if (!(ie
->ie_Qualifier
& IEQUALIFIER_RELATIVEMOUSE
)) {
1909 DEBUG_MONITOR(bug("[Inputhandler] Adjusting coordinates to (%d, %d)\n", ie
->ie_X
, ie
->ie_Y
));
1910 IntuitionBase
->MouseX
= ie
->ie_X
;
1911 IntuitionBase
->MouseY
= ie
->ie_Y
;
1912 notify_mousemove_screensandwindows(IntuitionBase
);
1916 /* new event, we need to reset this */
1917 screen
= FindActiveScreen(IntuitionBase
);
1918 iihdata
->ActEventTablet
= 0;
1920 /* Set the timestamp in IntuitionBase */
1922 IntuitionBase
->Seconds
= ie
->ie_TimeStamp
.tv_secs
;
1923 IntuitionBase
->Micros
= ie
->ie_TimeStamp
.tv_micro
;
1925 #if 0 /* toolbox stuff disabled. broken. calling LockLayerinfo() for every event is broken. deadlocks */
1926 /* Use event to find the active window */
1928 toolbox
= GetToolBoxWindow(ie
, screen
, IntuitionBase
);
1932 /* Do ToolBox Window Actions */
1933 /* ToolBox Windows supports only a subset of IECLASS Actions */
1934 switch (ie
->ie_Class
) {
1936 case IECLASS_RAWMOUSE
:
1937 boxgadget
= Process_RawMouse(ie
, iihdata
, screen
, toolbox
, boxgadget
, boxgi
, 0, FALSE
, TRUE
,
1938 orig_ie
, &keep_event
, &reuse_event
,
1939 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1940 &call_setpointerpos
,
1945 } /* switch (ie->ie_Class) */
1946 } /* if (toolbox) */
1949 w
= IntuitionBase
->ActiveWindow
;
1951 if (!MENUS_ACTIVE
&& !SYSGADGET_ACTIVE
)
1953 /* lock = LockIBase(0UL); */
1956 if (ie
->ie_Class
== IECLASS_RAWMOUSE
&& ie
->ie_Code
== SELECTDOWN
)
1958 w
= FindActiveWindow(ie
, screen
, &stitlebarhit
, IntuitionBase
);
1959 DEBUG_CLICK(bug("iih:New active window: %p\n", w
));
1967 DEBUG_WINDOW(bug("Activating new window (title %s)\n", w
->Title
? w
->Title
: "<noname>"));
1969 DEBUG_WINDOW(bug("Window activated\n"));
1973 DEBUG_WINDOW(bug("Making active window inactive. Now there's no active window\n"));
1975 new_active_window
= TRUE
;
1976 iihdata
->NewActWindow
= w
;
1979 /* UnlockIBase(lock); */
1981 if (new_active_window
)
1984 (!(GetPrivScreen(w
->WScreen
)->MenuVerifyMsgCount
)) &&
1985 (!(MENUS_ACTIVE
)) && (!(SYSGADGET_ACTIVE
)))
1987 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
1990 case GTYP_CUSTOMGADGET
:
1992 struct gpGoInactive gpgi
;
1994 gpgi
.MethodID
= GM_GOINACTIVE
;
1995 gpgi
.gpgi_GInfo
= gi
;
1996 gpgi
.gpgi_Abort
= 1;
1998 Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpgi
, IntuitionBase
);
2002 case GTYP_STRGADGET
:
2003 gadget
->Flags
&= ~GFLG_SELECTED
;
2004 RefreshStrGadget(gadget
, gi
->gi_Window
, gi
->gi_Requester
, IntuitionBase
);
2007 case GTYP_BOOLGADGET
:
2008 /* That a bool gadget is active here can only happen
2009 if user used LMB to activate gadget and LAMIGA + LALT
2010 to activate other window, or viceversa */
2011 /* The gadget must be a RELVERIFY one */
2012 if (!(gadget
->Activation
& GACT_TOGGLESELECT
))
2016 inside
= InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
2017 gi
->gi_Requester
, gadget
,
2018 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
);
2022 gadget
->Flags
&= ~GFLG_SELECTED
;
2023 RefreshBoolGadgetState(gadget
, gi
->gi_Window
,
2024 gi
->gi_Requester
, IntuitionBase
);
2029 case GTYP_PROPGADGET
:
2030 /* That a prop gadget is active here can only happen
2031 if user used LMB to activate gadget and LAMIGA + LALT
2032 to activate other window, or viceversa */
2034 HandlePropSelectUp(gadget
, gi
->gi_Window
, NULL
, IntuitionBase
);
2035 if (gadget
->Activation
& GACT_RELVERIFY
)
2037 ih_fire_intuimessage(gi
->gi_Window
,
2045 } /* switch (gadget->GadgetType & GTYP_GTYPEMASK) */
2047 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
2048 iihdata
->ActiveGadget
= NULL
;
2052 /* ActivateWindow works if w = NULL */
2053 /* jacaDcaps: some gui toolkits (die reaction, die!) close the window opened by a boopsi gadget when
2054 it gets hit with lmb, so we need to check if the new active window does not go away by
2055 performing GM_GOINACTIVE on the gadget. NOTE: CloseWindow's part performed on input.device context
2056 clears the iihdata->NewActWindow if it's the actually closed one. */
2057 if (w
== iihdata
->NewActWindow
)
2063 w
= IntuitionBase
->ActiveWindow
;
2064 new_active_window
= FALSE
;
2065 ie
->ie_Class
= IECLASS_NULL
; //lose the event, otherwise the gadget will get activated again ;)
2068 iihdata
->NewActWindow
= 0;
2070 } /* if (new_active_window) */
2072 } /* if (!MENUS_ACTIVE) */
2077 req
= w
->FirstRequest
;
2080 D(bug("[Inputhandler] Screen 0x%p Window 0x%p Requester 0x%p gadget 0x%p\n", screen
, w
, req
, gadget
));
2082 switch (ie
->ie_Class
) {
2083 case IECLASS_POINTERPOS
:
2084 ie
->ie_SubClass
= IESUBCLASS_COMPATIBLE
;
2087 case IECLASS_NEWPOINTERPOS
:
2088 switch (ie
->ie_SubClass
)
2090 case IESUBCLASS_COMPATIBLE
:
2091 ie
->ie_Code
= IECODE_NOBUTTON
;
2094 case IESUBCLASS_PIXEL
:
2096 struct IEPointerPixel
*pp
= ie
->ie_EventAddress
;
2098 ie
->ie_X
= pp
->iepp_Position
.X
+ pp
->iepp_Screen
->LeftEdge
;
2099 ie
->ie_Y
= pp
->iepp_Position
.Y
+ pp
->iepp_Screen
->TopEdge
;
2101 ActivateMonitor(GetPrivScreen(pp
->iepp_Screen
)->IMonitorNode
, ie
->ie_X
, ie
->ie_Y
, IntuitionBase
);
2103 ie
->ie_Class
= IECLASS_RAWMOUSE
; /* otherwise a lot of code would ignore this message */
2104 ie
->ie_Code
= IECODE_NOBUTTON
;
2107 case IESUBCLASS_TABLET
:
2109 //unsupported - does anything use it anyway? ;)
2114 case IESUBCLASS_NEWTABLET
:
2116 struct IENewTablet
*nt
= (struct IENewTablet
*)ie
->ie_EventAddress
;
2120 iihdata
->ActEventTablet
= nt
; //cache this
2121 ie
->ie_X
= (screen
->Width
* nt
->ient_TabletX
) / nt
->ient_RangeX
;
2122 ie
->ie_Y
= (screen
->Height
* nt
->ient_TabletY
) / nt
->ient_RangeY
;
2124 ie
->ie_Class
= IECLASS_RAWMOUSE
;
2134 case IECLASS_RAWMOUSE
:
2135 gadget
= Process_RawMouse(ie
, iihdata
, screen
, w
, gadget
, gi
, stitlebarhit
, new_active_window
, FALSE
,
2136 orig_ie
, &keep_event
, &reuse_event
,
2137 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
2138 &call_setpointerpos
,
2144 case IECLASS_RAWKEY
:
2145 /* release events go only to gadgets and windows who
2146 have not set IDCMP_VANILLAKEY */
2148 DEBUG_HANDLER(dprintf("Handler: IECLASS_RAWKEY\n"));
2149 DEBUG_KEY(dprintf("Handler: Qual 0x%lx\n",iihdata
->ActQualifier
));
2151 iihdata
->ActQualifier
&= ~(KEY_QUALIFIERS
| IEQUALIFIER_REPEAT
);
2152 iihdata
->ActQualifier
|= (ie
->ie_Qualifier
& (KEY_QUALIFIERS
| IEQUALIFIER_REPEAT
));
2154 DEBUG_KEY(dprintf("Handler: real Qual 0x%lx\n",iihdata
->ActQualifier
));
2156 /* Keyboard mouse emulation and screen switching */
2159 UWORD code
= ie
->ie_Code
& ~IECODE_UP_PREFIX
;
2160 DEBUG_KEY(dprintf("Handler: code 0x%lx\n",code
));
2162 /* Left Amiga + N/M screen switching shortcut */
2163 if ((ie
->ie_Qualifier
& IEQUALIFIER_LCOMMAND
) && (code
== RAWKEY_N
|| code
== RAWKEY_M
)) {
2164 if (!(ie
->ie_Qualifier
& IEQUALIFIER_REPEAT
) && !(ie
->ie_Code
& IECODE_UP_PREFIX
)) {
2165 if (code
== RAWKEY_N
)
2167 else if (code
== RAWKEY_M
)
2168 ScreenToBack(IntuitionBase
->FirstScreen
);
2174 /* Mouse button emulation: LALT + LAMIGA = LBUTTON, RALT + RAMIGA = RBUTTON */
2175 if ((code
== RAWKEY_LAMIGA
) ||
2176 (code
== RAWKEY_LALT
) ||
2177 (code
== RAWKEY_RAMIGA
) ||
2178 (code
== RAWKEY_RALT
))
2180 DEBUG_KEY(dprintf("Handler: KeyMouseEmul\n"));
2181 iihdata
->PrevKeyMouseState
= iihdata
->ActKeyMouseState
;
2182 iihdata
->ActKeyMouseState
= 0;
2183 if ((ie
->ie_Qualifier
& (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_LALT
)) == (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_LALT
))
2185 iihdata
->ActKeyMouseState
|= IEQUALIFIER_LEFTBUTTON
;
2187 if ((ie
->ie_Qualifier
& (IEQUALIFIER_RCOMMAND
| IEQUALIFIER_RALT
)) == (IEQUALIFIER_RCOMMAND
| IEQUALIFIER_RALT
))
2189 iihdata
->ActKeyMouseState
|= IEQUALIFIER_RBUTTON
;
2192 if ((iihdata
->ActKeyMouseState
& IEQUALIFIER_LEFTBUTTON
) != (iihdata
->PrevKeyMouseState
& IEQUALIFIER_LEFTBUTTON
))
2194 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2195 orig_ie
->ie_SubClass
= 0;
2196 orig_ie
->ie_Code
= (iihdata
->ActKeyMouseState
& IEQUALIFIER_LEFTBUTTON
) ? IECODE_LBUTTON
: IECODE_LBUTTON
| IECODE_UP_PREFIX
;
2205 if ((iihdata
->ActKeyMouseState
& IEQUALIFIER_RBUTTON
) != (iihdata
->PrevKeyMouseState
& IEQUALIFIER_RBUTTON
))
2207 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2208 orig_ie
->ie_SubClass
= 0;
2209 orig_ie
->ie_Code
= (iihdata
->ActKeyMouseState
& IEQUALIFIER_RBUTTON
) ? IECODE_RBUTTON
: IECODE_RBUTTON
| IECODE_UP_PREFIX
;
2218 } /* if key is one of LAMIGA/LALT/RAMIGA/RALT */
2220 if ((iihdata
->ActQualifier
& (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_RCOMMAND
)) &&
2221 ((ie
->ie_Code
== RAWKEY_UP
) ||
2222 (ie
->ie_Code
== RAWKEY_DOWN
) ||
2223 (ie
->ie_Code
== RAWKEY_LEFT
) ||
2224 (ie
->ie_Code
== RAWKEY_RIGHT
)))
2226 static BYTE
const xmap
[] = { 0, 0, 1, -1};
2227 static BYTE
const ymap
[] = {-1, 1, 0, 0};
2230 shift
= (iihdata
->ActQualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) ? 40 : 1;
2232 /* Mouse Move Emulation */
2234 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2235 orig_ie
->ie_SubClass
= 0;
2236 orig_ie
->ie_Code
= IECODE_NOBUTTON
;
2237 orig_ie
->ie_Qualifier
= IEQUALIFIER_RELATIVEMOUSE
;
2238 orig_ie
->ie_X
= xmap
[code
- RAWKEY_UP
] * shift
;
2239 orig_ie
->ie_Y
= ymap
[code
- RAWKEY_UP
] * shift
;
2248 /* End Keyboard mouse emulation */
2252 DEBUG_KEY(dprintf("Handler: FireMenuMessage\n"));
2253 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2258 /* Hotkeys processing */
2263 if (!(ie
->ie_Code
& IECODE_UP_PREFIX
))
2264 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
2266 if (result
== RUNHOTREUSE
)
2276 w
= IntuitionBase
->ActiveWindow
;
2281 ((!(ie
->ie_Code
& IECODE_UP_PREFIX
)) ||
2283 (w
&& ((w
->IDCMPFlags
& IDCMP_VANILLAKEY
) == 0)) ))
2289 DEBUG_KEY(dprintf("Handler: Gadget 0x%lx active\n",gadget
));
2290 DEBUG_KEY(dprintf("Handler: GadgetID 0x%lx UserData 0x%lx\n",
2293 DEBUG_KEY(dprintf("Handler: GadgetType 0x%lx Flags 0x%lx Activation 0x%lx\n",
2296 gadget
->Activation
));
2297 DEBUG_KEY(dprintf("Handler: MoreFlags 0x%lx\n",
2298 ((struct ExtGadget
*)gadget
)->MoreFlags
));
2300 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
2302 case GTYP_STRGADGET
:
2305 ULONG ret
= HandleStrInput(gadget
, gi
, ie
, &imsgcode
,
2308 DEBUG_KEY(dprintf("Handler: Key GTYP_STRGADGET ret 0x%lx\n",ret
));
2309 if (ret
& (SGA_END
| SGA_NEXTACTIVE
| SGA_PREVACTIVE
))
2311 if (gadget
->Activation
& GACT_RELVERIFY
)
2313 DEBUG_KEY(dprintf("Handler: GACT_RELVERIFY\n"));
2314 ih_fire_intuimessage(w
,
2320 if (req
&& gadget
->Activation
& GACT_ENDGADGET
)
2322 DEBUG_KEY(dprintf("Handler: GACT_ENDGADGET\n"));
2325 req
= w
->FirstRequest
;
2330 if ((gadget
->Flags
& GFLG_TABCYCLE
) && (ret
& SGA_NEXTACTIVE
))
2332 gadget
= FindCycleGadget(w
, req
, gadget
, GMR_NEXTACTIVE
);
2333 DEBUG_KEY(dprintf("Handler: TabCycle next gadget 0x%lx\n",gadget
));
2335 else if ((gadget
->Flags
& GFLG_TABCYCLE
) && (ret
& SGA_PREVACTIVE
))
2337 gadget
= FindCycleGadget(w
, req
, gadget
, GMR_PREVACTIVE
);
2338 DEBUG_KEY(dprintf("Handler: TabCycle prev gadget 0x%lx\n",gadget
));
2347 gadget
= DoActivateGadget(w
, req
, gadget
, IntuitionBase
);
2350 } /* if (ret & (SGA_END | SGA_NEXTACTIVE | SGA_PREVACTIVE)) */
2355 case GTYP_CUSTOMGADGET
:
2356 DEBUG_KEY(dprintf("Handler: GTYP_CUSTOMGADGET\n"));
2357 DEBUG_KEY(dprintf("Handler: send GM_HANDLEINPUT\n"));
2358 gadget
= DoGPInput(gi
,
2364 DEBUG_KEY(dprintf("Handler: reuse %ld\n",reuse_event
));
2367 } /* switch (gadget type) */
2369 } /* if (a gadget is currently active) */
2370 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
))
2372 BOOL menushortcut
= FALSE
;
2374 DEBUG_KEY(dprintf("Handler: No Gadget active\n"));
2375 DEBUG_KEY(dprintf("Handler: Qualifier 0x%lx WinFlags 0x%lx IDCMP 0x%lx\n",ie
->ie_Qualifier
,w
->Flags
,w
->IDCMPFlags
));
2377 if ((ie
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
) &&
2378 (!(w
->Flags
& WFLG_RMBTRAP
)) &&
2379 (w
->IDCMPFlags
& IDCMP_MENUPICK
))
2381 struct Menu
*strip
= 0;
2383 DEBUG_KEY(dprintf("Handler: MenuKey\n"));
2384 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2386 strip
= w
->MenuStrip
;
2388 if (((struct IntWindow
*)w
)->menulendwindow
)
2390 strip
= ((struct IntWindow
*)w
)->menulendwindow
->MenuStrip
;
2393 DEBUG_KEY(dprintf("Handler: MenuStrip 0x%lx\n",strip
));
2398 if (MapRawKey(ie
, &key
, 1, NULL
) == 1)
2402 menucode
= FindMenuShortCut(strip
, key
, TRUE
, IntuitionBase
);
2404 DEBUG_KEY(dprintf("Handler: menucode 0x%lx\n",menucode
));
2406 if (menucode
!= MENUNULL
)
2408 DEBUG_KEY(dprintf("Handler: build menuevent\n"));
2409 ie
->ie_Class
= IECLASS_MENU
;
2410 ie
->ie_SubClass
= IESUBCLASS_MENUSTOP
;
2411 ie
->ie_EventAddress
= w
;
2412 ie
->ie_Code
= menucode
;
2415 menushortcut
= TRUE
;
2417 MENUS_ACTIVE
= TRUE
;
2418 iihdata
->MenuWindow
= w
;
2423 DEBUG_KEY(dprintf("Handler: MapRawKey failed\n"));
2426 if (!menushortcut
) /* !! */
2427 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2429 } /* if could be a menu short cut */
2431 if ((ie
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
) &&
2432 (!(w
->IDCMPFlags
& IDCMP_MENUPICK
)))
2434 struct Menu
*strip
= 0;
2435 struct Window
*window
= w
;
2437 /* not sure here about RMBTRAP */
2438 DEBUG_KEY(dprintf("Handler: no idcmp, create a MENULIST idcmp\n"));
2440 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2442 strip
= w
->MenuStrip
;
2444 if (((struct IntWindow
*)w
)->menulendwindow
)
2446 strip
= ((struct IntWindow
*)w
)->menulendwindow
->MenuStrip
;
2447 window
= ((struct IntWindow
*)w
)->menulendwindow
;
2450 DEBUG_KEY(dprintf("Handler: MenuStrip 0x%lx\n",strip
));
2455 if (MapRawKey(ie
, &key
, 1, NULL
) == 1)
2459 menucode
= FindMenuShortCut(strip
, key
, TRUE
, IntuitionBase
);
2461 DEBUG_KEY(dprintf("Handler: menucode 0x%lx\n",menucode
));
2463 if (menucode
!= MENUNULL
)
2465 DEBUG_KEY(dprintf("Handler: build menuevent\n"));
2466 ih_fire_intuimessage(window
,
2469 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machines!? */
2472 menushortcut
= TRUE
;
2477 DEBUG_KEY(dprintf("Handler: MapRawKey failed\n"));
2480 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2481 } /* if could be a menu short but current window has no idcmp cut */
2485 DEBUG_KEY(dprintf("Handler: menu shortcut..break\n"));
2489 /* This is a regular RAWKEY event (no gadget taking care
2492 if (iihdata
->ActQualifier
& IEQUALIFIER_REPEAT
)
2494 /* don't send repeat key events if repeatqueue is full */
2495 if (IW(w
)->num_repeatevents
>= IW(w
)->repeatqueue
)
2497 DEBUG_KEY(dprintf("Handler: RepeatEvents full..don't send more\n"));
2502 if (w
->IDCMPFlags
& IDCMP_VANILLAKEY
)
2506 DEBUG_KEY(dprintf("Handler: VANILLAKEY\n"));
2507 // DEBUG_KEY(dprintf("Handler: MapRawKey ie 0x%lx KeyMapBase 0x%lx IntutionBase 0x%lx\n",ie,KeymapBase,IntuitionBase));
2509 if (MapRawKey(ie
, &keyBuffer
, 1, NULL
) == 1)
2511 DEBUG_KEY(dprintf("Handler: send VANILLAKEY msg\n"));
2512 ih_fire_intuimessage(w
,
2515 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machines!? */
2517 DEBUG_KEY(dprintf("Handler: done\n"));
2521 /* If the event mapped to more than one byte, it is not
2522 a legal VANILLAKEY, so we send it as the original
2527 if (w
->IDCMPFlags
& IDCMP_RAWKEY
)
2529 DEBUG_KEY(dprintf("Handler: send IDCMP_RAWKEY Qual 0x%lx Code 0x%lx addr 0x%lx Event\n",
2530 ie
->ie_Qualifier
,ie
->ie_Code
,ie
->ie_position
.ie_addr
));
2531 ih_fire_intuimessage(w
,
2534 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machine!? */
2539 DEBUG_KEY(dprintf("Handler: done\n"));
2540 } /* regular RAWKEY */
2543 break; /* case IECLASS_RAWKEY */
2546 if (iihdata
->MouseBoundsKillTimer
)
2548 iihdata
->MouseBoundsKillTimer
--;
2549 if (iihdata
->MouseBoundsKillTimer
== 0)
2551 iihdata
->MouseBoundsActiveFlag
= FALSE
;
2555 if (GetPrivIBase(IntuitionBase
)->PointerDelay
)
2557 ULONG lock
= LockIBase(0);
2559 if (--GetPrivIBase(IntuitionBase
)->PointerDelay
== 0)
2561 struct SharedPointer
*shared_pointer
;
2562 struct Window
*window
= IntuitionBase
->ActiveWindow
;
2563 struct IntScreen
*scr
;
2565 DEBUG_POINTER(dprintf("InputHandler: PointerDelay\n"));
2566 DEBUG_POINTER(dprintf("InputHandler: Window 0x%lx\n",
2571 Object
*pointer
= ((struct IntWindow
*)window
)->pointer
;
2573 DEBUG_POINTER(dprintf("InputHandler: Pointer 0x%lx\n",
2575 scr
= GetPrivScreen(window
->WScreen
);
2578 DEBUG_POINTER(dprintf("InputHandler: Screen 0x%lx\n",
2580 if (pointer
== NULL
)
2582 pointer
= GetPrivIBase(IntuitionBase
)->DefaultPointer
;
2585 if (((struct IntWindow
*)window
)->busy
)
2587 pointer
= GetPrivIBase(IntuitionBase
)->BusyPointer
;
2590 GetAttr(POINTERA_SharedPointer
, pointer
, (IPTR
*) &shared_pointer
);
2592 DEBUG_POINTER(dprintf("InputHandler: scr 0x%lx pointer 0x%lx shared_pointer 0x%lx\n",
2593 scr
, pointer
, shared_pointer
));
2594 DEBUG_POINTER(dprintf("InputHandler: sprite 0x%lx\n",
2595 shared_pointer
->sprite
));
2597 if (DoMethod(scr
->IMonitorNode
, MM_SetPointerShape
, shared_pointer
))
2599 ObtainSharedPointer(shared_pointer
, IntuitionBase
);
2600 ReleaseSharedPointer(scr
->Pointer
, IntuitionBase
);
2601 scr
->Pointer
= shared_pointer
;
2604 window
->XOffset
= shared_pointer
->xoffset
;
2605 window
->YOffset
= shared_pointer
->yoffset
;
2610 DEBUG_POINTER(dprintf("InputHandler: can't set pointer.\n"));
2615 DEBUG_POINTER(dprintf("InputHandler: no screen.\n"));
2620 DEBUG_POINTER(dprintf("InputHandler: no window.\n"));
2627 if (GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
)
2629 struct IntScreen
*scr
= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
;
2631 if ((--scr
->MenuVerifyTimeOut
) <= 0)
2633 struct InputEvent ie
;
2635 /* currently we ONLY need the menu open time ! */
2636 ie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
2637 ie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
2639 if (FireMenuMessage(MMCODE_START
, scr
->MenuVerifyActiveWindow
, &ie
, IntuitionBase
))
2641 /* This lock will be released only when the user is
2642 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
2643 event arrives (generated by MenuHandler task) */
2645 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2646 iihdata
->MenuWindow
= scr
->MenuVerifyActiveWindow
;
2647 MENUS_ACTIVE
= TRUE
;
2650 scr
->MenuVerifyActiveWindow
= NULL
;
2651 scr
->MenuVerifyTimeOut
= 0;
2652 scr
->MenuVerifyMsgCount
= 0;
2653 scr
->MenuVerifySeconds
= 0;
2654 scr
->MenuVerifyMicros
= 0;
2655 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
2658 else if (MENUS_ACTIVE
)
2660 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2666 if (screen
->MouseY
<= screen
->BarHeight
&& GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
&& !iihdata
->TitlebarOnTop
&& iihdata
->TitlebarAppearTime
)
2668 UQUAD currenttime
= (((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50) + (UQUAD
)(ie
->ie_TimeStamp
.tv_micro
/ 20000);
2669 if (currenttime
>= iihdata
->TitlebarAppearTime
+ 10)
2671 iihdata
->TitlebarOnTop
= TRUE
;
2672 iihdata
->TitlebarAppearTime
= 0;
2674 LOCK_REFRESH(screen
);
2676 MoveLayer(0, screen
->BarLayer
, 0, screen
->BarHeight
+ 1);
2677 UpfrontLayer(0, screen
->BarLayer
);
2678 CheckLayers(screen
, IntuitionBase
);
2680 UNLOCK_REFRESH(screen
);
2686 UQUAD currenttime
= (((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50) + (UQUAD
)(ie
->ie_TimeStamp
.tv_micro
/ 20000);
2687 #define SECONDS(x) (x*50)
2688 if (iihdata
->HelpGadgetFindTime
&& (currenttime
>= iihdata
->HelpGadgetFindTime
+ SECONDS(1)))
2690 struct Gadget
*lhg
= iihdata
->LastHelpGadget
;
2691 fire_intuimessage(iihdata
->LastHelpWindow
,
2693 lhg
? lhg
->GadgetID
: 0, /* Don't know what it should be */
2696 iihdata
->HelpGadgetFindTime
= 0;
2702 if (IS_BOOPSI_GADGET(gadget
))
2704 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
2709 #if USE_NEWDISPLAYBEEP
2711 if (GetPrivIBase(IntuitionBase
)->BeepingScreens
)
2716 lock
= LockIBase(0);
2718 for (scr
= IntuitionBase
->FirstScreen
;
2719 scr
&& GetPrivIBase(IntuitionBase
)->BeepingScreens
;
2720 scr
= scr
->NextScreen
)
2722 if ((scr
->Flags
& BEEPING
) &&
2723 !GetPrivScreen(scr
)->BeepingCounter
--)
2725 GetPrivIBase(IntuitionBase
)->BeepingScreens
--;
2726 scr
->Flags
&= (UWORD
) ~BEEPING
;
2728 /* if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) <= 8)
2729 // visual beep on CLUT-screen
2731 // SetRGB4 (&screen->ViewPort, 0, scr->SaveColor0 & 0x000F, (scr->SaveColor0 & 0x00F0) >> 4, (scr->SaveColor0 & 0x0F00) >> 8);
2732 SetRGB32 (&scr->ViewPort, 0,
2733 GetPrivScreen(scr)->DisplayBeepColor0[0],
2734 GetPrivScreen(scr)->DisplayBeepColor0[1],
2735 GetPrivScreen(scr)->DisplayBeepColor0[2]
2739 // visual beep on hi- and truecolor screens
2741 RenderScreenBar(scr, FALSE, IntuitionBase);
2744 RenderScreenBar(scr
, FALSE
, IntuitionBase
);
2750 #endif /* USE_NEWDISPLAYBEEP */
2754 /* Send INTUITICK msg only if app already replied the last INTUITICK msg */
2755 if (w
->Flags
& WFLG_WINDOWTICKED
) break;
2757 if (w
->IDCMPFlags
& IDCMP_INTUITICKS
)
2759 /* Set the WINDOWTICKED flag, it will be cleared again when the app
2760 replies back the msg and the InputHandler handles the replymsg
2761 in HandleIntuiReplyPort() */
2763 ih_fire_intuimessage(w
,
2769 break; /* case IECLASS_TIMER */
2772 if (MENUS_ACTIVE
&& (ie
->ie_SubClass
== IESUBCLASS_MENUSTOP
))
2774 struct Window
*eventwin
= (struct Window
*)ie
->ie_EventAddress
;
2776 iihdata
->MenuWindow
= NULL
;
2777 MENUS_ACTIVE
= FALSE
;
2779 /* semaphore was locked when menu action started, see
2780 above where MMCODE_START MenuMessage is sent.
2782 It could have also have been locked if the user
2783 activated one of the menu key shortcuts, see
2784 "case IECLASS_RAWKEY" */
2786 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2790 if (((struct IntWindow
*)eventwin
)->menulendwindow
)
2792 eventwin
= ((struct IntWindow
*)eventwin
)->menulendwindow
;
2795 ih_fire_intuimessage((struct Window
*)eventwin
,
2798 (struct Window
*)ie
->ie_EventAddress
,
2804 case IECLASS_DISKINSERTED
:
2805 case IECLASS_DISKREMOVED
:
2806 case IECLASS_NEWPREFS
:
2812 switch (ie
->ie_Class
)
2814 case IECLASS_DISKINSERTED
:
2815 idcmp
= IDCMP_DISKINSERTED
;
2818 case IECLASS_DISKREMOVED
:
2819 idcmp
= IDCMP_DISKREMOVED
;
2823 idcmp
= IDCMP_NEWPREFS
;
2825 * Here we need to update the mouse prefs and
2826 * maybe other stuff which comes from the global prefs file.
2831 lock
= LockIBase(0);
2833 for (scr
= IntuitionBase
->FirstScreen
; scr
; scr
= scr
->NextScreen
)
2837 for (win
= scr
->FirstWindow
; win
; win
= win
->NextWindow
)
2840 CHECKME, really use fire_intuimessage() here,
2841 instead of ih_fireintuimessage? Same for
2842 IDCMP_GADGETHELP above, BTW. */
2844 fire_intuimessage(win
,
2856 case IECLASS_NEWMOUSE
:
2859 * The following is only needed on hardware not running
2860 * the NewMouse driver.
2862 if (w
->IDCMPFlags
& IDCMP_RAWKEY
&& (!SysBase
->MaxLocMem
))
2864 ih_fire_intuimessage(w
,
2867 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machine!? */
2877 case IECLASS_NEWTIMER
:
2880 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2887 if (gadget
== iihdata
->MasterSizeGadget
)
2889 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
2894 #endif /* __MORPHOS__ */
2899 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2906 "[Intui] InputHandler: Unknown IEClass: addr = %x class = %d (origclass = %d)\n",
2907 orig_ie
, ie
->ie_Class
,orig_ie
->ie_Class
2911 } /* switch (ie->ie_Class) */
2916 else if (keep_event
&& !ie_used
)
2918 *iihdata
->EndInputEventChain
= orig_ie
;
2919 iihdata
->EndInputEventChain
= &orig_ie
->ie_NextEvent
;
2924 orig_ie
->ie_NextEvent
= iihdata
->FreeInputEvents
;
2925 iihdata
->FreeInputEvents
= orig_ie
;
2928 } /* for (each event in the chain) */
2930 iihdata
->ActiveGadget
= gadget
;
2932 D(bug("Outside pollingloop\n"));
2934 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
2935 if (call_setpointerpos
)
2936 MySetPointerPos(IntuitionBase
);
2939 /* Terminate the event chain. */
2940 *iihdata
->EndInputEventChain
= NULL
;
2942 /* Transfer the list of allocated events in the list of events that should
2943 * be freed the next time the handler is entered.
2945 iihdata
->AllocatedInputEventList
= iihdata
->NewAllocatedInputEventList
;
2946 NEWLIST((struct List
*)&iihdata
->NewAllocatedInputEventList
);
2948 /* Reset the event chain here, not at the beginning of the handler, for
2949 * events that might be allocated in other handers.
2951 iihdata
->EndInputEventChain
= &iihdata
->ReturnInputEvent
;
2952 iihdata
->FreeInputEvents
= NULL
;
2954 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->InputHandlerLock
);
2956 // DEBUG_HANDLER(dprintf("Handler: ->IBase 0x%lx KeyMapBase 0x%lx\n",IntuitionBase,KeymapBase));
2958 return iihdata
->ReturnInputEvent
;
2963 /****************************************************************************************/