2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
7 /****************************************************************************************/
9 #include <aros/config.h>
11 #include <proto/exec.h>
12 #include <proto/execlock.h>
13 #include <proto/intuition.h>
14 #include <proto/alib.h>
15 #include <proto/layers.h>
16 #include <proto/graphics.h>
17 #include <proto/keymap.h>
18 #include <proto/utility.h>
19 #include <proto/input.h>
20 #include <proto/timer.h>
21 #include <exec/memory.h>
22 #include <exec/alerts.h>
23 #include <exec/interrupts.h>
24 #include <exec/ports.h>
25 #include <intuition/intuition.h>
26 #include <intuition/intuitionbase.h>
27 #include <intuition/gadgetclass.h>
28 #include <intuition/pointerclass.h>
29 #include <intuition/cghooks.h>
30 #include <intuition/sghooks.h>
31 #include <devices/inputevent.h>
32 #include <devices/rawkeycodes.h>
33 #include <clib/macros.h>
34 #include "inputhandler.h"
36 #include "boopsigadgets.h"
37 #include "boolgadgets.h"
38 #include "propgadgets.h"
39 #include "strgadgets.h"
41 #include "intuition_intern.h" /* EWFLG_xxx */
42 #include "inputhandler_support.h"
43 #include "inputhandler_actions.h"
45 #include "monitorclass_private.h"
48 # include "smallmenu.h"
49 # include "intuition_customizesupport.h"
54 #include <aros/debug.h>
56 #define DEBUG_HANDLER(x) ;
57 #define DEBUG_KEY(x) ;
58 #define DEBUG_SCREENKEY(x) ;
59 #define DEBUG_AUTOSCROLL(x)
60 #define DEBUG_CLICK(x)
62 #define DEBUG_GADGET(x)
63 #define DEBUG_MONITOR(x)
64 #define DEBUG_MOUSE(x)
65 #define DEBUG_WINDOW(x)
67 /****************************************************************************************/
69 struct Interrupt
*InitIIH(struct IntuitionBase
*IntuitionBase
)
71 struct Interrupt
*iihandler
;
73 D(bug("[Intuition] %s(IntuitionBase=%p)\n", __func__
, IntuitionBase
));
75 iihandler
= AllocMem(sizeof (struct Interrupt
), MEMF_PUBLIC
| MEMF_CLEAR
);
78 struct IIHData
*iihdata
;
80 iihdata
= AllocMem(sizeof (struct IIHData
), MEMF_PUBLIC
| MEMF_CLEAR
);
85 port
= CreateMsgPort();
88 if ((iihdata
->InputEventMemPool
= CreatePool(MEMF_PUBLIC
| MEMF_CLEAR
,
89 sizeof(struct GeneratedInputEvent
) * 10,
90 sizeof(struct GeneratedInputEvent
) * 10)) &&
91 (iihdata
->ActionsMemPool
= CreatePool(MEMF_SEM_PROTECTED
,
94 const struct TagItem dragtags
[] =
96 {GA_SysGadget
, TRUE
},
97 {GA_SysGType
, GTYP_WDRAGGING
},
101 const struct TagItem sizetags
[] =
103 {GA_SysGadget
, TRUE
},
104 {GA_SysGType
, GTYP_SIZING
},
108 iihdata
->MasterDragGadget
= (struct Gadget
*)NewObjectA(GetPrivIBase(IntuitionBase
)->dragbarclass
,
110 (struct TagItem
*)dragtags
);
112 iihdata
->MasterSizeGadget
= (struct Gadget
*)NewObjectA(GetPrivIBase(IntuitionBase
)->sizebuttonclass
,
114 (struct TagItem
*)sizetags
);
116 if (iihdata
->MasterDragGadget
&& iihdata
->MasterSizeGadget
)
120 /* We do not want to be woken up by message replies.
121 We are anyway woken up about 10 times a second by
124 FreeSignal(port
->mp_SigBit
);
125 port
->mp_SigBit
= -1;
126 port
->mp_Flags
= PA_IGNORE
;
128 iihdata
->IntuiReplyPort
= port
;
130 NEWLIST((struct List
*) &iihdata
->IntuiActionQueue
);
131 NEWLIST((struct List
*)&iihdata
->NewAllocatedInputEventList
);
132 NEWLIST((struct List
*)&iihdata
->AllocatedInputEventList
);
133 iihdata
->EndInputEventChain
= &iihdata
->ReturnInputEvent
;
134 iihdata
->FreeInputEvents
= NULL
;
136 iihdata
->ActQualifier
= IEQUALIFIER_RELATIVEMOUSE
;
138 /* Note: there are several routines like CloseWindow, which
139 expect is_Data to point to the IIHData structure, so don't
142 iihandler
->is_Code
= (VOID_FUNC
)AROS_ASMSYMNAME(IntuiInputHandler
);
143 iihandler
->is_Data
= iihdata
;
144 iihandler
->is_Node
.ln_Pri
= 50;
145 iihandler
->is_Node
.ln_Name
= "Intuition InputHandler";
147 lock
= LockIBase(0UL);
149 iihdata
->IntuitionBase
= IntuitionBase
;
153 GetPrivIBase(IntuitionBase
)->IntuiReplyPort
= iihdata
->IntuiReplyPort
;
154 GetPrivIBase(IntuitionBase
)->IntuiActionQueue
= &iihdata
->IntuiActionQueue
;
156 ReturnPtr ("InitIIH", struct Interrupt
*, iihandler
);
157 } /* f (iihdata->MasterDragGadget && iihdata->MasterSizeGadget) */
159 DisposeObject((Object
*)iihdata
->MasterDragGadget
);
160 DisposeObject((Object
*)iihdata
->MasterSizeGadget
);
162 DeletePool(iihdata
->ActionsMemPool
);
163 DeletePool(iihdata
->InputEventMemPool
);
165 } /* if (iihdata->InputEventMemPool = ... */
169 FreeMem(iihdata
, sizeof (struct IIHData
));
170 iihdata
->MouseBoundsActiveFlag
= FALSE
;
173 FreeMem(iihandler
, sizeof (struct Interrupt
));
175 } /* if (iihandler) */
177 ReturnPtr ("InitIIH", struct Interrupt
*, NULL
);
180 /****************************************************************************************/
182 VOID
CleanupIIH(struct Interrupt
*iihandler
, struct IntuitionBase
*IntuitionBase
)
184 struct IIHData
*iihdata
= (struct IIHData
*)iihandler
->is_Data
;
186 D(bug("[Intuition] %s()\n", __func__
));
188 DisposeObject((Object
*)iihdata
->MasterDragGadget
);
189 DisposeObject((Object
*)iihdata
->MasterSizeGadget
);
191 FreeGeneratedInputEvents(iihdata
);
192 DeletePool(iihdata
->InputEventMemPool
);
193 DeletePool(iihdata
->ActionsMemPool
);
195 /* One might think that this port is still in use by the inputhandler.
196 ** However, if intuition is closed for the last time, there should be no
197 ** windows that IntuiMessage can be sent to.
199 FreeMem(iihdata
->IntuiReplyPort
, sizeof (struct MsgPort
));
201 FreeMem(iihdata
, sizeof (struct IIHData
));
202 FreeMem(iihandler
, sizeof (struct Interrupt
));
207 /****************************************************************************************/
209 static void HandleIntuiReplyPort(struct IIHData
*iihdata
, struct IntuitionBase
*IntuitionBase
)
211 struct Library
*TimerBase
= GetPrivIBase(IntuitionBase
)->TimerBase
;
212 struct IntuiMessage
*im
;
214 D(bug("[Intuition] %s()\n", __func__
));
216 while ((im
= (struct IntuiMessage
*)GetMsg(iihdata
->IntuiReplyPort
)))
218 if (im
->IDCMPWindow
&& ResourceExisting(im
->IDCMPWindow
, RESOURCE_WINDOW
, IntuitionBase
))
220 struct IntWindow
*win
= (struct IntWindow
*)im
->IDCMPWindow
;
223 GetSysTime(&win
->lastmsgreplied
);
228 case IDCMP_MOUSEMOVE
:
229 IW(im
->IDCMPWindow
)->num_mouseevents
--;
232 case IDCMP_INTUITICKS
:
233 AROS_ATOMIC_AND(im
->IDCMPWindow
->Flags
, ~WFLG_WINDOWTICKED
);
236 #if USE_IDCMPUPDATE_MESSAGECACHE
237 case IDCMP_IDCMPUPDATE
:
238 IW(im
->IDCMPWindow
)->num_idcmpupdate
--;
240 if (!(IW(im
->IDCMPWindow
)->num_idcmpupdate
) && IW(im
->IDCMPWindow
)->messagecache
)
242 SendIntuiMessage(im
->IDCMPWindow
,IW(im
->IDCMPWindow
)->messagecache
);
243 IW(im
->IDCMPWindow
)->messagecache
= 0;
248 case IDCMP_MENUVERIFY
:
250 struct Window
*w
= im
->IDCMPWindow
;
251 struct IntScreen
*scr
= 0;
253 scr
= GetPrivScreen(w
->WScreen
);
255 if (scr
!= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
||
256 scr
->MenuVerifySeconds
> im
->Seconds
||
257 (scr
->MenuVerifySeconds
== im
->Seconds
&&
258 scr
->MenuVerifyMicros
> im
->Micros
))
260 /* The timeout has expired, just ignore. */
264 --scr
->MenuVerifyMsgCount
;
265 if (w
== scr
->MenuVerifyActiveWindow
&&
266 im
->Code
== MENUCANCEL
)
268 ULONG lock
= LockIBase(0);
271 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
273 if (w1
->IDCMPFlags
& IDCMP_MENUVERIFY
&& w1
!= scr
->MenuVerifyActiveWindow
)
275 ih_fire_intuimessage(w1
,
285 scr
->MenuVerifyActiveWindow
= NULL
;
286 scr
->MenuVerifyTimeOut
= 0;
287 scr
->MenuVerifyMsgCount
= 0;
288 scr
->MenuVerifySeconds
= 0;
289 scr
->MenuVerifyMicros
= 0;
290 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
292 else if (scr
->MenuVerifyMsgCount
== 0)
294 struct InputEvent ie
;
296 /* currently we ONLY need the menu open time ! */
297 ie
.ie_TimeStamp
.tv_secs
= im
->Seconds
;
298 ie
.ie_TimeStamp
.tv_micro
= im
->Micros
;
300 if (FireMenuMessage(MMCODE_START
, scr
->MenuVerifyActiveWindow
, &ie
, IntuitionBase
))
302 /* This lock will be released only when the user is
303 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
304 event arrives (generated by MenuHandler task) */
306 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
307 iihdata
->MenuWindow
= scr
->MenuVerifyActiveWindow
;
311 scr
->MenuVerifyActiveWindow
= NULL
;
312 scr
->MenuVerifyTimeOut
= 0;
313 scr
->MenuVerifyMsgCount
= 0;
314 scr
->MenuVerifySeconds
= 0;
315 scr
->MenuVerifyMicros
= 0;
316 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
322 case IDCMP_SIZEVERIFY
:
324 struct GadgetInfo
*gi
= &iihdata
->GadgetInfo
;
325 struct Window
*w
= im
->IDCMPWindow
;
326 struct Gadget
*gadget
= im
->IAddress
;
327 struct InputEvent ie
;
330 PrepareGadgetInfo(gi
, IntuitionBase
->ActiveScreen
, w
, NULL
);
331 SetGadgetInfoGadget(gi
, gadget
, IntuitionBase
);
333 if (IS_BOOPSI_GADGET(gadget
))
335 ie
.ie_NextEvent
= NULL
;
336 ie
.ie_Class
= IECLASS_RAWMOUSE
;
338 ie
.ie_Code
= IECODE_LBUTTON
;
339 ie
.ie_Qualifier
= im
->Qualifier
;
340 ie
.ie_X
= im
->MouseX
;
341 ie
.ie_Y
= im
->MouseY
;
342 ie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
343 ie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
352 /* For compatibility, send a GM_HANDLEINPUT too */
353 ie
.ie_Class
= IECLASS_RAWMOUSE
;
354 ie
.ie_Code
= IECODE_NOBUTTON
;
358 gadget
= DoGPInput(gi
,
366 /* From now on the master drag/size gadget takes over */
368 iihdata
->ActiveSysGadget
= gadget
;
369 gadget
= iihdata
->MasterSizeGadget
;
370 iihdata
->ActiveGadget
= gadget
;
372 ie
.ie_Class
= IECLASS_RAWMOUSE
;
373 ie
.ie_Code
= IECODE_LBUTTON
;
374 ie
.ie_X
= im
->MouseX
;
375 ie
.ie_Y
= im
->MouseY
;
386 case IDCMP_REQVERIFY
:
388 struct Window
*w
= im
->IDCMPWindow
;
390 EndRequest(w
->DMRequest
, w
);
392 ih_fire_intuimessage(w
,
400 case IDCMP_WBENCHMESSAGE
:
401 DEBUG_WORKBENCH(dprintf("HandleIntuiReplyPort: code 0x%lx\n",
405 } /* switch(im->Class) */
407 if (im
->Qualifier
& IEQUALIFIER_REPEAT
)
409 /* IDCMP_IDCMPUPDATE messages can also be sent from app task, therefore
410 it would be better if there was an ATOMIC_DEC macro or something */
412 if (IW(im
->IDCMPWindow
)->num_repeatevents
)
414 IW(im
->IDCMPWindow
)->num_repeatevents
--;
418 FreeIntuiMessage(im
);
420 } /* while ((im = (struct IntuiMessage *)GetMsg(iihdata->IntuiReplyPort))) */
422 /****************************************************************************************/
424 struct Window
*GetToolBoxWindow(struct InputEvent
*ie
, struct Screen
*scr
, struct IntuitionBase
*IntuitionBase
)
426 /* The caller has checked that the input event is a IECLASS_RAWMOUSE, SELECTDOWN event */
427 /* NOTE: may be called with NULL ie ptr! */
428 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
430 struct Window
*new_w
= NULL
;
432 D(bug("[Intuition] %s()\n", __func__
));
436 D(bug("GetToolBoxWindow: Click at (%d,%d)\n",scr
->MouseX
,scr
->MouseY
));
439 LockLayerInfo(&scr
->LayerInfo
);
441 l
= WhichLayer(&scr
->LayerInfo
, scr
->MouseX
, scr
->MouseY
);
443 UnlockLayerInfo(&scr
->LayerInfo
);
448 D(bug("GetToolBoxWindow: Click not inside layer\n"));
450 else if (l
== scr
->BarLayer
)
455 new_w
= (struct Window
*)l
->Window
;
458 if ((new_w
->Flags
& WFLG_TOOLBOX
) == 0) new_w
= NULL
;
462 D(bug("GetToolBoxWindow: Selected layer is not a ToolBox window\n"));
466 D(bug("GetToolBoxWindow: Found layer %p\n", l
));
471 D(bug("GetToolBoxWindow: New window %p\n", new_w
));
475 /****************************************************************************************/
477 #define KEY_QUALIFIERS (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT | \
478 IEQUALIFIER_CAPSLOCK | IEQUALIFIER_CONTROL | \
479 IEQUALIFIER_LALT | IEQUALIFIER_RALT | \
480 IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND | \
481 IEQUALIFIER_NUMERICPAD)
483 #define BUTTON_QUALIFIERS (IEQUALIFIER_MIDBUTTON | IEQUALIFIER_RBUTTON | IEQUALIFIER_LEFTBUTTON)
485 static struct Gadget
*Process_RawMouse(struct InputEvent
*ie
, struct IIHData
*iihdata
, struct Screen
*screen
,
486 struct Window
*w
, struct Gadget
*gadget
, struct GadgetInfo
*gi
,
487 ULONG stitlebarhit
, BOOL new_active_window
, BOOL IsToolbox
,
488 struct InputEvent
*orig_ie
, BOOL
*keep_event
, BOOL
*reuse_event
,
489 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
490 BOOL
*call_setpointerpos
,
492 struct IntuitionBase
*IntuitionBase
)
494 struct Library
*InputBase
= GetPrivIBase(IntuitionBase
)->InputBase
;
495 struct Requester
*req
= w
? w
->FirstRequest
: NULL
;
497 D(bug("[Intuition] %s()\n", __func__
));
499 switch (ie
->ie_Code
) {
502 BOOL new_gadget
= FALSE
;
503 BOOL sizeverify
= FALSE
;
504 UWORD MetaDrag
= GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_MetaDrag
;
506 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
));
507 DEBUG_CLICK(if (screen
) bug("[Inputhandler] Coordinates: (%d, %d)\n", screen
->MouseX
, screen
->MouseY
));
509 iihdata
->ActQualifier
|= IEQUALIFIER_LEFTBUTTON
;
511 /* Enter screen dragging mode if LButton + MetaDrag are pressed. */
512 if (MetaDrag
&& ((iihdata
->ActQualifier
& KEY_QUALIFIERS
) == MetaDrag
)) {
513 iihdata
->ScreenDrag
= screen
;
514 iihdata
->ScreenDragPointX
= screen
->MouseX
;
515 iihdata
->ScreenDragPointY
= screen
->MouseY
;
521 iihdata
->TitlebarAppearTime
= 0;
525 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
533 struct Gadget
* draggadget
= 0;
535 if ((!(w
->FirstRequest
)) && (w
->Flags
& WFLG_DRAGBAR
) && MatchHotkey(ie
,IA_ACTIVEWINDOWMOVE
,IntuitionBase
))
537 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)
539 for (draggadget
= w
->FirstGadget
; draggadget
; draggadget
= draggadget
->NextGadget
)
541 if ((draggadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
)
551 if ((!(w
->FirstRequest
)) && (w
->Flags
& WFLG_SIZEGADGET
) && MatchHotkey(ie
,IA_ACTIVEWINDOWSIZE
,IntuitionBase
))
553 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)
555 for (draggadget
= w
->FirstGadget
; draggadget
; draggadget
= draggadget
->NextGadget
)
557 if ((draggadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
)
571 /* use the *current* screen rather than active one when searching
572 for sdepth gadget! */
574 gadget
= FindGadget (screen
, stitlebarhit
? NULL
: w
, stitlebarhit
? NULL
: req
,
575 screen
->MouseX
, screen
->MouseY
, gi
, FALSE
, IntuitionBase
);
576 DEBUG_CLICK(bug("Click on gadget %p\n", gadget
));
581 /* If we clicked screen titlebar outside of any gadget, enter drag mode */
582 if ((!gadget
) && stitlebarhit
) {
583 DEBUG_CLICK(bug("[Inputhandler] Entering drag state for screen 0x%p\n", screen
));
584 iihdata
->ScreenDrag
= screen
;
585 iihdata
->ScreenDragPointX
= screen
->MouseX
;
586 iihdata
->ScreenDragPointY
= screen
->MouseY
;
592 if (!gadget
&& stitlebarhit
)
594 struct Window
*ww
= 0;
596 ww
= FindDesktopWindow(screen
, IntuitionBase
);
597 DEBUG_CLICK(bug("[Inputhandler] Clicked on backdrop window 0x%p\n", ww
));
604 if (!stitlebarhit
&& !new_active_window
&& DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
605 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
607 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= SELECTDOWN
)
609 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
610 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= SELECTDOWN
;
614 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
619 DEBUG_CLICK(bug("[Inputhandler] Resetting doubleclick counter\n"));
620 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= SELECTDOWN
;
621 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
624 /* update last click time for doubleclicktofront */
625 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
626 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
633 if (!(gadget
&& ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
)))
634 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
637 if (result
== RUNHOTREUSE
)
649 if (gadget
&& new_gadget
)
651 DEBUG_GADGET(bug("[Inputhandler] Activate gadget: 0x%p\n", gadget
));
652 if (w
&& (w
->IDCMPFlags
& IDCMP_SIZEVERIFY
) &&
653 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
/*||
654 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WZOOM*/)
656 ih_fire_intuimessage(w
,
666 BOOL is_draggad
, is_sizegad
;
669 /* Whenever the active gadget changes the gi must be updated
670 because it is cached in iidata->GadgetInfo!!!! Don't
671 forget to do this if somewhere else the active
672 gadget is changed, for example in ActivateGadget!!! */
674 PrepareGadgetInfo(gi
, screen
, w
, req
);
675 SetGadgetInfoGadget(gi
, gadget
, IntuitionBase
);
677 gsystype
= gadget
->GadgetType
& GTYP_SYSTYPEMASK
;
678 is_draggad
= ((gsystype
== GTYP_WDRAGGING
)
680 || (gsystype
== GTYP_WDRAGGING2
)
683 is_sizegad
= (gsystype
== GTYP_SIZING
);
685 /* jDc: intui68k sends IDCMPs for GACT_IMMEDIATE drag&sizegads! */
686 if (gadget
->Activation
& GACT_IMMEDIATE
)
688 ih_fire_intuimessage(w
,
695 if (is_draggad
|| is_sizegad
)
697 if (IS_BOOPSI_GADGET(gadget
))
706 /* Ignoring retval of dispatcher above is what
707 AmigaOS does too for boopsi drag/resize
712 /* From now on the master drag/size gadget takes over */
713 if ((w
->MoreFlags
& WMFLG_IAMMUI
) && (w
->Flags
& WFLG_BORDERLESS
))
714 iihdata
->ActiveSysGadget
= is_draggad
? gadget
: 0;
716 iihdata
->ActiveSysGadget
= gadget
;
717 gadget
= is_draggad
? iihdata
->MasterDragGadget
: iihdata
->MasterSizeGadget
;
725 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
727 case GTYP_BOOLGADGET
:
728 /* Only set the GFLG_SELECTED flag for RELVERIFY and
729 * TOGGLESELECT gadget. It's for the user to do it if
730 * he wants for other GADGIMMEDIATE ones.
731 * Only RELVERIFY gadgets stay active.
734 if (gadget
->Activation
& (GACT_TOGGLESELECT
| GACT_RELVERIFY
))
736 gadget
->Flags
^= GFLG_SELECTED
;
737 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
740 if (gadget
->Activation
& GACT_RELVERIFY
)
742 gadget
->Activation
|= GACT_ACTIVEGADGET
;
743 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
751 case GTYP_PROPGADGET
:
752 HandlePropSelectDown(gadget
,
755 w
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
756 w
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
763 /* If the click was inside the active strgad,
764 ** then let it update cursor pos,
765 ** else deactivate stringadget and reuse event.
768 if (InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
769 gi
->gi_Requester
, gadget
,
770 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
))
774 HandleStrInput(gadget
, gi
, ie
, &imsgcode
,
779 gadget
->Flags
&= ~GFLG_SELECTED
;
781 RefreshStrGadget(gadget
, w
, req
, IntuitionBase
);
782 /* Gadget not active anymore */
788 case GTYP_CUSTOMGADGET
:
789 gadget
= DoGPInput(gi
,
792 (new_gadget
? GM_GOACTIVE
: GM_HANDLEINPUT
),
795 D(bug("new_gadget %d, goactive %p\n", new_gadget
, gadget
));
797 if (gadget
&& new_gadget
&& (!(gadget
->GadgetType
& GTYP_SIZING
)))
799 /* For compatibility, send a GM_HANDLEINPUT too */
800 struct InputEvent newie
;
803 newie
.ie_NextEvent
= NULL
;
804 newie
.ie_Class
= IECLASS_RAWMOUSE
;
805 newie
.ie_SubClass
= 0;
806 newie
.ie_Code
= IECODE_NOBUTTON
;
807 newie
.ie_Qualifier
= ie
->ie_Qualifier
;
810 newie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
811 newie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
813 gadget
= DoGPInput(gi
,
819 D(bug("handleinput %p\n", gadget
));
823 case 0: //orig gadtools / some 1.3 gadgets
824 if (IS_SYS_GADGET(gadget
))
826 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
830 if (gadget
->Activation
& GACT_RELVERIFY
)
832 gadget
->Activation
|= GACT_ACTIVEGADGET
;
833 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
834 if (gadget
->Flags
& GFLG_GADGHIMAGE
)
836 gadget
->Flags
^= GFLG_SELECTED
;
837 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
842 /* jDc: this is what original intuition does, before crashing after a while ;)*/
843 DEBUG_CLICK(bug("[Inputhandler] Sending SELECTDOWN (old gadget), window 0x%p\n", w
));
844 ih_fire_intuimessage(w
,
852 } /* switch (GadgetType) */
854 } /* if (a gadget is active) */
855 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && !sizeverify
&& !stitlebarhit
)
857 DEBUG_CLICK(bug("[Inputhandler] Sending SELECTDOWN, window 0x%p\n", w
));
858 ih_fire_intuimessage(w
,
865 } /* case SELECTDOWN */
869 iihdata
->ActQualifier
&= ~IEQUALIFIER_LEFTBUTTON
;
871 /* Ignore this event if screen drag qualifier is pressed */
872 if (iihdata
->ScreenDrag
) {
873 iihdata
->ScreenDrag
= NULL
;
879 iihdata
->TitlebarAppearTime
= 0;
883 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
890 BOOL inside
= InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
891 gi
->gi_Requester
, gadget
,
892 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
);
894 /*int selected = (gadget->Flags & GFLG_SELECTED) != 0;*/
896 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
898 case GTYP_BOOLGADGET
:
899 /* Must be a RELVERIFY gadget */
901 if (!(gadget
->Activation
& GACT_TOGGLESELECT
) && inside
)
903 gadget
->Flags
^= GFLG_SELECTED
;
904 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
909 if (IS_SYS_GADGET(gadget
))
911 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
915 if (req
&& gadget
->Activation
& GACT_ENDGADGET
)
919 req
= w
->FirstRequest
;
922 ih_fire_intuimessage(w
,
932 ih_fire_intuimessage(w
,
939 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
943 case GTYP_PROPGADGET
:
944 HandlePropSelectUp(gadget
, w
, req
, IntuitionBase
);
945 if (gadget
->Activation
& GACT_RELVERIFY
)
947 ih_fire_intuimessage(w
,
957 /* Intuition string gadgets don't care about SELECTUP */
959 case GTYP_CUSTOMGADGET
:
960 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
963 case 0: //orig gadtools / some 1.3 gadgets
964 /* jDc: adding a gadget with gtyp field set to NULL crashes intui68k
965 ** seems we don't need compatibility on this field ;) anyway we should
966 ** handle the case of GTYP_CLOSE, etc, set by some "cod3r"
968 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
969 if (gadget
->Activation
& GACT_RELVERIFY
)
971 if (gadget
->Flags
& GFLG_GADGHIMAGE
)
975 gadget
->Flags
^= GFLG_SELECTED
;
976 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
982 ih_fire_intuimessage(w
,
989 ih_fire_intuimessage(w
,
998 } /* switch GadgetType */
1000 } /* if (a gadget is currently active) */
1001 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
))
1003 ih_fire_intuimessage(w
,
1010 break; /* case SELECTUP */
1013 iihdata
->ActQualifier
|= IEQUALIFIER_RBUTTON
;
1016 iihdata
->TitlebarAppearTime
= 0;
1020 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1021 *keep_event
= FALSE
;
1025 if (DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
1026 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
1028 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= MENUDOWN
)
1030 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1031 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MENUDOWN
;
1035 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
1040 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MENUDOWN
;
1041 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1044 /* update last click time for doubleclicktofront */
1045 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
1046 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
1052 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
1054 if (result
== RUNHOTREUSE
)
1056 *reuse_event
= TRUE
;
1060 *keep_event
= FALSE
;
1064 w
= IntuitionBase
->ActiveWindow
;
1069 if ((!MENUS_ACTIVE
) && (!gadget
) && (!(iihdata
->ActQualifier
& (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_MIDBUTTON
))))
1072 struct GadgetInfo ginf
;
1074 struct Window
*wind
= FindActiveWindow(0, screen
, &hit
,IntuitionBase
);
1078 gad
= FindGadget (screen
,
1080 IntuitionBase
->ActiveScreen
->MouseX
,
1081 IntuitionBase
->ActiveScreen
->MouseY
,
1082 &ginf
, TRUE
, IntuitionBase
);
1084 if (gad
&& ((gad
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
))
1086 CreateSmallMenuTask(wind
,SMALLMENU_TYPE_WINDOWDEPTH
,IntuitionBase
);
1087 *keep_event
= FALSE
;
1091 if (gad
&& ((gad
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SDEPTH
))
1093 CreateSmallMenuTask(0,SMALLMENU_TYPE_SCREENDEPTH
,IntuitionBase
);
1094 *keep_event
= FALSE
;
1101 if (w
&& !req
&& w
->DMRequest
&& !(w
->Flags
& WFLG_RMBTRAP
))
1103 if (!MENUS_ACTIVE
&&
1104 DoubleClick(GetPrivIBase(IntuitionBase
)->DMStartSecs
,
1105 GetPrivIBase(IntuitionBase
)->DMStartMicro
,
1106 ie
->ie_TimeStamp
.tv_secs
,
1107 ie
->ie_TimeStamp
.tv_micro
))
1109 if (w
->IDCMPFlags
& IDCMP_REQVERIFY
)
1111 ih_fire_intuimessage(w
,
1117 else if (Request(w
->DMRequest
, w
))
1121 ih_fire_intuimessage(w
,
1127 *keep_event
= FALSE
;
1131 GetPrivIBase(IntuitionBase
)->DMStartSecs
= ie
->ie_TimeStamp
.tv_secs
;
1132 GetPrivIBase(IntuitionBase
)->DMStartMicro
= ie
->ie_TimeStamp
.tv_micro
;
1137 if (!(w
->Flags
& WFLG_RMBTRAP
) && !req
)
1139 struct IntScreen
*scr
= GetPrivScreen(w
->WScreen
);
1142 BOOL mouseon
= TRUE
;
1144 scr
->MenuVerifyMsgCount
= 0;
1146 if (w
->MouseX
< 0 || w
->MouseY
< 0) mouseon
= FALSE
;
1147 if (w
->MouseX
> w
->Width
|| w
->MouseY
> w
->Height
) mouseon
= FALSE
;
1149 if (w
->IDCMPFlags
& IDCMP_MENUVERIFY
&& (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
1151 ih_fire_intuimessage(w
,
1153 mouseon
? MENUHOT
: MENUWAITING
,
1156 scr
->MenuVerifyMsgCount
++;
1159 lock
= LockIBase(0);
1161 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
1163 if ((w1
->IDCMPFlags
& IDCMP_MENUVERIFY
) && (w1
!= w
) && (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
1165 ih_fire_intuimessage(w1
,
1170 ++scr
->MenuVerifyMsgCount
;
1176 /* FIXME: when a window is opened with IDCMP_MENUVERIFY
1177 * (or this event is requested via ModifyIDCMP), and a
1178 * verify operation is pending, the window should get
1179 * a verify message too. Oh well.
1182 if (scr
->MenuVerifyMsgCount
)
1184 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= scr
;
1185 scr
->MenuVerifyActiveWindow
= w
;
1186 scr
->MenuVerifyTimeOut
= 2;
1187 scr
->MenuVerifySeconds
= IntuitionBase
->Seconds
;
1188 scr
->MenuVerifyMicros
= IntuitionBase
->Micros
;
1190 else if (FireMenuMessage(MMCODE_START
, w
, NULL
/*ie*/, IntuitionBase
))
1192 /* This lock will be released only when the user is
1193 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
1194 event arrives (generated by MenuHandler task) */
1196 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
1197 iihdata
->MenuWindow
= w
;
1198 MENUS_ACTIVE
= TRUE
;
1208 switch(ie
->ie_Code
) {
1210 iihdata
->ActQualifier
&= ~IEQUALIFIER_RBUTTON
;
1211 if (GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
)
1214 struct IntScreen
*scr
= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
;
1215 ULONG lock
= LockIBase(0);
1217 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
1219 if (w1
->IDCMPFlags
& IDCMP_MENUVERIFY
&& w1
->IDCMPFlags
& IDCMP_MOUSEBUTTONS
)
1221 ih_fire_intuimessage(w1
,
1231 /* FIXME: when the active window replies the verifymessage,
1232 * it should get a IDCMP_MENUPICK/MENUNULL message.
1234 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
1235 scr
->MenuVerifyActiveWindow
= NULL
;
1236 scr
->MenuVerifyMsgCount
= 0;
1237 scr
->MenuVerifyTimeOut
= 0;
1238 scr
->MenuVerifySeconds
= 0;
1239 scr
->MenuVerifyMicros
= 0;
1244 iihdata
->ActQualifier
|= IEQUALIFIER_MIDBUTTON
;
1245 if (DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
1246 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
1248 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= MIDDLEDOWN
)
1250 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1251 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
1253 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
1255 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
1256 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1258 /* update last click time for doubleclicktofront */
1259 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
1260 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
1264 iihdata
->ActQualifier
&= ~IEQUALIFIER_MIDBUTTON
;
1269 iihdata
->TitlebarAppearTime
= 0;
1273 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1274 *keep_event
= FALSE
;
1279 if (ie
->ie_Code
== MIDDLEDOWN
)
1283 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
1285 if (result
== RUNHOTREUSE
)
1287 *reuse_event
= TRUE
;
1291 *keep_event
= FALSE
;
1295 w
= IntuitionBase
->ActiveWindow
;
1300 if (IS_BOOPSI_GADGET(gadget
))
1302 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
1305 } /* if (there is an active gadget) */
1306 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && w
!= GetPrivScreen(w
->WScreen
)->MenuVerifyActiveWindow
)
1308 ih_fire_intuimessage(w
,
1315 break; /* case MENUDOWN */
1317 case IECODE_NOBUTTON
: /* MOUSEMOVE */
1320 UWORD DWidth
, DHeight
;
1322 if (ie
->ie_Qualifier
& IEQUALIFIER_RELATIVEMOUSE
) {
1325 /* Add delta information lost in previous mousemove event. See below. */
1326 iihdata
->DeltaMouseX
= ie
->ie_X
+ iihdata
->DeltaMouseX_Correction
;
1327 iihdata
->DeltaMouseY
= ie
->ie_Y
+ iihdata
->DeltaMouseY_Correction
;
1329 #define ACCELERATOR_THRESH 2
1330 #define ACCELERATOR_MULTI 2
1332 if (GetPrivIBase(IntuitionBase
)->ActivePreferences
.EnableCLI
& MOUSE_ACCEL
)
1335 if (ABS(iihdata
->DeltaMouseX
) > ACCELERATOR_THRESH
)
1336 iihdata
->DeltaMouseX
*= ACCELERATOR_MULTI
;
1337 if (ABS(iihdata
->DeltaMouseY
) > ACCELERATOR_THRESH
)
1338 iihdata
->DeltaMouseY
*= ACCELERATOR_MULTI
;
1341 switch (GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
)
1344 iihdata
->DeltaMouseX_Correction
= 0;
1345 iihdata
->DeltaMouseX_Correction
= 0;
1349 /* Remember the delta information which gets lost because of division by PointerTicks.
1350 Will be added to prescaled deltas of next mousemove event. If this is not done, moving
1351 the mouse very slowly would cause it to not move at all */
1353 iihdata
->DeltaMouseX_Correction
= iihdata
->DeltaMouseX
% GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1354 iihdata
->DeltaMouseY_Correction
= iihdata
->DeltaMouseY
% GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1356 iihdata
->DeltaMouseX
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1357 iihdata
->DeltaMouseY
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1362 ie
->ie_X
= iihdata
->DeltaMouseX
+ IntuitionBase
->MouseX
;
1363 ie
->ie_Y
= iihdata
->DeltaMouseY
+ IntuitionBase
->MouseY
;
1365 DEBUG_MOUSE(bug("[Inputhandler] Last mouse position: (%d, %d), new mouse position: (%d, %d)\n",
1366 IntuitionBase
->MouseX
, IntuitionBase
->MouseY
, ie
->ie_X
, ie
->ie_Y
));
1367 iihdata
->DeltaMouseX
= ie
->ie_X
- IntuitionBase
->MouseX
;
1368 iihdata
->DeltaMouseY
= ie
->ie_Y
- IntuitionBase
->MouseY
;
1369 DEBUG_MOUSE(bug("[InputHandler] Delta is (%d, %d)\n", iihdata
->DeltaMouseX
, iihdata
->DeltaMouseY
));
1372 /* Calculate current display size.
1373 It's determined by the first screen on this monitor.
1374 TODO: perhaps we should just ask display driver about its current display mode? */
1375 scr
= FindFirstScreen(GetPrivIBase(IntuitionBase
)->ActiveMonitor
, IntuitionBase
);
1378 DWidth
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxX
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinX
+ 1;
1379 DHeight
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxY
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinY
+ 1;
1383 /* If there's no active screen, we take 160x160 as a limit */
1388 scr
= iihdata
->ScreenDrag
;
1390 WORD dx
= iihdata
->DeltaMouseX
;
1391 WORD dy
= iihdata
->DeltaMouseY
;
1393 UWORD spFlags
= GetPrivScreen(scr
)->SpecialFlags
;
1394 UWORD DragMode
= GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_VDragModes
[0];
1396 DEBUG_DRAG(bug("[InputHandler] Screen drag, delta is (%d, %d)\n", dx
, dy
));
1398 /* Restrict dragging to a physical display area if the driver does not allow composition or if the user wants it*/
1399 if (((spFlags
& SF_HorCompose
) != SF_HorCompose
) || (DragMode
& ICVDM_HBOUND
)) {
1400 /* Calculate limits */
1401 if (scr
->Width
> DWidth
) {
1402 min
= DWidth
- scr
->Width
;
1406 max
= DWidth
- scr
->Width
;
1408 /* The purpose of the following complex check is to prevent jumping if the
1409 screen was positioned out of user drag limits by the program itself using
1410 ScreenPosition() or OpenScreen(). We apply restrictions in parts depending
1411 on the dragging direction.
1412 Maybe the user should also be able to drag the screen back off-display in such
1414 Calculate the position we would go to */
1415 val
= scr
->LeftEdge
+ dx
;
1416 /* Determine the direction */
1417 if ((dx
< 0) && ((!(spFlags
& SF_ComposeRight
)) || (DragMode
& ICVDM_LBOUND
))) {
1418 /* Can we move at all in this direction ? */
1419 if (scr
->LeftEdge
> min
) {
1420 /* If too far, restrict it */
1422 dx
= min
- scr
->LeftEdge
;
1424 /* Just don't move if we can't */
1426 } else if ((!(spFlags
& SF_ComposeLeft
)) || (DragMode
& ICVDM_RBOUND
)) {
1427 if (scr
->LeftEdge
< max
) {
1429 dx
= max
- scr
->LeftEdge
;
1434 if (((spFlags
& SF_VertCompose
) != SF_VertCompose
) || (DragMode
& ICVDM_VBOUND
)) {
1435 DEBUG_DRAG(bug("[Inputhandler] Restricting vertical drag\n"));
1436 DEBUG_DRAG(bug("[Inputhandler] Screen size: %d, display size: %d\n", scr
->Height
, DHeight
));
1437 if (scr
->Height
> DHeight
) {
1438 min
= DHeight
- scr
->Height
;
1442 max
= DHeight
- scr
->Height
;
1444 DEBUG_DRAG(bug("[Inputhandler] Limits: min %d max %d\n", min
, max
));
1445 val
= scr
->TopEdge
+ dy
;
1446 DEBUG_DRAG(bug("[Inputhandler] New position would be %d\n", val
));
1447 if ((dy
< 0) && ((!(spFlags
& SF_ComposeBelow
)) || (DragMode
& ICVDM_TBOUND
))) {
1448 if (scr
->TopEdge
> min
) {
1450 dy
= min
- scr
->TopEdge
;
1453 } else if ((!(spFlags
& SF_ComposeAbove
)) || (DragMode
& ICVDM_BBOUND
)) {
1454 if (scr
->TopEdge
< max
) {
1456 dy
= max
- scr
->TopEdge
;
1460 DEBUG_DRAG(bug("[Inputhandler] Restricted delta will be %d\n", dy
));
1462 ScreenPosition(scr
, SPOS_RELATIVE
, dx
, dy
, 0, 0);
1465 /* Autoscroll the active screen */
1466 scr
= IntuitionBase
->ActiveScreen
;
1467 if (scr
&& (scr
->Flags
& AUTOSCROLL
) &&
1468 (GetPrivScreen(scr
)->IMonitorNode
== GetPrivIBase(IntuitionBase
)->ActiveMonitor
))
1470 WORD xval
= scr
->LeftEdge
;
1471 WORD yval
= scr
->TopEdge
;
1474 DEBUG_AUTOSCROLL(bug("[Inputhandler] Autoscroll screen 0x%p, event at (%d, %d)\n",
1475 scr
, ie
->ie_X
, ie
->ie_Y
));
1477 if ((ie
->ie_X
< 0) || (ie
->ie_X
>= DWidth
)) {
1478 DEBUG_AUTOSCROLL(bug("[InputHandler] X delta: %d pixels\n", iihdata
->DeltaMouseX
));
1479 xval
-= iihdata
->DeltaMouseX
;
1484 } else if (ie
->ie_X
>= DWidth
) {
1485 min
= DWidth
- scr
->Width
;
1491 if ((ie
->ie_Y
< 0) || (ie
->ie_Y
>= DHeight
)) {
1492 yval
-= iihdata
->DeltaMouseY
;
1495 /* If screen is dragged down and user touched upper screen
1496 boundary, do nothing */
1497 if (scr
->TopEdge
>= 0)
1498 yval
= scr
->TopEdge
;
1500 /* If scrolled down screen is being scrolled up, make sure it
1501 does not go over 0 */
1504 } else if (ie
->ie_Y
>= DHeight
) {
1505 min
= DHeight
- scr
->Height
;
1511 if ((xval
!= scr
->LeftEdge
) || (yval
!= scr
->TopEdge
))
1512 ScreenPosition(scr
, SPOS_ABSOLUTE
, xval
, yval
, 0, 0);
1515 /* Restrict mouse coordinates to the physical display area */
1516 if (ie
->ie_X
>= DWidth
) ie
->ie_X
= DWidth
- 1;
1517 if (ie
->ie_Y
>= DHeight
) ie
->ie_Y
= DHeight
- 1;
1518 if (ie
->ie_X
< 0) ie
->ie_X
= 0;
1519 if (ie
->ie_Y
< 0) ie
->ie_Y
= 0;
1522 if (gadget
== iihdata
->MasterDragGadget
) {
1526 gpi
.MethodID
= GM_MOVETEST
;
1528 gpi
.gpi_Mouse
.X
= ie
->ie_X
- gi
->gi_Window
->WScreen
->LeftEdge
;
1529 gpi
.gpi_Mouse
.Y
= ie
->ie_Y
- gi
->gi_Window
->WScreen
->TopEdge
;
1530 gpi
.gpi_IEvent
= ie
;
1532 retval
= Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpi
, IntuitionBase
);
1533 if (retval
== MOVETEST_ADJUSTPOS
)
1535 ie
->ie_X
= gpi
.gpi_Mouse
.X
+ gi
->gi_Window
->WScreen
->LeftEdge
;
1536 ie
->ie_Y
= gpi
.gpi_Mouse
.Y
+ gi
->gi_Window
->WScreen
->TopEdge
;
1541 /* Do Mouse Bounding - mouse will be most restrictive of screen size or mouse bounds */
1542 if (iihdata
->MouseBoundsActiveFlag
) {
1543 if (ie
->ie_X
< iihdata
->MouseBoundsLeft
)
1544 ie
->ie_X
= iihdata
->MouseBoundsLeft
;
1545 else if (ie
->ie_X
> iihdata
->MouseBoundsRight
)
1546 ie
->ie_X
= iihdata
->MouseBoundsRight
;
1548 if (ie
->ie_Y
< iihdata
->MouseBoundsTop
)
1549 ie
->ie_Y
= iihdata
->MouseBoundsTop
;
1550 else if (ie
->ie_Y
> iihdata
->MouseBoundsBottom
)
1551 ie
->ie_Y
= iihdata
->MouseBoundsBottom
;
1554 /* Prevent mouse going above all screens */
1555 scr
= FindHighestScreen(IntuitionBase
);
1557 if (ie
->ie_Y
< scr
->TopEdge
)
1558 ie
->ie_Y
= scr
->TopEdge
;
1561 /* Store new mouse coords. If a screen is being dragged, lock drag point */
1562 scr
= iihdata
->ScreenDrag
;
1564 IntuitionBase
->MouseX
= scr
->LeftEdge
+ iihdata
->ScreenDragPointX
;
1565 IntuitionBase
->MouseY
= scr
->TopEdge
+ iihdata
->ScreenDragPointY
;
1567 IntuitionBase
->MouseX
= ie
->ie_X
;
1568 IntuitionBase
->MouseY
= ie
->ie_Y
;
1570 notify_mousemove_screensandwindows(IntuitionBase
);
1571 #if !SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1572 MySetPointerPos(IntuitionBase
);
1574 *call_setpointerpos
= TRUE
;
1577 screen
= FindActiveScreen(IntuitionBase
); /* The mouse was moved, so current screen may have changed */
1581 if (iihdata
->TitlebarOnTop
)
1583 if (screen
->MouseY
> screen
->BarHeight
&& GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
)
1585 iihdata
->TitlebarOnTop
= FALSE
;
1586 iihdata
->TitlebarAppearTime
= 0;
1588 LOCK_REFRESH(screen
);
1590 MoveLayer(0, screen
->BarLayer
, 0, -(screen
->BarHeight
+ 1));
1591 CheckLayers(screen
, IntuitionBase
);
1593 UNLOCK_REFRESH(screen
);
1598 if (screen
->MouseY
== 0 && GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
&& !MENUS_ACTIVE
&& !(PeekQualifier() & (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_RBUTTON
|IEQUALIFIER_MIDBUTTON
)))
1600 if (!(iihdata
->TitlebarAppearTime
))
1602 iihdata
->TitlebarAppearTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1603 iihdata
->TitlebarAppearTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1608 iihdata
->TitlebarAppearTime
= 0;
1614 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1615 *keep_event
= FALSE
;
1620 *keep_event
= FALSE
;
1622 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
1624 case GTYP_BOOLGADGET
:
1625 case 0: //fallback for sucky gadgets
1626 /* Must be a RELVERIFY gadget */
1630 inside
= InsideGadget(gi
->gi_Screen
,
1634 gi
->gi_Screen
->MouseX
,
1635 gi
->gi_Screen
->MouseY
);
1637 if (inside
!= iihdata
->MouseWasInsideBoolGadget
) {
1638 iihdata
->MouseWasInsideBoolGadget
= inside
;
1640 gadget
->Flags
^= GFLG_SELECTED
;
1641 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
1646 case GTYP_PROPGADGET
:
1647 HandlePropMouseMove(gadget
,
1650 w
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
1651 w
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
1656 case GTYP_CUSTOMGADGET
:
1657 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
1660 } /* switch GadgetType */
1662 } /* if (a gadget is currently active) */
1664 *keep_event
= FALSE
;
1669 if (IW(w
)->helpflags
& HELPF_GADGETHELP
&& (!(PeekQualifier() & (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_RBUTTON
|IEQUALIFIER_MIDBUTTON
)))) {
1673 hw
= FindActiveWindow(ie
, screen
, 0, IntuitionBase
);
1676 (!hw
|| !(IW(w
)->helpflags
& HELPF_ISHELPGROUP
) ||
1677 !(IW(hw
)->helpflags
& HELPF_ISHELPGROUP
) ||
1678 IW(w
)->helpgroup
!= IW(hw
)->helpgroup
))
1681 if (iihdata
->LastHelpWindow
)
1683 fire_intuimessage(w
,
1689 iihdata
->LastHelpGadget
= NULL
;
1690 iihdata
->LastHelpWindow
= NULL
;
1691 iihdata
->HelpGadgetFindTime
= 0;
1696 g
= FindHelpGadget (hw
,
1697 IntuitionBase
->ActiveScreen
->MouseX
,
1698 IntuitionBase
->ActiveScreen
->MouseY
,
1700 if (g
&& g
!= iihdata
->LastHelpGadget
)
1702 if (!iihdata
->LastHelpGadget
)
1704 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1705 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1707 if (hw
== iihdata
->LastHelpWindow
)
1709 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1710 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1711 iihdata
->HelpGadgetFindTime
+= 25;//smaller delay
1715 else if (g
!= iihdata
->LastHelpGadget
||
1716 hw
!= iihdata
->LastHelpWindow
)
1718 fire_intuimessage(hw
,
1720 0, /* Don't know what it should be */
1725 iihdata
->LastHelpGadget
= g
;
1726 iihdata
->LastHelpWindow
= hw
;
1729 iihdata
->LastHelpGadget
= NULL
;
1730 iihdata
->LastHelpWindow
= NULL
;
1731 iihdata
->HelpGadgetFindTime
= 0;
1734 if (!(w
->IDCMPFlags
& IDCMP_MOUSEMOVE
))
1737 /* Send IDCMP_MOUSEMOVE if WFLG_REPORTMOUSE is set
1738 and/or active gadget has GACT_FOLLOWMOUSE set */
1740 /* jDc: do NOT send when sizegad is pressed */
1741 if (!(w
->Flags
& WFLG_REPORTMOUSE
)) {
1744 if (!(gadget
->Activation
& GACT_FOLLOWMOUSE
))
1747 if (gadget
&& (gadget
->GadgetType
& (GTYP_SIZING
|GTYP_WDRAGGING
)))
1751 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
1753 /* Limit the number of IDCMP_MOUSEMOVE messages sent to intuition.
1754 note that this comes after handling gadgets, because gadgets should get all events.
1757 if (IW(w
)->num_mouseevents
>= IW(w
)->mousequeue
) {
1758 BOOL old_msg_found
= FALSE
;
1760 /* Mouse Queue is full, so try looking for a not
1761 yet GetMsg()ed IntuiMessage in w->UserPort
1762 trying to modify that. */
1767 struct IntuiMessage
*im
;
1768 #if defined(__AROSEXEC_SMP__)
1769 struct ExecLockBase
*ExecLockBase
= GetPrivIBase(IntuitionBase
)->ExecLockBase
;
1770 if (ExecLockBase
) ObtainLock(&w
->UserPort
->mp_SpinLock
, SPINLOCK_MODE_READ
, 0);
1772 for (im
= (struct IntuiMessage
*)w
->UserPort
->mp_MsgList
.lh_TailPred
;
1773 im
->ExecMessage
.mn_Node
.ln_Pred
;
1774 im
= (struct IntuiMessage
*)im
->ExecMessage
.mn_Node
.ln_Pred
)
1776 if ((im
->Class
== IDCMP_MOUSEMOVE
) &&
1777 (im
->IDCMPWindow
== w
))
1779 im
->Qualifier
= iihdata
->ActQualifier
;
1781 if (w
->IDCMPFlags
& IDCMP_DELTAMOVE
)
1783 im
->MouseX
= iihdata
->DeltaMouseX
;
1784 im
->MouseY
= iihdata
->DeltaMouseY
;
1788 im
->MouseX
= w
->MouseX
;
1789 im
->MouseY
= w
->MouseY
;
1791 CurrentTime(&im
->Seconds
, &im
->Micros
);
1793 old_msg_found
= TRUE
;
1797 #if defined(__AROSEXEC_SMP__)
1798 if (ExecLockBase
) ReleaseLock(&w
->UserPort
->mp_SpinLock
, 0);
1800 } /* if (w->UserPort) */
1803 /* no need to send a new message if we modified
1804 an existing one ... */
1806 if (old_msg_found
) break;
1808 /* ... otherwise we are in a strange situation. The mouse
1809 queue is full, but we did not find an existing MOUSEMOVE
1810 imsg in w->UserPort. So the app probably has removed
1811 an imsg from the UserPort with GetMsg but we did not get
1812 the ReplyMsg, yet. In this case we do send a new message */
1814 HandleIntuiReplyPort(iihdata
, IntuitionBase
);
1818 /* MouseQueue is not full, so we can send a message. We increase
1819 IntWindow->num_mouseevents which will later be decreased after
1820 the Intuition InputHandler gets the ReplyMessage from the app
1821 and handles it in HandleIntuiReplyPort() */
1823 if (ih_fire_intuimessage(w
, IDCMP_MOUSEMOVE
, IECODE_NOBUTTON
, w
, IntuitionBase
))
1824 IW(w
)->num_mouseevents
++;
1828 } /* case IECODE_NOBUTTON */
1829 } /* switch (ie->ie_Code) (what button was pressed ?) */
1834 /****************************************************************************************/
1836 AROS_UFH2(struct InputEvent
*, IntuiInputHandler
,
1837 AROS_UFHA(struct InputEvent
*, oldchain
, A0
),
1838 AROS_UFHA(struct IIHData
*, iihdata
, A1
)
1843 struct InputEvent
*ie
, *orig_ie
, *next_ie
, stackie
;
1844 struct Gadget
*gadget
= NULL
;
1845 struct IntuitionBase
*IntuitionBase
= iihdata
->IntuitionBase
;
1846 struct Library
*KeymapBase
= GetPrivIBase(IntuitionBase
)->KeymapBase
;
1847 struct Screen
*screen
;
1849 struct GadgetInfo
*gi
= &iihdata
->GadgetInfo
;
1850 BOOL reuse_event
, ie_used
;
1852 struct Requester
*req
;
1853 ULONG stitlebarhit
= 0;
1854 #if 0 /* Toolbox is broken-as-designed */
1855 struct Window
*toolbox
;
1856 struct GadgetInfo
*boxgi
= &iihdata
->BoxGadgetInfo
;
1857 struct Gadget
*boxgadget
= NULL
;
1859 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1860 BOOL call_setpointerpos
= FALSE
;
1863 D(bug("Inside intuition inputhandler, active window=%p\n", IntuitionBase
->ActiveWindow
));
1864 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->InputHandlerLock
);
1866 if (!iihdata
->InputDeviceTask
) iihdata
->InputDeviceTask
= FindTask(NULL
);
1868 /* Then free generated InputEvents done in the previous round */
1870 FreeGeneratedInputEvents(iihdata
);
1872 /* First handle IntuiMessages which were replied back to the IntuiReplyPort
1875 HandleIntuiReplyPort(iihdata
, IntuitionBase
);
1877 /* Handle action messages */
1879 HandleIntuiActions(iihdata
, IntuitionBase
);
1881 /* Now handle the input events */
1884 reuse_event
= FALSE
;
1887 /* shut up the compiler */
1891 gadget
= iihdata
->ActiveGadget
;
1893 while (reuse_event
|| next_ie
)
1895 struct Window
*old_w
;
1896 BOOL keep_event
= TRUE
;
1897 BOOL new_active_window
= FALSE
;
1898 Object
*newmonitor
= GetPrivIBase(IntuitionBase
)->NewMonitor
;
1900 /* Process hosted display activation event (if any).
1901 This is experimental. If this works badly, we'll possibly have to put it into
1902 input events queue */
1904 DEBUG_MONITOR(bug("[Inputhandler] Activating monitor 0x%p\n", newmonitor
));
1905 GetPrivIBase(IntuitionBase
)->NewMonitor
= NULL
;
1906 ActivateMonitor(newmonitor
, -1, -1, IntuitionBase
);
1907 iihdata
->SwitchedMonitor
= TRUE
;
1914 next_ie
= ie
->ie_NextEvent
;
1918 D(bug("iih: Handling event of class %d, code %d\n", ie
->ie_Class
, ie
->ie_Code
));
1919 reuse_event
= FALSE
;
1921 /* If the monitor has been changed, this possibly happened because of mouse click in
1922 its display window. In such a case we have to update current mouse coordinates
1923 from the first absolute mouse event. Otherwise input will misbehave. */
1924 if (iihdata
->SwitchedMonitor
&& (ie
->ie_Class
== IECLASS_RAWMOUSE
)) {
1925 iihdata
->SwitchedMonitor
= FALSE
;
1926 if (!(ie
->ie_Qualifier
& IEQUALIFIER_RELATIVEMOUSE
)) {
1927 DEBUG_MONITOR(bug("[Inputhandler] Adjusting coordinates to (%d, %d)\n", ie
->ie_X
, ie
->ie_Y
));
1928 IntuitionBase
->MouseX
= ie
->ie_X
;
1929 IntuitionBase
->MouseY
= ie
->ie_Y
;
1930 notify_mousemove_screensandwindows(IntuitionBase
);
1934 /* new event, we need to reset this */
1935 screen
= FindActiveScreen(IntuitionBase
);
1936 iihdata
->ActEventTablet
= 0;
1938 /* Set the timestamp in IntuitionBase */
1940 IntuitionBase
->Seconds
= ie
->ie_TimeStamp
.tv_secs
;
1941 IntuitionBase
->Micros
= ie
->ie_TimeStamp
.tv_micro
;
1943 #if 0 /* toolbox stuff disabled. broken. calling LockLayerinfo() for every event is broken. deadlocks */
1944 /* Use event to find the active window */
1946 toolbox
= GetToolBoxWindow(ie
, screen
, IntuitionBase
);
1950 /* Do ToolBox Window Actions */
1951 /* ToolBox Windows supports only a subset of IECLASS Actions */
1952 switch (ie
->ie_Class
) {
1954 case IECLASS_RAWMOUSE
:
1955 boxgadget
= Process_RawMouse(ie
, iihdata
, screen
, toolbox
, boxgadget
, boxgi
, 0, FALSE
, TRUE
,
1956 orig_ie
, &keep_event
, &reuse_event
,
1957 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1958 &call_setpointerpos
,
1963 } /* switch (ie->ie_Class) */
1964 } /* if (toolbox) */
1967 w
= IntuitionBase
->ActiveWindow
;
1969 if (!MENUS_ACTIVE
&& !SYSGADGET_ACTIVE
)
1971 /* lock = LockIBase(0UL); */
1974 if (ie
->ie_Class
== IECLASS_RAWMOUSE
&& ie
->ie_Code
== SELECTDOWN
)
1976 w
= FindActiveWindow(ie
, screen
, &stitlebarhit
, IntuitionBase
);
1977 DEBUG_CLICK(bug("iih:New active window: %p\n", w
));
1985 DEBUG_WINDOW(bug("Activating new window (title %s)\n", w
->Title
? w
->Title
: "<noname>"));
1987 DEBUG_WINDOW(bug("Window activated\n"));
1991 DEBUG_WINDOW(bug("Making active window inactive. Now there's no active window\n"));
1993 new_active_window
= TRUE
;
1994 iihdata
->NewActWindow
= w
;
1997 /* UnlockIBase(lock); */
1999 if (new_active_window
)
2002 (!(GetPrivScreen(w
->WScreen
)->MenuVerifyMsgCount
)) &&
2003 (!(MENUS_ACTIVE
)) && (!(SYSGADGET_ACTIVE
)))
2005 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
2008 case GTYP_CUSTOMGADGET
:
2010 struct gpGoInactive gpgi
;
2012 gpgi
.MethodID
= GM_GOINACTIVE
;
2013 gpgi
.gpgi_GInfo
= gi
;
2014 gpgi
.gpgi_Abort
= 1;
2016 Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpgi
, IntuitionBase
);
2020 case GTYP_STRGADGET
:
2021 gadget
->Flags
&= ~GFLG_SELECTED
;
2022 RefreshStrGadget(gadget
, gi
->gi_Window
, gi
->gi_Requester
, IntuitionBase
);
2025 case GTYP_BOOLGADGET
:
2026 /* That a bool gadget is active here can only happen
2027 if user used LMB to activate gadget and LAMIGA + LALT
2028 to activate other window, or viceversa */
2029 /* The gadget must be a RELVERIFY one */
2030 if (!(gadget
->Activation
& GACT_TOGGLESELECT
))
2034 inside
= InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
2035 gi
->gi_Requester
, gadget
,
2036 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
);
2040 gadget
->Flags
&= ~GFLG_SELECTED
;
2041 RefreshBoolGadgetState(gadget
, gi
->gi_Window
,
2042 gi
->gi_Requester
, IntuitionBase
);
2047 case GTYP_PROPGADGET
:
2048 /* That a prop gadget is active here can only happen
2049 if user used LMB to activate gadget and LAMIGA + LALT
2050 to activate other window, or viceversa */
2052 HandlePropSelectUp(gadget
, gi
->gi_Window
, NULL
, IntuitionBase
);
2053 if (gadget
->Activation
& GACT_RELVERIFY
)
2055 ih_fire_intuimessage(gi
->gi_Window
,
2063 } /* switch (gadget->GadgetType & GTYP_GTYPEMASK) */
2065 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
2066 iihdata
->ActiveGadget
= NULL
;
2070 /* ActivateWindow works if w = NULL */
2071 /* jacaDcaps: some gui toolkits (die reaction, die!) close the window opened by a boopsi gadget when
2072 it gets hit with lmb, so we need to check if the new active window does not go away by
2073 performing GM_GOINACTIVE on the gadget. NOTE: CloseWindow's part performed on input.device context
2074 clears the iihdata->NewActWindow if it's the actually closed one. */
2075 if (w
== iihdata
->NewActWindow
)
2081 w
= IntuitionBase
->ActiveWindow
;
2082 new_active_window
= FALSE
;
2083 ie
->ie_Class
= IECLASS_NULL
; //lose the event, otherwise the gadget will get activated again ;)
2086 iihdata
->NewActWindow
= 0;
2088 } /* if (new_active_window) */
2090 } /* if (!MENUS_ACTIVE) */
2095 req
= w
->FirstRequest
;
2098 D(bug("[Inputhandler] Screen 0x%p Window 0x%p Requester 0x%p gadget 0x%p\n", screen
, w
, req
, gadget
));
2100 switch (ie
->ie_Class
) {
2101 case IECLASS_POINTERPOS
:
2102 ie
->ie_SubClass
= IESUBCLASS_COMPATIBLE
;
2105 case IECLASS_NEWPOINTERPOS
:
2106 switch (ie
->ie_SubClass
)
2108 case IESUBCLASS_COMPATIBLE
:
2109 ie
->ie_Code
= IECODE_NOBUTTON
;
2112 case IESUBCLASS_PIXEL
:
2114 struct IEPointerPixel
*pp
= ie
->ie_EventAddress
;
2116 ie
->ie_X
= pp
->iepp_Position
.X
+ pp
->iepp_Screen
->LeftEdge
;
2117 ie
->ie_Y
= pp
->iepp_Position
.Y
+ pp
->iepp_Screen
->TopEdge
;
2119 ActivateMonitor(GetPrivScreen(pp
->iepp_Screen
)->IMonitorNode
, ie
->ie_X
, ie
->ie_Y
, IntuitionBase
);
2121 ie
->ie_Class
= IECLASS_RAWMOUSE
; /* otherwise a lot of code would ignore this message */
2122 ie
->ie_Code
= IECODE_NOBUTTON
;
2125 case IESUBCLASS_TABLET
:
2127 //unsupported - does anything use it anyway? ;)
2132 case IESUBCLASS_NEWTABLET
:
2134 struct IENewTablet
*nt
= (struct IENewTablet
*)ie
->ie_EventAddress
;
2138 iihdata
->ActEventTablet
= nt
; //cache this
2139 ie
->ie_X
= (screen
->Width
* nt
->ient_TabletX
) / nt
->ient_RangeX
;
2140 ie
->ie_Y
= (screen
->Height
* nt
->ient_TabletY
) / nt
->ient_RangeY
;
2142 ie
->ie_Class
= IECLASS_RAWMOUSE
;
2152 case IECLASS_RAWMOUSE
:
2153 gadget
= Process_RawMouse(ie
, iihdata
, screen
, w
, gadget
, gi
, stitlebarhit
, new_active_window
, FALSE
,
2154 orig_ie
, &keep_event
, &reuse_event
,
2155 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
2156 &call_setpointerpos
,
2162 case IECLASS_RAWKEY
:
2163 /* release events go only to gadgets and windows who
2164 have not set IDCMP_VANILLAKEY */
2166 DEBUG_HANDLER(dprintf("Handler: IECLASS_RAWKEY\n"));
2167 DEBUG_KEY(dprintf("Handler: Qual 0x%lx\n",iihdata
->ActQualifier
));
2169 iihdata
->ActQualifier
&= ~(KEY_QUALIFIERS
| IEQUALIFIER_REPEAT
);
2170 iihdata
->ActQualifier
|= (ie
->ie_Qualifier
& (KEY_QUALIFIERS
| IEQUALIFIER_REPEAT
));
2172 DEBUG_KEY(dprintf("Handler: real Qual 0x%lx\n",iihdata
->ActQualifier
));
2174 /* Keyboard mouse emulation and screen switching */
2177 UWORD code
= ie
->ie_Code
& ~IECODE_UP_PREFIX
;
2178 DEBUG_KEY(dprintf("Handler: code 0x%lx\n",code
));
2180 /* Left Amiga + N/M screen switching shortcut */
2181 if ((ie
->ie_Qualifier
& IEQUALIFIER_LCOMMAND
) && (code
== RAWKEY_N
|| code
== RAWKEY_M
)) {
2182 if (!(ie
->ie_Qualifier
& IEQUALIFIER_REPEAT
) && !(ie
->ie_Code
& IECODE_UP_PREFIX
)) {
2183 if (code
== RAWKEY_N
)
2185 else if (code
== RAWKEY_M
)
2186 ScreenToBack(IntuitionBase
->FirstScreen
);
2192 /* Mouse button emulation: LALT + LAMIGA = LBUTTON, RALT + RAMIGA = RBUTTON */
2193 if ((code
== RAWKEY_LAMIGA
) ||
2194 (code
== RAWKEY_LALT
) ||
2195 (code
== RAWKEY_RAMIGA
) ||
2196 (code
== RAWKEY_RALT
))
2198 DEBUG_KEY(dprintf("Handler: KeyMouseEmul\n"));
2199 iihdata
->PrevKeyMouseState
= iihdata
->ActKeyMouseState
;
2200 iihdata
->ActKeyMouseState
= 0;
2201 if ((ie
->ie_Qualifier
& (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_LALT
)) == (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_LALT
))
2203 iihdata
->ActKeyMouseState
|= IEQUALIFIER_LEFTBUTTON
;
2205 if ((ie
->ie_Qualifier
& (IEQUALIFIER_RCOMMAND
| IEQUALIFIER_RALT
)) == (IEQUALIFIER_RCOMMAND
| IEQUALIFIER_RALT
))
2207 iihdata
->ActKeyMouseState
|= IEQUALIFIER_RBUTTON
;
2210 if ((iihdata
->ActKeyMouseState
& IEQUALIFIER_LEFTBUTTON
) != (iihdata
->PrevKeyMouseState
& IEQUALIFIER_LEFTBUTTON
))
2212 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2213 orig_ie
->ie_SubClass
= 0;
2214 orig_ie
->ie_Code
= (iihdata
->ActKeyMouseState
& IEQUALIFIER_LEFTBUTTON
) ? IECODE_LBUTTON
: IECODE_LBUTTON
| IECODE_UP_PREFIX
;
2223 if ((iihdata
->ActKeyMouseState
& IEQUALIFIER_RBUTTON
) != (iihdata
->PrevKeyMouseState
& IEQUALIFIER_RBUTTON
))
2225 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2226 orig_ie
->ie_SubClass
= 0;
2227 orig_ie
->ie_Code
= (iihdata
->ActKeyMouseState
& IEQUALIFIER_RBUTTON
) ? IECODE_RBUTTON
: IECODE_RBUTTON
| IECODE_UP_PREFIX
;
2236 } /* if key is one of LAMIGA/LALT/RAMIGA/RALT */
2238 if ((iihdata
->ActQualifier
& (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_RCOMMAND
)) &&
2239 ((ie
->ie_Code
== RAWKEY_UP
) ||
2240 (ie
->ie_Code
== RAWKEY_DOWN
) ||
2241 (ie
->ie_Code
== RAWKEY_LEFT
) ||
2242 (ie
->ie_Code
== RAWKEY_RIGHT
)))
2244 static BYTE
const xmap
[] = { 0, 0, 1, -1};
2245 static BYTE
const ymap
[] = {-1, 1, 0, 0};
2248 shift
= (iihdata
->ActQualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) ? 40 : 1;
2250 /* Mouse Move Emulation */
2252 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2253 orig_ie
->ie_SubClass
= 0;
2254 orig_ie
->ie_Code
= IECODE_NOBUTTON
;
2255 orig_ie
->ie_Qualifier
= IEQUALIFIER_RELATIVEMOUSE
;
2256 orig_ie
->ie_X
= xmap
[code
- RAWKEY_UP
] * shift
;
2257 orig_ie
->ie_Y
= ymap
[code
- RAWKEY_UP
] * shift
;
2266 /* End Keyboard mouse emulation */
2270 DEBUG_KEY(dprintf("Handler: FireMenuMessage\n"));
2271 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2276 /* Hotkeys processing */
2281 if (!(ie
->ie_Code
& IECODE_UP_PREFIX
))
2282 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
2284 if (result
== RUNHOTREUSE
)
2294 w
= IntuitionBase
->ActiveWindow
;
2299 ((!(ie
->ie_Code
& IECODE_UP_PREFIX
)) ||
2301 (w
&& ((w
->IDCMPFlags
& IDCMP_VANILLAKEY
) == 0)) ))
2307 DEBUG_KEY(dprintf("Handler: Gadget 0x%lx active\n",gadget
));
2308 DEBUG_KEY(dprintf("Handler: GadgetID 0x%lx UserData 0x%lx\n",
2311 DEBUG_KEY(dprintf("Handler: GadgetType 0x%lx Flags 0x%lx Activation 0x%lx\n",
2314 gadget
->Activation
));
2315 DEBUG_KEY(dprintf("Handler: MoreFlags 0x%lx\n",
2316 ((struct ExtGadget
*)gadget
)->MoreFlags
));
2318 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
2320 case GTYP_STRGADGET
:
2323 ULONG ret
= HandleStrInput(gadget
, gi
, ie
, &imsgcode
,
2326 DEBUG_KEY(dprintf("Handler: Key GTYP_STRGADGET ret 0x%lx\n",ret
));
2327 if (ret
& (SGA_END
| SGA_NEXTACTIVE
| SGA_PREVACTIVE
))
2329 if (gadget
->Activation
& GACT_RELVERIFY
)
2331 DEBUG_KEY(dprintf("Handler: GACT_RELVERIFY\n"));
2332 ih_fire_intuimessage(w
,
2338 if (req
&& gadget
->Activation
& GACT_ENDGADGET
)
2340 DEBUG_KEY(dprintf("Handler: GACT_ENDGADGET\n"));
2343 req
= w
->FirstRequest
;
2348 if ((gadget
->Flags
& GFLG_TABCYCLE
) && (ret
& SGA_NEXTACTIVE
))
2350 gadget
= FindCycleGadget(w
, req
, gadget
, GMR_NEXTACTIVE
);
2351 DEBUG_KEY(dprintf("Handler: TabCycle next gadget 0x%lx\n",gadget
));
2353 else if ((gadget
->Flags
& GFLG_TABCYCLE
) && (ret
& SGA_PREVACTIVE
))
2355 gadget
= FindCycleGadget(w
, req
, gadget
, GMR_PREVACTIVE
);
2356 DEBUG_KEY(dprintf("Handler: TabCycle prev gadget 0x%lx\n",gadget
));
2365 gadget
= DoActivateGadget(w
, req
, gadget
, IntuitionBase
);
2368 } /* if (ret & (SGA_END | SGA_NEXTACTIVE | SGA_PREVACTIVE)) */
2373 case GTYP_CUSTOMGADGET
:
2374 DEBUG_KEY(dprintf("Handler: GTYP_CUSTOMGADGET\n"));
2375 DEBUG_KEY(dprintf("Handler: send GM_HANDLEINPUT\n"));
2376 gadget
= DoGPInput(gi
,
2382 DEBUG_KEY(dprintf("Handler: reuse %ld\n",reuse_event
));
2385 } /* switch (gadget type) */
2387 } /* if (a gadget is currently active) */
2388 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
))
2390 BOOL menushortcut
= FALSE
;
2392 DEBUG_KEY(dprintf("Handler: No Gadget active\n"));
2393 DEBUG_KEY(dprintf("Handler: Qualifier 0x%lx WinFlags 0x%lx IDCMP 0x%lx\n",ie
->ie_Qualifier
,w
->Flags
,w
->IDCMPFlags
));
2395 if ((ie
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
) &&
2396 (!(w
->Flags
& WFLG_RMBTRAP
)) &&
2397 (w
->IDCMPFlags
& IDCMP_MENUPICK
))
2399 struct Menu
*strip
= 0;
2401 DEBUG_KEY(dprintf("Handler: MenuKey\n"));
2402 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2404 strip
= w
->MenuStrip
;
2406 if (((struct IntWindow
*)w
)->menulendwindow
)
2408 strip
= ((struct IntWindow
*)w
)->menulendwindow
->MenuStrip
;
2411 DEBUG_KEY(dprintf("Handler: MenuStrip 0x%lx\n",strip
));
2416 if (MapRawKey(ie
, &key
, 1, NULL
) == 1)
2420 menucode
= FindMenuShortCut(strip
, key
, TRUE
, IntuitionBase
);
2422 DEBUG_KEY(dprintf("Handler: menucode 0x%lx\n",menucode
));
2424 if (menucode
!= MENUNULL
)
2426 DEBUG_KEY(dprintf("Handler: build menuevent\n"));
2427 ie
->ie_Class
= IECLASS_MENU
;
2428 ie
->ie_SubClass
= IESUBCLASS_MENUSTOP
;
2429 ie
->ie_EventAddress
= w
;
2430 ie
->ie_Code
= menucode
;
2433 menushortcut
= TRUE
;
2435 MENUS_ACTIVE
= TRUE
;
2436 iihdata
->MenuWindow
= w
;
2441 DEBUG_KEY(dprintf("Handler: MapRawKey failed\n"));
2444 if (!menushortcut
) /* !! */
2445 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2447 } /* if could be a menu short cut */
2449 if ((ie
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
) &&
2450 (!(w
->IDCMPFlags
& IDCMP_MENUPICK
)))
2452 struct Menu
*strip
= 0;
2453 struct Window
*window
= w
;
2455 /* not sure here about RMBTRAP */
2456 DEBUG_KEY(dprintf("Handler: no idcmp, create a MENULIST idcmp\n"));
2458 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2460 strip
= w
->MenuStrip
;
2462 if (((struct IntWindow
*)w
)->menulendwindow
)
2464 strip
= ((struct IntWindow
*)w
)->menulendwindow
->MenuStrip
;
2465 window
= ((struct IntWindow
*)w
)->menulendwindow
;
2468 DEBUG_KEY(dprintf("Handler: MenuStrip 0x%lx\n",strip
));
2473 if (MapRawKey(ie
, &key
, 1, NULL
) == 1)
2477 menucode
= FindMenuShortCut(strip
, key
, TRUE
, IntuitionBase
);
2479 DEBUG_KEY(dprintf("Handler: menucode 0x%lx\n",menucode
));
2481 if (menucode
!= MENUNULL
)
2483 DEBUG_KEY(dprintf("Handler: build menuevent\n"));
2484 ih_fire_intuimessage(window
,
2487 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machines!? */
2490 menushortcut
= TRUE
;
2495 DEBUG_KEY(dprintf("Handler: MapRawKey failed\n"));
2498 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2499 } /* if could be a menu short but current window has no idcmp cut */
2503 DEBUG_KEY(dprintf("Handler: menu shortcut..break\n"));
2507 /* This is a regular RAWKEY event (no gadget taking care
2510 if (iihdata
->ActQualifier
& IEQUALIFIER_REPEAT
)
2512 /* don't send repeat key events if repeatqueue is full */
2513 if (IW(w
)->num_repeatevents
>= IW(w
)->repeatqueue
)
2515 DEBUG_KEY(dprintf("Handler: RepeatEvents full..don't send more\n"));
2520 if (w
->IDCMPFlags
& IDCMP_VANILLAKEY
)
2524 DEBUG_KEY(dprintf("Handler: VANILLAKEY\n"));
2525 // DEBUG_KEY(dprintf("Handler: MapRawKey ie 0x%lx KeyMapBase 0x%lx IntutionBase 0x%lx\n",ie,KeymapBase,IntuitionBase));
2527 if (MapRawKey(ie
, &keyBuffer
, 1, NULL
) == 1)
2529 DEBUG_KEY(dprintf("Handler: send VANILLAKEY msg\n"));
2530 ih_fire_intuimessage(w
,
2533 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machines!? */
2535 DEBUG_KEY(dprintf("Handler: done\n"));
2539 /* If the event mapped to more than one byte, it is not
2540 a legal VANILLAKEY, so we send it as the original
2545 if (w
->IDCMPFlags
& IDCMP_RAWKEY
)
2547 DEBUG_KEY(dprintf("Handler: send IDCMP_RAWKEY Qual 0x%lx Code 0x%lx addr 0x%lx Event\n",
2548 ie
->ie_Qualifier
,ie
->ie_Code
,ie
->ie_position
.ie_addr
));
2549 ih_fire_intuimessage(w
,
2552 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machine!? */
2557 DEBUG_KEY(dprintf("Handler: done\n"));
2558 } /* regular RAWKEY */
2561 break; /* case IECLASS_RAWKEY */
2564 if (iihdata
->MouseBoundsKillTimer
)
2566 iihdata
->MouseBoundsKillTimer
--;
2567 if (iihdata
->MouseBoundsKillTimer
== 0)
2569 iihdata
->MouseBoundsActiveFlag
= FALSE
;
2573 if (GetPrivIBase(IntuitionBase
)->PointerDelay
)
2575 ULONG lock
= LockIBase(0);
2577 if (--GetPrivIBase(IntuitionBase
)->PointerDelay
== 0)
2579 struct SharedPointer
*shared_pointer
;
2580 struct Window
*window
= IntuitionBase
->ActiveWindow
;
2581 struct IntScreen
*scr
;
2583 DEBUG_POINTER(dprintf("InputHandler: PointerDelay\n"));
2584 DEBUG_POINTER(dprintf("InputHandler: Window 0x%lx\n",
2589 Object
*pointer
= ((struct IntWindow
*)window
)->pointer
;
2591 DEBUG_POINTER(dprintf("InputHandler: Pointer 0x%lx\n",
2593 scr
= GetPrivScreen(window
->WScreen
);
2596 DEBUG_POINTER(dprintf("InputHandler: Screen 0x%lx\n",
2598 if (pointer
== NULL
)
2600 pointer
= GetPrivIBase(IntuitionBase
)->DefaultPointer
;
2603 if (((struct IntWindow
*)window
)->busy
)
2605 pointer
= GetPrivIBase(IntuitionBase
)->BusyPointer
;
2608 GetAttr(POINTERA_SharedPointer
, pointer
, (IPTR
*) &shared_pointer
);
2610 DEBUG_POINTER(dprintf("InputHandler: scr 0x%lx pointer 0x%lx shared_pointer 0x%lx\n",
2611 scr
, pointer
, shared_pointer
));
2612 DEBUG_POINTER(dprintf("InputHandler: sprite 0x%lx\n",
2613 shared_pointer
->sprite
));
2615 if (DoMethod(scr
->IMonitorNode
, MM_SetPointerShape
, shared_pointer
))
2617 ObtainSharedPointer(shared_pointer
, IntuitionBase
);
2618 ReleaseSharedPointer(scr
->Pointer
, IntuitionBase
);
2619 scr
->Pointer
= shared_pointer
;
2622 window
->XOffset
= shared_pointer
->xoffset
;
2623 window
->YOffset
= shared_pointer
->yoffset
;
2628 DEBUG_POINTER(dprintf("InputHandler: can't set pointer.\n"));
2633 DEBUG_POINTER(dprintf("InputHandler: no screen.\n"));
2638 DEBUG_POINTER(dprintf("InputHandler: no window.\n"));
2645 if (GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
)
2647 struct IntScreen
*scr
= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
;
2649 if ((--scr
->MenuVerifyTimeOut
) <= 0)
2651 struct InputEvent ie
;
2653 /* currently we ONLY need the menu open time ! */
2654 ie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
2655 ie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
2657 if (FireMenuMessage(MMCODE_START
, scr
->MenuVerifyActiveWindow
, &ie
, IntuitionBase
))
2659 /* This lock will be released only when the user is
2660 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
2661 event arrives (generated by MenuHandler task) */
2663 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2664 iihdata
->MenuWindow
= scr
->MenuVerifyActiveWindow
;
2665 MENUS_ACTIVE
= TRUE
;
2668 scr
->MenuVerifyActiveWindow
= NULL
;
2669 scr
->MenuVerifyTimeOut
= 0;
2670 scr
->MenuVerifyMsgCount
= 0;
2671 scr
->MenuVerifySeconds
= 0;
2672 scr
->MenuVerifyMicros
= 0;
2673 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
2676 else if (MENUS_ACTIVE
)
2678 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2684 if (screen
->MouseY
<= screen
->BarHeight
&& GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
&& !iihdata
->TitlebarOnTop
&& iihdata
->TitlebarAppearTime
)
2686 UQUAD currenttime
= (((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50) + (UQUAD
)(ie
->ie_TimeStamp
.tv_micro
/ 20000);
2687 if (currenttime
>= iihdata
->TitlebarAppearTime
+ 10)
2689 iihdata
->TitlebarOnTop
= TRUE
;
2690 iihdata
->TitlebarAppearTime
= 0;
2692 LOCK_REFRESH(screen
);
2694 MoveLayer(0, screen
->BarLayer
, 0, screen
->BarHeight
+ 1);
2695 UpfrontLayer(0, screen
->BarLayer
);
2696 CheckLayers(screen
, IntuitionBase
);
2698 UNLOCK_REFRESH(screen
);
2704 UQUAD currenttime
= (((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50) + (UQUAD
)(ie
->ie_TimeStamp
.tv_micro
/ 20000);
2705 #define SECONDS(x) (x*50)
2706 if (iihdata
->HelpGadgetFindTime
&& (currenttime
>= iihdata
->HelpGadgetFindTime
+ SECONDS(1)))
2708 struct Gadget
*lhg
= iihdata
->LastHelpGadget
;
2709 fire_intuimessage(iihdata
->LastHelpWindow
,
2711 lhg
? lhg
->GadgetID
: 0, /* Don't know what it should be */
2714 iihdata
->HelpGadgetFindTime
= 0;
2720 if (IS_BOOPSI_GADGET(gadget
))
2722 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
2727 #if USE_NEWDISPLAYBEEP
2729 if (GetPrivIBase(IntuitionBase
)->BeepingScreens
)
2734 lock
= LockIBase(0);
2736 for (scr
= IntuitionBase
->FirstScreen
;
2737 scr
&& GetPrivIBase(IntuitionBase
)->BeepingScreens
;
2738 scr
= scr
->NextScreen
)
2740 if ((scr
->Flags
& BEEPING
) &&
2741 !GetPrivScreen(scr
)->BeepingCounter
--)
2743 GetPrivIBase(IntuitionBase
)->BeepingScreens
--;
2744 scr
->Flags
&= (UWORD
) ~BEEPING
;
2746 /* if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) <= 8)
2747 // visual beep on CLUT-screen
2749 // SetRGB4 (&screen->ViewPort, 0, scr->SaveColor0 & 0x000F, (scr->SaveColor0 & 0x00F0) >> 4, (scr->SaveColor0 & 0x0F00) >> 8);
2750 SetRGB32 (&scr->ViewPort, 0,
2751 GetPrivScreen(scr)->DisplayBeepColor0[0],
2752 GetPrivScreen(scr)->DisplayBeepColor0[1],
2753 GetPrivScreen(scr)->DisplayBeepColor0[2]
2757 // visual beep on hi- and truecolor screens
2759 RenderScreenBar(scr, FALSE, IntuitionBase);
2762 RenderScreenBar(scr
, FALSE
, IntuitionBase
);
2768 #endif /* USE_NEWDISPLAYBEEP */
2772 /* Send INTUITICK msg only if app already replied the last INTUITICK msg */
2773 if (w
->Flags
& WFLG_WINDOWTICKED
) break;
2775 if (w
->IDCMPFlags
& IDCMP_INTUITICKS
)
2777 /* Set the WINDOWTICKED flag, it will be cleared again when the app
2778 replies back the msg and the InputHandler handles the replymsg
2779 in HandleIntuiReplyPort() */
2781 ih_fire_intuimessage(w
,
2787 break; /* case IECLASS_TIMER */
2790 if (MENUS_ACTIVE
&& (ie
->ie_SubClass
== IESUBCLASS_MENUSTOP
))
2792 struct Window
*eventwin
= (struct Window
*)ie
->ie_EventAddress
;
2794 iihdata
->MenuWindow
= NULL
;
2795 MENUS_ACTIVE
= FALSE
;
2797 /* semaphore was locked when menu action started, see
2798 above where MMCODE_START MenuMessage is sent.
2800 It could have also have been locked if the user
2801 activated one of the menu key shortcuts, see
2802 "case IECLASS_RAWKEY" */
2804 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2808 if (((struct IntWindow
*)eventwin
)->menulendwindow
)
2810 eventwin
= ((struct IntWindow
*)eventwin
)->menulendwindow
;
2813 ih_fire_intuimessage((struct Window
*)eventwin
,
2816 (struct Window
*)ie
->ie_EventAddress
,
2822 case IECLASS_DISKINSERTED
:
2823 case IECLASS_DISKREMOVED
:
2824 case IECLASS_NEWPREFS
:
2830 switch (ie
->ie_Class
)
2832 case IECLASS_DISKINSERTED
:
2833 idcmp
= IDCMP_DISKINSERTED
;
2836 case IECLASS_DISKREMOVED
:
2837 idcmp
= IDCMP_DISKREMOVED
;
2841 idcmp
= IDCMP_NEWPREFS
;
2843 * Here we need to update the mouse prefs and
2844 * maybe other stuff which comes from the global prefs file.
2849 lock
= LockIBase(0);
2851 for (scr
= IntuitionBase
->FirstScreen
; scr
; scr
= scr
->NextScreen
)
2855 for (win
= scr
->FirstWindow
; win
; win
= win
->NextWindow
)
2858 CHECKME, really use fire_intuimessage() here,
2859 instead of ih_fireintuimessage? Same for
2860 IDCMP_GADGETHELP above, BTW. */
2862 fire_intuimessage(win
,
2874 case IECLASS_NEWMOUSE
:
2877 * The following is only needed on hardware not running
2878 * the NewMouse driver.
2880 if (w
->IDCMPFlags
& IDCMP_RAWKEY
&& (!SysBase
->MaxLocMem
))
2882 ih_fire_intuimessage(w
,
2885 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machine!? */
2895 case IECLASS_NEWTIMER
:
2898 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2905 if (gadget
== iihdata
->MasterSizeGadget
)
2907 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
2912 #endif /* __MORPHOS__ */
2917 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2924 "[Intui] InputHandler: Unknown IEClass: addr = %x class = %d (origclass = %d)\n",
2925 orig_ie
, ie
->ie_Class
,orig_ie
->ie_Class
2929 } /* switch (ie->ie_Class) */
2934 else if (keep_event
&& !ie_used
)
2936 *iihdata
->EndInputEventChain
= orig_ie
;
2937 iihdata
->EndInputEventChain
= &orig_ie
->ie_NextEvent
;
2942 orig_ie
->ie_NextEvent
= iihdata
->FreeInputEvents
;
2943 iihdata
->FreeInputEvents
= orig_ie
;
2946 } /* for (each event in the chain) */
2948 iihdata
->ActiveGadget
= gadget
;
2950 D(bug("Outside pollingloop\n"));
2952 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
2953 if (call_setpointerpos
)
2954 MySetPointerPos(IntuitionBase
);
2957 /* Terminate the event chain. */
2958 *iihdata
->EndInputEventChain
= NULL
;
2960 /* Transfer the list of allocated events in the list of events that should
2961 * be freed the next time the handler is entered.
2963 iihdata
->AllocatedInputEventList
= iihdata
->NewAllocatedInputEventList
;
2964 NEWLIST((struct List
*)&iihdata
->NewAllocatedInputEventList
);
2966 /* Reset the event chain here, not at the beginning of the handler, for
2967 * events that might be allocated in other handers.
2969 iihdata
->EndInputEventChain
= &iihdata
->ReturnInputEvent
;
2970 iihdata
->FreeInputEvents
= NULL
;
2972 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->InputHandlerLock
);
2974 // DEBUG_HANDLER(dprintf("Handler: ->IBase 0x%lx KeyMapBase 0x%lx\n",IntuitionBase,KeymapBase));
2976 return iihdata
->ReturnInputEvent
;
2981 /****************************************************************************************/