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 <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
= CreateMsgPort();
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 FreeSignal(port
->mp_SigBit
);
122 port
->mp_SigBit
= -1;
123 port
->mp_Flags
= PA_IGNORE
;
125 iihdata
->IntuiReplyPort
= port
;
127 NEWLIST((struct List
*) &iihdata
->IntuiActionQueue
);
128 NEWLIST((struct List
*)&iihdata
->NewAllocatedInputEventList
);
129 NEWLIST((struct List
*)&iihdata
->AllocatedInputEventList
);
130 iihdata
->EndInputEventChain
= &iihdata
->ReturnInputEvent
;
131 iihdata
->FreeInputEvents
= NULL
;
133 iihdata
->ActQualifier
= IEQUALIFIER_RELATIVEMOUSE
;
135 /* Note: there are several routines like CloseWindow, which
136 expect is_Data to point to the IIHData structure, so don't
139 iihandler
->is_Code
= (VOID_FUNC
)AROS_ASMSYMNAME(IntuiInputHandler
);
140 iihandler
->is_Data
= iihdata
;
141 iihandler
->is_Node
.ln_Pri
= 50;
142 iihandler
->is_Node
.ln_Name
= "Intuition InputHandler";
144 lock
= LockIBase(0UL);
146 iihdata
->IntuitionBase
= IntuitionBase
;
150 GetPrivIBase(IntuitionBase
)->IntuiReplyPort
= iihdata
->IntuiReplyPort
;
151 GetPrivIBase(IntuitionBase
)->IntuiActionQueue
= &iihdata
->IntuiActionQueue
;
153 ReturnPtr ("InitIIH", struct Interrupt
*, iihandler
);
154 } /* f (iihdata->MasterDragGadget && iihdata->MasterSizeGadget) */
156 DisposeObject((Object
*)iihdata
->MasterDragGadget
);
157 DisposeObject((Object
*)iihdata
->MasterSizeGadget
);
159 DeletePool(iihdata
->ActionsMemPool
);
160 DeletePool(iihdata
->InputEventMemPool
);
162 } /* if (iihdata->InputEventMemPool = ... */
166 FreeMem(iihdata
, sizeof (struct IIHData
));
167 iihdata
->MouseBoundsActiveFlag
= FALSE
;
170 FreeMem(iihandler
, sizeof (struct Interrupt
));
172 } /* if (iihandler) */
174 ReturnPtr ("InitIIH", struct Interrupt
*, NULL
);
177 /****************************************************************************************/
179 VOID
CleanupIIH(struct Interrupt
*iihandler
, struct IntuitionBase
*IntuitionBase
)
181 struct IIHData
*iihdata
= (struct IIHData
*)iihandler
->is_Data
;
183 DisposeObject((Object
*)iihdata
->MasterDragGadget
);
184 DisposeObject((Object
*)iihdata
->MasterSizeGadget
);
186 FreeGeneratedInputEvents(iihdata
);
187 DeletePool(iihdata
->InputEventMemPool
);
188 DeletePool(iihdata
->ActionsMemPool
);
190 /* One might think that this port is still in use by the inputhandler.
191 ** However, if intuition is closed for the last time, there should be no
192 ** windows that IntuiMessage can be sent to.
194 FreeMem(iihdata
->IntuiReplyPort
, sizeof (struct MsgPort
));
196 FreeMem(iihdata
, sizeof (struct IIHData
));
197 FreeMem(iihandler
, sizeof (struct Interrupt
));
202 /****************************************************************************************/
204 static void HandleIntuiReplyPort(struct IIHData
*iihdata
, struct IntuitionBase
*IntuitionBase
)
206 struct Library
*TimerBase
= GetPrivIBase(IntuitionBase
)->TimerBase
;
207 struct IntuiMessage
*im
;
209 while ((im
= (struct IntuiMessage
*)GetMsg(iihdata
->IntuiReplyPort
)))
211 if (im
->IDCMPWindow
&& ResourceExisting(im
->IDCMPWindow
, RESOURCE_WINDOW
, IntuitionBase
))
213 struct IntWindow
*win
= (struct IntWindow
*)im
->IDCMPWindow
;
216 GetSysTime(&win
->lastmsgreplied
);
221 case IDCMP_MOUSEMOVE
:
222 IW(im
->IDCMPWindow
)->num_mouseevents
--;
225 case IDCMP_INTUITICKS
:
226 AROS_ATOMIC_AND(im
->IDCMPWindow
->Flags
, ~WFLG_WINDOWTICKED
);
229 #if USE_IDCMPUPDATE_MESSAGECACHE
230 case IDCMP_IDCMPUPDATE
:
231 IW(im
->IDCMPWindow
)->num_idcmpupdate
--;
233 if (!(IW(im
->IDCMPWindow
)->num_idcmpupdate
) && IW(im
->IDCMPWindow
)->messagecache
)
235 SendIntuiMessage(im
->IDCMPWindow
,IW(im
->IDCMPWindow
)->messagecache
);
236 IW(im
->IDCMPWindow
)->messagecache
= 0;
241 case IDCMP_MENUVERIFY
:
243 struct Window
*w
= im
->IDCMPWindow
;
244 struct IntScreen
*scr
= 0;
246 scr
= GetPrivScreen(w
->WScreen
);
248 if (scr
!= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
||
249 scr
->MenuVerifySeconds
> im
->Seconds
||
250 (scr
->MenuVerifySeconds
== im
->Seconds
&&
251 scr
->MenuVerifyMicros
> im
->Micros
))
253 /* The timeout has expired, just ignore. */
257 --scr
->MenuVerifyMsgCount
;
258 if (w
== scr
->MenuVerifyActiveWindow
&&
259 im
->Code
== MENUCANCEL
)
261 ULONG lock
= LockIBase(0);
264 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
266 if (w1
->IDCMPFlags
& IDCMP_MENUVERIFY
&& w1
!= scr
->MenuVerifyActiveWindow
)
268 ih_fire_intuimessage(w1
,
278 scr
->MenuVerifyActiveWindow
= NULL
;
279 scr
->MenuVerifyTimeOut
= 0;
280 scr
->MenuVerifyMsgCount
= 0;
281 scr
->MenuVerifySeconds
= 0;
282 scr
->MenuVerifyMicros
= 0;
283 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
285 else if (scr
->MenuVerifyMsgCount
== 0)
287 struct InputEvent ie
;
289 /* currently we ONLY need the menu open time ! */
290 ie
.ie_TimeStamp
.tv_secs
= im
->Seconds
;
291 ie
.ie_TimeStamp
.tv_micro
= im
->Micros
;
293 if (FireMenuMessage(MMCODE_START
, scr
->MenuVerifyActiveWindow
, &ie
, IntuitionBase
))
295 /* This lock will be released only when the user is
296 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
297 event arrives (generated by MenuHandler task) */
299 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
300 iihdata
->MenuWindow
= scr
->MenuVerifyActiveWindow
;
304 scr
->MenuVerifyActiveWindow
= NULL
;
305 scr
->MenuVerifyTimeOut
= 0;
306 scr
->MenuVerifyMsgCount
= 0;
307 scr
->MenuVerifySeconds
= 0;
308 scr
->MenuVerifyMicros
= 0;
309 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
315 case IDCMP_SIZEVERIFY
:
317 struct GadgetInfo
*gi
= &iihdata
->GadgetInfo
;
318 struct Window
*w
= im
->IDCMPWindow
;
319 struct Gadget
*gadget
= im
->IAddress
;
320 struct InputEvent ie
;
323 PrepareGadgetInfo(gi
, IntuitionBase
->ActiveScreen
, w
, NULL
);
324 SetGadgetInfoGadget(gi
, gadget
, IntuitionBase
);
326 if (IS_BOOPSI_GADGET(gadget
))
328 ie
.ie_NextEvent
= NULL
;
329 ie
.ie_Class
= IECLASS_RAWMOUSE
;
331 ie
.ie_Code
= IECODE_LBUTTON
;
332 ie
.ie_Qualifier
= im
->Qualifier
;
333 ie
.ie_X
= im
->MouseX
;
334 ie
.ie_Y
= im
->MouseY
;
335 ie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
336 ie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
345 /* For compatibility, send a GM_HANDLEINPUT too */
346 ie
.ie_Class
= IECLASS_RAWMOUSE
;
347 ie
.ie_Code
= IECODE_NOBUTTON
;
351 gadget
= DoGPInput(gi
,
359 /* From now on the master drag/size gadget takes over */
361 iihdata
->ActiveSysGadget
= gadget
;
362 gadget
= iihdata
->MasterSizeGadget
;
363 iihdata
->ActiveGadget
= gadget
;
365 ie
.ie_Class
= IECLASS_RAWMOUSE
;
366 ie
.ie_Code
= IECODE_LBUTTON
;
367 ie
.ie_X
= im
->MouseX
;
368 ie
.ie_Y
= im
->MouseY
;
379 case IDCMP_REQVERIFY
:
381 struct Window
*w
= im
->IDCMPWindow
;
383 EndRequest(w
->DMRequest
, w
);
385 ih_fire_intuimessage(w
,
393 case IDCMP_WBENCHMESSAGE
:
394 DEBUG_WORKBENCH(dprintf("HandleIntuiReplyPort: code 0x%lx\n",
398 } /* switch(im->Class) */
400 if (im
->Qualifier
& IEQUALIFIER_REPEAT
)
402 /* IDCMP_IDCMPUPDATE messages can also be sent from app task, therefore
403 it would be better if there was an ATOMIC_DEC macro or something */
405 if (IW(im
->IDCMPWindow
)->num_repeatevents
)
407 IW(im
->IDCMPWindow
)->num_repeatevents
--;
411 FreeIntuiMessage(im
);
413 } /* while ((im = (struct IntuiMessage *)GetMsg(iihdata->IntuiReplyPort))) */
415 /****************************************************************************************/
417 struct Window
*GetToolBoxWindow(struct InputEvent
*ie
, struct Screen
*scr
, struct IntuitionBase
*IntuitionBase
)
419 /* The caller has checked that the input event is a IECLASS_RAWMOUSE, SELECTDOWN event */
420 /* NOTE: may be called with NULL ie ptr! */
421 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
423 struct Window
*new_w
= NULL
;
427 D(bug("GetToolBoxWindow: Click at (%d,%d)\n",scr
->MouseX
,scr
->MouseY
));
430 LockLayerInfo(&scr
->LayerInfo
);
432 l
= WhichLayer(&scr
->LayerInfo
, scr
->MouseX
, scr
->MouseY
);
434 UnlockLayerInfo(&scr
->LayerInfo
);
439 D(bug("GetToolBoxWindow: Click not inside layer\n"));
441 else if (l
== scr
->BarLayer
)
446 new_w
= (struct Window
*)l
->Window
;
449 if ((new_w
->Flags
& WFLG_TOOLBOX
) == 0) new_w
= NULL
;
453 D(bug("GetToolBoxWindow: Selected layer is not a ToolBox window\n"));
457 D(bug("GetToolBoxWindow: Found layer %p\n", l
));
462 D(bug("GetToolBoxWindow: New window %p\n", new_w
));
466 /****************************************************************************************/
468 #define KEY_QUALIFIERS (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT | \
469 IEQUALIFIER_CAPSLOCK | IEQUALIFIER_CONTROL | \
470 IEQUALIFIER_LALT | IEQUALIFIER_RALT | \
471 IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND | \
472 IEQUALIFIER_NUMERICPAD)
474 #define BUTTON_QUALIFIERS (IEQUALIFIER_MIDBUTTON | IEQUALIFIER_RBUTTON | IEQUALIFIER_LEFTBUTTON)
476 static struct Gadget
*Process_RawMouse(struct InputEvent
*ie
, struct IIHData
*iihdata
, struct Screen
*screen
,
477 struct Window
*w
, struct Gadget
*gadget
, struct GadgetInfo
*gi
,
478 ULONG stitlebarhit
, BOOL new_active_window
, BOOL IsToolbox
,
479 struct InputEvent
*orig_ie
, BOOL
*keep_event
, BOOL
*reuse_event
,
480 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
481 BOOL
*call_setpointerpos
,
483 struct IntuitionBase
*IntuitionBase
)
485 struct Library
*InputBase
= GetPrivIBase(IntuitionBase
)->InputBase
;
486 struct Requester
*req
= w
? w
->FirstRequest
: NULL
;
488 switch (ie
->ie_Code
) {
491 BOOL new_gadget
= FALSE
;
492 BOOL sizeverify
= FALSE
;
493 UWORD MetaDrag
= GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_MetaDrag
;
495 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
));
496 DEBUG_CLICK(if (screen
) bug("[Inputhandler] Coordinates: (%d, %d)\n", screen
->MouseX
, screen
->MouseY
));
498 iihdata
->ActQualifier
|= IEQUALIFIER_LEFTBUTTON
;
500 /* Enter screen dragging mode if LButton + MetaDrag are pressed. */
501 if (MetaDrag
&& ((iihdata
->ActQualifier
& KEY_QUALIFIERS
) == MetaDrag
)) {
502 iihdata
->ScreenDrag
= screen
;
503 iihdata
->ScreenDragPointX
= screen
->MouseX
;
504 iihdata
->ScreenDragPointY
= screen
->MouseY
;
510 iihdata
->TitlebarAppearTime
= 0;
514 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
522 struct Gadget
* draggadget
= 0;
524 if ((!(w
->FirstRequest
)) && (w
->Flags
& WFLG_DRAGBAR
) && MatchHotkey(ie
,IA_ACTIVEWINDOWMOVE
,IntuitionBase
))
526 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)
528 for (draggadget
= w
->FirstGadget
; draggadget
; draggadget
= draggadget
->NextGadget
)
530 if ((draggadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
)
540 if ((!(w
->FirstRequest
)) && (w
->Flags
& WFLG_SIZEGADGET
) && MatchHotkey(ie
,IA_ACTIVEWINDOWSIZE
,IntuitionBase
))
542 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)
544 for (draggadget
= w
->FirstGadget
; draggadget
; draggadget
= draggadget
->NextGadget
)
546 if ((draggadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
)
560 /* use the *current* screen rather than active one when searching
561 for sdepth gadget! */
563 gadget
= FindGadget (screen
, stitlebarhit
? NULL
: w
, stitlebarhit
? NULL
: req
,
564 screen
->MouseX
, screen
->MouseY
, gi
, FALSE
, IntuitionBase
);
565 DEBUG_CLICK(bug("Click on gadget %p\n", gadget
));
570 /* If we clicked screen titlebar outside of any gadget, enter drag mode */
571 if ((!gadget
) && stitlebarhit
) {
572 DEBUG_CLICK(bug("[Inputhandler] Entering drag state for screen 0x%p\n", screen
));
573 iihdata
->ScreenDrag
= screen
;
574 iihdata
->ScreenDragPointX
= screen
->MouseX
;
575 iihdata
->ScreenDragPointY
= screen
->MouseY
;
581 if (!gadget
&& stitlebarhit
)
583 struct Window
*ww
= 0;
585 ww
= FindDesktopWindow(screen
, IntuitionBase
);
586 DEBUG_CLICK(bug("[Inputhandler] Clicked on backdrop window 0x%p\n", ww
));
593 if (!stitlebarhit
&& !new_active_window
&& DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
594 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
596 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= SELECTDOWN
)
598 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
599 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= SELECTDOWN
;
603 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
608 DEBUG_CLICK(bug("[Inputhandler] Resetting doubleclick counter\n"));
609 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= SELECTDOWN
;
610 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
613 /* update last click time for doubleclicktofront */
614 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
615 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
622 if (!(gadget
&& ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
)))
623 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
626 if (result
== RUNHOTREUSE
)
638 if (gadget
&& new_gadget
)
640 DEBUG_GADGET(bug("[Inputhandler] Activate gadget: 0x%p\n", gadget
));
641 if (w
&& (w
->IDCMPFlags
& IDCMP_SIZEVERIFY
) &&
642 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
/*||
643 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WZOOM*/)
645 ih_fire_intuimessage(w
,
655 BOOL is_draggad
, is_sizegad
;
658 /* Whenever the active gadget changes the gi must be updated
659 because it is cached in iidata->GadgetInfo!!!! Don't
660 forget to do this if somewhere else the active
661 gadget is changed, for example in ActivateGadget!!! */
663 PrepareGadgetInfo(gi
, screen
, w
, req
);
664 SetGadgetInfoGadget(gi
, gadget
, IntuitionBase
);
666 gsystype
= gadget
->GadgetType
& GTYP_SYSTYPEMASK
;
667 is_draggad
= ((gsystype
== GTYP_WDRAGGING
)
669 || (gsystype
== GTYP_WDRAGGING2
)
672 is_sizegad
= (gsystype
== GTYP_SIZING
);
674 /* jDc: intui68k sends IDCMPs for GACT_IMMEDIATE drag&sizegads! */
675 if (gadget
->Activation
& GACT_IMMEDIATE
)
677 ih_fire_intuimessage(w
,
684 if (is_draggad
|| is_sizegad
)
686 if (IS_BOOPSI_GADGET(gadget
))
695 /* Ignoring retval of dispatcher above is what
696 AmigaOS does too for boopsi drag/resize
701 /* From now on the master drag/size gadget takes over */
702 if ((w
->MoreFlags
& WMFLG_IAMMUI
) && (w
->Flags
& WFLG_BORDERLESS
))
703 iihdata
->ActiveSysGadget
= is_draggad
? gadget
: 0;
705 iihdata
->ActiveSysGadget
= gadget
;
706 gadget
= is_draggad
? iihdata
->MasterDragGadget
: iihdata
->MasterSizeGadget
;
714 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
716 case GTYP_BOOLGADGET
:
717 /* Only set the GFLG_SELECTED flag for RELVERIFY and
718 * TOGGLESELECT gadget. It's for the user to do it if
719 * he wants for other GADGIMMEDIATE ones.
720 * Only RELVERIFY gadgets stay active.
723 if (gadget
->Activation
& (GACT_TOGGLESELECT
| GACT_RELVERIFY
))
725 gadget
->Flags
^= GFLG_SELECTED
;
726 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
729 if (gadget
->Activation
& GACT_RELVERIFY
)
731 gadget
->Activation
|= GACT_ACTIVEGADGET
;
732 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
740 case GTYP_PROPGADGET
:
741 HandlePropSelectDown(gadget
,
744 w
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
745 w
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
752 /* If the click was inside the active strgad,
753 ** then let it update cursor pos,
754 ** else deactivate stringadget and reuse event.
757 if (InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
758 gi
->gi_Requester
, gadget
,
759 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
))
763 HandleStrInput(gadget
, gi
, ie
, &imsgcode
,
768 gadget
->Flags
&= ~GFLG_SELECTED
;
770 RefreshStrGadget(gadget
, w
, req
, IntuitionBase
);
771 /* Gadget not active anymore */
777 case GTYP_CUSTOMGADGET
:
778 gadget
= DoGPInput(gi
,
781 (new_gadget
? GM_GOACTIVE
: GM_HANDLEINPUT
),
784 D(bug("new_gadget %d, goactive %p\n", new_gadget
, gadget
));
786 if (gadget
&& new_gadget
&& (!(gadget
->GadgetType
& GTYP_SIZING
)))
788 /* For compatibility, send a GM_HANDLEINPUT too */
789 struct InputEvent newie
;
792 newie
.ie_NextEvent
= NULL
;
793 newie
.ie_Class
= IECLASS_RAWMOUSE
;
794 newie
.ie_SubClass
= 0;
795 newie
.ie_Code
= IECODE_NOBUTTON
;
796 newie
.ie_Qualifier
= ie
->ie_Qualifier
;
799 newie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
800 newie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
802 gadget
= DoGPInput(gi
,
808 D(bug("handleinput %p\n", gadget
));
812 case 0: //orig gadtools / some 1.3 gadgets
813 if (IS_SYS_GADGET(gadget
))
815 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
819 if (gadget
->Activation
& GACT_RELVERIFY
)
821 gadget
->Activation
|= GACT_ACTIVEGADGET
;
822 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
823 if (gadget
->Flags
& GFLG_GADGHIMAGE
)
825 gadget
->Flags
^= GFLG_SELECTED
;
826 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
831 /* jDc: this is what original intuition does, before crashing after a while ;)*/
832 DEBUG_CLICK(bug("[Inputhandler] Sending SELECTDOWN (old gadget), window 0x%p\n", w
));
833 ih_fire_intuimessage(w
,
841 } /* switch (GadgetType) */
843 } /* if (a gadget is active) */
844 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && !sizeverify
&& !stitlebarhit
)
846 DEBUG_CLICK(bug("[Inputhandler] Sending SELECTDOWN, window 0x%p\n", w
));
847 ih_fire_intuimessage(w
,
854 } /* case SELECTDOWN */
858 iihdata
->ActQualifier
&= ~IEQUALIFIER_LEFTBUTTON
;
860 /* Ignore this event if screen drag qualifier is pressed */
861 if (iihdata
->ScreenDrag
) {
862 iihdata
->ScreenDrag
= NULL
;
868 iihdata
->TitlebarAppearTime
= 0;
872 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
879 BOOL inside
= InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
880 gi
->gi_Requester
, gadget
,
881 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
);
883 /*int selected = (gadget->Flags & GFLG_SELECTED) != 0;*/
885 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
887 case GTYP_BOOLGADGET
:
888 /* Must be a RELVERIFY gadget */
890 if (!(gadget
->Activation
& GACT_TOGGLESELECT
) && inside
)
892 gadget
->Flags
^= GFLG_SELECTED
;
893 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
898 if (IS_SYS_GADGET(gadget
))
900 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
904 if (req
&& gadget
->Activation
& GACT_ENDGADGET
)
908 req
= w
->FirstRequest
;
911 ih_fire_intuimessage(w
,
921 ih_fire_intuimessage(w
,
928 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
932 case GTYP_PROPGADGET
:
933 HandlePropSelectUp(gadget
, w
, req
, IntuitionBase
);
934 if (gadget
->Activation
& GACT_RELVERIFY
)
936 ih_fire_intuimessage(w
,
946 /* Intuition string gadgets don't care about SELECTUP */
948 case GTYP_CUSTOMGADGET
:
949 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
952 case 0: //orig gadtools / some 1.3 gadgets
953 /* jDc: adding a gadget with gtyp field set to NULL crashes intui68k
954 ** seems we don't need compatibility on this field ;) anyway we should
955 ** handle the case of GTYP_CLOSE, etc, set by some "cod3r"
957 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
958 if (gadget
->Activation
& GACT_RELVERIFY
)
960 if (gadget
->Flags
& GFLG_GADGHIMAGE
)
964 gadget
->Flags
^= GFLG_SELECTED
;
965 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
971 ih_fire_intuimessage(w
,
978 ih_fire_intuimessage(w
,
987 } /* switch GadgetType */
989 } /* if (a gadget is currently active) */
990 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
))
992 ih_fire_intuimessage(w
,
999 break; /* case SELECTUP */
1002 iihdata
->ActQualifier
|= IEQUALIFIER_RBUTTON
;
1005 iihdata
->TitlebarAppearTime
= 0;
1009 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1010 *keep_event
= FALSE
;
1014 if (DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
1015 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
1017 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= MENUDOWN
)
1019 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1020 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MENUDOWN
;
1024 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
1029 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MENUDOWN
;
1030 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1033 /* update last click time for doubleclicktofront */
1034 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
1035 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
1041 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
1043 if (result
== RUNHOTREUSE
)
1045 *reuse_event
= TRUE
;
1049 *keep_event
= FALSE
;
1053 w
= IntuitionBase
->ActiveWindow
;
1058 if ((!MENUS_ACTIVE
) && (!gadget
) && (!(iihdata
->ActQualifier
& (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_MIDBUTTON
))))
1061 struct GadgetInfo ginf
;
1063 struct Window
*wind
= FindActiveWindow(0, screen
, &hit
,IntuitionBase
);
1067 gad
= FindGadget (screen
,
1069 IntuitionBase
->ActiveScreen
->MouseX
,
1070 IntuitionBase
->ActiveScreen
->MouseY
,
1071 &ginf
, TRUE
, IntuitionBase
);
1073 if (gad
&& ((gad
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
))
1075 CreateSmallMenuTask(wind
,SMALLMENU_TYPE_WINDOWDEPTH
,IntuitionBase
);
1076 *keep_event
= FALSE
;
1080 if (gad
&& ((gad
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SDEPTH
))
1082 CreateSmallMenuTask(0,SMALLMENU_TYPE_SCREENDEPTH
,IntuitionBase
);
1083 *keep_event
= FALSE
;
1090 if (w
&& !req
&& w
->DMRequest
&& !(w
->Flags
& WFLG_RMBTRAP
))
1092 if (!MENUS_ACTIVE
&&
1093 DoubleClick(GetPrivIBase(IntuitionBase
)->DMStartSecs
,
1094 GetPrivIBase(IntuitionBase
)->DMStartMicro
,
1095 ie
->ie_TimeStamp
.tv_secs
,
1096 ie
->ie_TimeStamp
.tv_micro
))
1098 if (w
->IDCMPFlags
& IDCMP_REQVERIFY
)
1100 ih_fire_intuimessage(w
,
1106 else if (Request(w
->DMRequest
, w
))
1110 ih_fire_intuimessage(w
,
1116 *keep_event
= FALSE
;
1120 GetPrivIBase(IntuitionBase
)->DMStartSecs
= ie
->ie_TimeStamp
.tv_secs
;
1121 GetPrivIBase(IntuitionBase
)->DMStartMicro
= ie
->ie_TimeStamp
.tv_micro
;
1126 if (!(w
->Flags
& WFLG_RMBTRAP
) && !req
)
1128 struct IntScreen
*scr
= GetPrivScreen(w
->WScreen
);
1131 BOOL mouseon
= TRUE
;
1133 scr
->MenuVerifyMsgCount
= 0;
1135 if (w
->MouseX
< 0 || w
->MouseY
< 0) mouseon
= FALSE
;
1136 if (w
->MouseX
> w
->Width
|| w
->MouseY
> w
->Height
) mouseon
= FALSE
;
1138 if (w
->IDCMPFlags
& IDCMP_MENUVERIFY
&& (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
1140 ih_fire_intuimessage(w
,
1142 mouseon
? MENUHOT
: MENUWAITING
,
1145 scr
->MenuVerifyMsgCount
++;
1148 lock
= LockIBase(0);
1150 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
1152 if ((w1
->IDCMPFlags
& IDCMP_MENUVERIFY
) && (w1
!= w
) && (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
1154 ih_fire_intuimessage(w1
,
1159 ++scr
->MenuVerifyMsgCount
;
1165 /* FIXME: when a window is opened with IDCMP_MENUVERIFY
1166 * (or this event is requested via ModifyIDCMP), and a
1167 * verify operation is pending, the window should get
1168 * a verify message too. Oh well.
1171 if (scr
->MenuVerifyMsgCount
)
1173 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= scr
;
1174 scr
->MenuVerifyActiveWindow
= w
;
1175 scr
->MenuVerifyTimeOut
= 2;
1176 scr
->MenuVerifySeconds
= IntuitionBase
->Seconds
;
1177 scr
->MenuVerifyMicros
= IntuitionBase
->Micros
;
1179 else if (FireMenuMessage(MMCODE_START
, w
, NULL
/*ie*/, IntuitionBase
))
1181 /* This lock will be released only when the user is
1182 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
1183 event arrives (generated by MenuHandler task) */
1185 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
1186 iihdata
->MenuWindow
= w
;
1187 MENUS_ACTIVE
= TRUE
;
1197 switch(ie
->ie_Code
) {
1199 iihdata
->ActQualifier
&= ~IEQUALIFIER_RBUTTON
;
1200 if (GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
)
1203 struct IntScreen
*scr
= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
;
1204 ULONG lock
= LockIBase(0);
1206 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
1208 if (w1
->IDCMPFlags
& IDCMP_MENUVERIFY
&& w1
->IDCMPFlags
& IDCMP_MOUSEBUTTONS
)
1210 ih_fire_intuimessage(w1
,
1220 /* FIXME: when the active window replies the verifymessage,
1221 * it should get a IDCMP_MENUPICK/MENUNULL message.
1223 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
1224 scr
->MenuVerifyActiveWindow
= NULL
;
1225 scr
->MenuVerifyMsgCount
= 0;
1226 scr
->MenuVerifyTimeOut
= 0;
1227 scr
->MenuVerifySeconds
= 0;
1228 scr
->MenuVerifyMicros
= 0;
1233 iihdata
->ActQualifier
|= IEQUALIFIER_MIDBUTTON
;
1234 if (DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
1235 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
1237 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= MIDDLEDOWN
)
1239 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1240 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
1242 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
1244 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
1245 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1247 /* update last click time for doubleclicktofront */
1248 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
1249 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
1253 iihdata
->ActQualifier
&= ~IEQUALIFIER_MIDBUTTON
;
1258 iihdata
->TitlebarAppearTime
= 0;
1262 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1263 *keep_event
= FALSE
;
1268 if (ie
->ie_Code
== MIDDLEDOWN
)
1272 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
1274 if (result
== RUNHOTREUSE
)
1276 *reuse_event
= TRUE
;
1280 *keep_event
= FALSE
;
1284 w
= IntuitionBase
->ActiveWindow
;
1289 if (IS_BOOPSI_GADGET(gadget
))
1291 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
1294 } /* if (there is an active gadget) */
1295 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && w
!= GetPrivScreen(w
->WScreen
)->MenuVerifyActiveWindow
)
1297 ih_fire_intuimessage(w
,
1304 break; /* case MENUDOWN */
1306 case IECODE_NOBUTTON
: /* MOUSEMOVE */
1309 UWORD DWidth
, DHeight
;
1311 if (ie
->ie_Qualifier
& IEQUALIFIER_RELATIVEMOUSE
) {
1314 /* Add delta information lost in previous mousemove event. See below. */
1315 iihdata
->DeltaMouseX
= ie
->ie_X
+ iihdata
->DeltaMouseX_Correction
;
1316 iihdata
->DeltaMouseY
= ie
->ie_Y
+ iihdata
->DeltaMouseY_Correction
;
1318 #define ACCELERATOR_THRESH 2
1319 #define ACCELERATOR_MULTI 2
1321 if (GetPrivIBase(IntuitionBase
)->ActivePreferences
.EnableCLI
& MOUSE_ACCEL
)
1324 if (ABS(iihdata
->DeltaMouseX
) > ACCELERATOR_THRESH
)
1325 iihdata
->DeltaMouseX
*= ACCELERATOR_MULTI
;
1326 if (ABS(iihdata
->DeltaMouseY
) > ACCELERATOR_THRESH
)
1327 iihdata
->DeltaMouseY
*= ACCELERATOR_MULTI
;
1330 switch (GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
)
1333 iihdata
->DeltaMouseX_Correction
= 0;
1334 iihdata
->DeltaMouseX_Correction
= 0;
1338 /* Remember the delta information which gets lost because of division by PointerTicks.
1339 Will be added to prescaled deltas of next mousemove event. If this is not done, moving
1340 the mouse very slowly would cause it to not move at all */
1342 iihdata
->DeltaMouseX_Correction
= iihdata
->DeltaMouseX
% GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1343 iihdata
->DeltaMouseY_Correction
= iihdata
->DeltaMouseY
% GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1345 iihdata
->DeltaMouseX
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1346 iihdata
->DeltaMouseY
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
.PointerTicks
;
1351 ie
->ie_X
= iihdata
->DeltaMouseX
+ IntuitionBase
->MouseX
;
1352 ie
->ie_Y
= iihdata
->DeltaMouseY
+ IntuitionBase
->MouseY
;
1354 DEBUG_MOUSE(bug("[Inputhandler] Last mouse position: (%d, %d), new mouse position: (%d, %d)\n",
1355 IntuitionBase
->MouseX
, IntuitionBase
->MouseY
, ie
->ie_X
, ie
->ie_Y
));
1356 iihdata
->DeltaMouseX
= ie
->ie_X
- IntuitionBase
->MouseX
;
1357 iihdata
->DeltaMouseY
= ie
->ie_Y
- IntuitionBase
->MouseY
;
1358 DEBUG_MOUSE(bug("[InputHandler] Delta is (%d, %d)\n", iihdata
->DeltaMouseX
, iihdata
->DeltaMouseY
));
1361 /* Calculate current display size.
1362 It's determined by the first screen on this monitor.
1363 TODO: perhaps we should just ask display driver about its current display mode? */
1364 scr
= FindFirstScreen(GetPrivIBase(IntuitionBase
)->ActiveMonitor
, IntuitionBase
);
1367 DWidth
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxX
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinX
+ 1;
1368 DHeight
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxY
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinY
+ 1;
1372 /* If there's no active screen, we take 160x160 as a limit */
1377 scr
= iihdata
->ScreenDrag
;
1379 WORD dx
= iihdata
->DeltaMouseX
;
1380 WORD dy
= iihdata
->DeltaMouseY
;
1382 UWORD spFlags
= GetPrivScreen(scr
)->SpecialFlags
;
1383 UWORD DragMode
= GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_VDragModes
[0];
1385 DEBUG_DRAG(bug("[InputHandler] Screen drag, delta is (%d, %d)\n", dx
, dy
));
1387 /* Restrict dragging to a physical display area if the driver does not allow composition or if the user wants it*/
1388 if (((spFlags
& SF_HorCompose
) != SF_HorCompose
) || (DragMode
& ICVDM_HBOUND
)) {
1389 /* Calculate limits */
1390 if (scr
->Width
> DWidth
) {
1391 min
= DWidth
- scr
->Width
;
1395 max
= DWidth
- scr
->Width
;
1397 /* The purpose of the following complex check is to prevent jumping if the
1398 screen was positioned out of user drag limits by the program itself using
1399 ScreenPosition() or OpenScreen(). We apply restrictions in parts depending
1400 on the dragging direction.
1401 Maybe the user should also be able to drag the screen back off-display in such
1403 Calculate the position we would go to */
1404 val
= scr
->LeftEdge
+ dx
;
1405 /* Determine the direction */
1406 if ((dx
< 0) && ((!(spFlags
& SF_ComposeRight
)) || (DragMode
& ICVDM_LBOUND
))) {
1407 /* Can we move at all in this direction ? */
1408 if (scr
->LeftEdge
> min
) {
1409 /* If too far, restrict it */
1411 dx
= min
- scr
->LeftEdge
;
1413 /* Just don't move if we can't */
1415 } else if ((!(spFlags
& SF_ComposeLeft
)) || (DragMode
& ICVDM_RBOUND
)) {
1416 if (scr
->LeftEdge
< max
) {
1418 dx
= max
- scr
->LeftEdge
;
1423 if (((spFlags
& SF_VertCompose
) != SF_VertCompose
) || (DragMode
& ICVDM_VBOUND
)) {
1424 DEBUG_DRAG(bug("[Inputhandler] Restricting vertical drag\n"));
1425 DEBUG_DRAG(bug("[Inputhandler] Screen size: %d, display size: %d\n", scr
->Height
, DHeight
));
1426 if (scr
->Height
> DHeight
) {
1427 min
= DHeight
- scr
->Height
;
1431 max
= DHeight
- scr
->Height
;
1433 DEBUG_DRAG(bug("[Inputhandler] Limits: min %d max %d\n", min
, max
));
1434 val
= scr
->TopEdge
+ dy
;
1435 DEBUG_DRAG(bug("[Inputhandler] New position would be %d\n", val
));
1436 if ((dy
< 0) && ((!(spFlags
& SF_ComposeBelow
)) || (DragMode
& ICVDM_TBOUND
))) {
1437 if (scr
->TopEdge
> min
) {
1439 dy
= min
- scr
->TopEdge
;
1442 } else if ((!(spFlags
& SF_ComposeAbove
)) || (DragMode
& ICVDM_BBOUND
)) {
1443 if (scr
->TopEdge
< max
) {
1445 dy
= max
- scr
->TopEdge
;
1449 DEBUG_DRAG(bug("[Inputhandler] Restricted delta will be %d\n", dy
));
1451 ScreenPosition(scr
, SPOS_RELATIVE
, dx
, dy
, 0, 0);
1454 /* Autoscroll the active screen */
1455 scr
= IntuitionBase
->ActiveScreen
;
1456 if (scr
&& (scr
->Flags
& AUTOSCROLL
) &&
1457 (GetPrivScreen(scr
)->IMonitorNode
== GetPrivIBase(IntuitionBase
)->ActiveMonitor
))
1459 WORD xval
= scr
->LeftEdge
;
1460 WORD yval
= scr
->TopEdge
;
1463 DEBUG_AUTOSCROLL(bug("[Inputhandler] Autoscroll screen 0x%p, event at (%d, %d)\n",
1464 scr
, ie
->ie_X
, ie
->ie_Y
));
1466 if ((ie
->ie_X
< 0) || (ie
->ie_X
>= DWidth
)) {
1467 DEBUG_AUTOSCROLL(bug("[InputHandler] X delta: %d pixels\n", iihdata
->DeltaMouseX
));
1468 xval
-= iihdata
->DeltaMouseX
;
1473 } else if (ie
->ie_X
>= DWidth
) {
1474 min
= DWidth
- scr
->Width
;
1480 if ((ie
->ie_Y
< 0) || (ie
->ie_Y
>= DHeight
)) {
1481 yval
-= iihdata
->DeltaMouseY
;
1484 /* If screen is dragged down and user touched upper screen
1485 boundary, do nothing */
1486 if (scr
->TopEdge
>= 0)
1487 yval
= scr
->TopEdge
;
1489 /* If scrolled down screen is being scrolled up, make sure it
1490 does not go over 0 */
1493 } else if (ie
->ie_Y
>= DHeight
) {
1494 min
= DHeight
- scr
->Height
;
1500 if ((xval
!= scr
->LeftEdge
) || (yval
!= scr
->TopEdge
))
1501 ScreenPosition(scr
, SPOS_ABSOLUTE
, xval
, yval
, 0, 0);
1504 /* Restrict mouse coordinates to the physical display area */
1505 if (ie
->ie_X
>= DWidth
) ie
->ie_X
= DWidth
- 1;
1506 if (ie
->ie_Y
>= DHeight
) ie
->ie_Y
= DHeight
- 1;
1507 if (ie
->ie_X
< 0) ie
->ie_X
= 0;
1508 if (ie
->ie_Y
< 0) ie
->ie_Y
= 0;
1511 if (gadget
== iihdata
->MasterDragGadget
) {
1515 gpi
.MethodID
= GM_MOVETEST
;
1517 gpi
.gpi_Mouse
.X
= ie
->ie_X
- gi
->gi_Window
->WScreen
->LeftEdge
;
1518 gpi
.gpi_Mouse
.Y
= ie
->ie_Y
- gi
->gi_Window
->WScreen
->TopEdge
;
1519 gpi
.gpi_IEvent
= ie
;
1521 retval
= Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpi
, IntuitionBase
);
1522 if (retval
== MOVETEST_ADJUSTPOS
)
1524 ie
->ie_X
= gpi
.gpi_Mouse
.X
+ gi
->gi_Window
->WScreen
->LeftEdge
;
1525 ie
->ie_Y
= gpi
.gpi_Mouse
.Y
+ gi
->gi_Window
->WScreen
->TopEdge
;
1530 /* Do Mouse Bounding - mouse will be most restrictive of screen size or mouse bounds */
1531 if (iihdata
->MouseBoundsActiveFlag
) {
1532 if (ie
->ie_X
< iihdata
->MouseBoundsLeft
)
1533 ie
->ie_X
= iihdata
->MouseBoundsLeft
;
1534 else if (ie
->ie_X
> iihdata
->MouseBoundsRight
)
1535 ie
->ie_X
= iihdata
->MouseBoundsRight
;
1537 if (ie
->ie_Y
< iihdata
->MouseBoundsTop
)
1538 ie
->ie_Y
= iihdata
->MouseBoundsTop
;
1539 else if (ie
->ie_Y
> iihdata
->MouseBoundsBottom
)
1540 ie
->ie_Y
= iihdata
->MouseBoundsBottom
;
1543 /* Prevent mouse going above all screens */
1544 scr
= FindHighestScreen(IntuitionBase
);
1546 if (ie
->ie_Y
< scr
->TopEdge
)
1547 ie
->ie_Y
= scr
->TopEdge
;
1550 /* Store new mouse coords. If a screen is being dragged, lock drag point */
1551 scr
= iihdata
->ScreenDrag
;
1553 IntuitionBase
->MouseX
= scr
->LeftEdge
+ iihdata
->ScreenDragPointX
;
1554 IntuitionBase
->MouseY
= scr
->TopEdge
+ iihdata
->ScreenDragPointY
;
1556 IntuitionBase
->MouseX
= ie
->ie_X
;
1557 IntuitionBase
->MouseY
= ie
->ie_Y
;
1559 notify_mousemove_screensandwindows(IntuitionBase
);
1560 #if !SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1561 MySetPointerPos(IntuitionBase
);
1563 *call_setpointerpos
= TRUE
;
1566 screen
= FindActiveScreen(IntuitionBase
); /* The mouse was moved, so current screen may have changed */
1570 if (iihdata
->TitlebarOnTop
)
1572 if (screen
->MouseY
> screen
->BarHeight
&& GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
)
1574 iihdata
->TitlebarOnTop
= FALSE
;
1575 iihdata
->TitlebarAppearTime
= 0;
1577 LOCK_REFRESH(screen
);
1579 MoveLayer(0, screen
->BarLayer
, 0, -(screen
->BarHeight
+ 1));
1580 CheckLayers(screen
, IntuitionBase
);
1582 UNLOCK_REFRESH(screen
);
1587 if (screen
->MouseY
== 0 && GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
&& !MENUS_ACTIVE
&& !(PeekQualifier() & (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_RBUTTON
|IEQUALIFIER_MIDBUTTON
)))
1589 if (!(iihdata
->TitlebarAppearTime
))
1591 iihdata
->TitlebarAppearTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1592 iihdata
->TitlebarAppearTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1597 iihdata
->TitlebarAppearTime
= 0;
1603 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1604 *keep_event
= FALSE
;
1609 *keep_event
= FALSE
;
1611 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
1613 case GTYP_BOOLGADGET
:
1614 case 0: //fallback for sucky gadgets
1615 /* Must be a RELVERIFY gadget */
1619 inside
= InsideGadget(gi
->gi_Screen
,
1623 gi
->gi_Screen
->MouseX
,
1624 gi
->gi_Screen
->MouseY
);
1626 if (inside
!= iihdata
->MouseWasInsideBoolGadget
) {
1627 iihdata
->MouseWasInsideBoolGadget
= inside
;
1629 gadget
->Flags
^= GFLG_SELECTED
;
1630 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
1635 case GTYP_PROPGADGET
:
1636 HandlePropMouseMove(gadget
,
1639 w
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
1640 w
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
1645 case GTYP_CUSTOMGADGET
:
1646 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
1649 } /* switch GadgetType */
1651 } /* if (a gadget is currently active) */
1653 *keep_event
= FALSE
;
1658 if (IW(w
)->helpflags
& HELPF_GADGETHELP
&& (!(PeekQualifier() & (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_RBUTTON
|IEQUALIFIER_MIDBUTTON
)))) {
1662 hw
= FindActiveWindow(ie
, screen
, 0, IntuitionBase
);
1665 (!hw
|| !(IW(w
)->helpflags
& HELPF_ISHELPGROUP
) ||
1666 !(IW(hw
)->helpflags
& HELPF_ISHELPGROUP
) ||
1667 IW(w
)->helpgroup
!= IW(hw
)->helpgroup
))
1670 if (iihdata
->LastHelpWindow
)
1672 fire_intuimessage(w
,
1678 iihdata
->LastHelpGadget
= NULL
;
1679 iihdata
->LastHelpWindow
= NULL
;
1680 iihdata
->HelpGadgetFindTime
= 0;
1685 g
= FindHelpGadget (hw
,
1686 IntuitionBase
->ActiveScreen
->MouseX
,
1687 IntuitionBase
->ActiveScreen
->MouseY
,
1689 if (g
&& g
!= iihdata
->LastHelpGadget
)
1691 if (!iihdata
->LastHelpGadget
)
1693 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1694 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1696 if (hw
== iihdata
->LastHelpWindow
)
1698 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1699 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1700 iihdata
->HelpGadgetFindTime
+= 25;//smaller delay
1704 else if (g
!= iihdata
->LastHelpGadget
||
1705 hw
!= iihdata
->LastHelpWindow
)
1707 fire_intuimessage(hw
,
1709 0, /* Don't know what it should be */
1714 iihdata
->LastHelpGadget
= g
;
1715 iihdata
->LastHelpWindow
= hw
;
1718 iihdata
->LastHelpGadget
= NULL
;
1719 iihdata
->LastHelpWindow
= NULL
;
1720 iihdata
->HelpGadgetFindTime
= 0;
1723 if (!(w
->IDCMPFlags
& IDCMP_MOUSEMOVE
))
1726 /* Send IDCMP_MOUSEMOVE if WFLG_REPORTMOUSE is set
1727 and/or active gadget has GACT_FOLLOWMOUSE set */
1729 /* jDc: do NOT send when sizegad is pressed */
1730 if (!(w
->Flags
& WFLG_REPORTMOUSE
)) {
1733 if (!(gadget
->Activation
& GACT_FOLLOWMOUSE
))
1736 if (gadget
&& (gadget
->GadgetType
& (GTYP_SIZING
|GTYP_WDRAGGING
)))
1740 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
1742 /* Limit the number of IDCMP_MOUSEMOVE messages sent to intuition.
1743 note that this comes after handling gadgets, because gadgets should get all events.
1746 if (IW(w
)->num_mouseevents
>= IW(w
)->mousequeue
) {
1747 BOOL old_msg_found
= FALSE
;
1749 /* Mouse Queue is full, so try looking for a not
1750 yet GetMsg()ed IntuiMessage in w->UserPort
1751 trying to modify that. */
1756 struct IntuiMessage
*im
;
1758 //TODO: __AROSEXEC_SMP_ should spinlock protect access...
1759 for (im
= (struct IntuiMessage
*)w
->UserPort
->mp_MsgList
.lh_TailPred
;
1760 im
->ExecMessage
.mn_Node
.ln_Pred
;
1761 im
= (struct IntuiMessage
*)im
->ExecMessage
.mn_Node
.ln_Pred
)
1763 if ((im
->Class
== IDCMP_MOUSEMOVE
) &&
1764 (im
->IDCMPWindow
== w
))
1766 im
->Qualifier
= iihdata
->ActQualifier
;
1768 if (w
->IDCMPFlags
& IDCMP_DELTAMOVE
)
1770 im
->MouseX
= iihdata
->DeltaMouseX
;
1771 im
->MouseY
= iihdata
->DeltaMouseY
;
1775 im
->MouseX
= w
->MouseX
;
1776 im
->MouseY
= w
->MouseY
;
1778 CurrentTime(&im
->Seconds
, &im
->Micros
);
1780 old_msg_found
= TRUE
;
1784 } /* if (w->UserPort) */
1787 /* no need to send a new message if we modified
1788 an existing one ... */
1790 if (old_msg_found
) break;
1792 /* ... otherwise we are in a strange situation. The mouse
1793 queue is full, but we did not find an existing MOUSEMOVE
1794 imsg in w->UserPort. So the app probably has removed
1795 an imsg from the UserPort with GetMsg but we did not get
1796 the ReplyMsg, yet. In this case we do send a new message */
1798 HandleIntuiReplyPort(iihdata
, IntuitionBase
);
1802 /* MouseQueue is not full, so we can send a message. We increase
1803 IntWindow->num_mouseevents which will later be decreased after
1804 the Intuition InputHandler gets the ReplyMessage from the app
1805 and handles it in HandleIntuiReplyPort() */
1807 if (ih_fire_intuimessage(w
, IDCMP_MOUSEMOVE
, IECODE_NOBUTTON
, w
, IntuitionBase
))
1808 IW(w
)->num_mouseevents
++;
1812 } /* case IECODE_NOBUTTON */
1813 } /* switch (ie->ie_Code) (what button was pressed ?) */
1818 /****************************************************************************************/
1820 AROS_UFH2(struct InputEvent
*, IntuiInputHandler
,
1821 AROS_UFHA(struct InputEvent
*, oldchain
, A0
),
1822 AROS_UFHA(struct IIHData
*, iihdata
, A1
)
1827 struct InputEvent
*ie
, *orig_ie
, *next_ie
, stackie
;
1828 struct Gadget
*gadget
= NULL
;
1829 struct IntuitionBase
*IntuitionBase
= iihdata
->IntuitionBase
;
1830 struct Library
*KeymapBase
= GetPrivIBase(IntuitionBase
)->KeymapBase
;
1831 struct Screen
*screen
;
1833 struct GadgetInfo
*gi
= &iihdata
->GadgetInfo
;
1834 BOOL reuse_event
, ie_used
;
1836 struct Requester
*req
;
1837 ULONG stitlebarhit
= 0;
1838 #if 0 /* Toolbox is broken-as-designed */
1839 struct Window
*toolbox
;
1840 struct GadgetInfo
*boxgi
= &iihdata
->BoxGadgetInfo
;
1841 struct Gadget
*boxgadget
= NULL
;
1843 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1844 BOOL call_setpointerpos
= FALSE
;
1847 D(bug("Inside intuition inputhandler, active window=%p\n", IntuitionBase
->ActiveWindow
));
1848 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->InputHandlerLock
);
1850 if (!iihdata
->InputDeviceTask
) iihdata
->InputDeviceTask
= FindTask(NULL
);
1852 /* Then free generated InputEvents done in the previous round */
1854 FreeGeneratedInputEvents(iihdata
);
1856 /* First handle IntuiMessages which were replied back to the IntuiReplyPort
1859 HandleIntuiReplyPort(iihdata
, IntuitionBase
);
1861 /* Handle action messages */
1863 HandleIntuiActions(iihdata
, IntuitionBase
);
1865 /* Now handle the input events */
1868 reuse_event
= FALSE
;
1871 /* shut up the compiler */
1875 gadget
= iihdata
->ActiveGadget
;
1877 while (reuse_event
|| next_ie
)
1879 struct Window
*old_w
;
1880 BOOL keep_event
= TRUE
;
1881 BOOL new_active_window
= FALSE
;
1882 Object
*newmonitor
= GetPrivIBase(IntuitionBase
)->NewMonitor
;
1884 /* Process hosted display activation event (if any).
1885 This is experimental. If this works badly, we'll possibly have to put it into
1886 input events queue */
1888 DEBUG_MONITOR(bug("[Inputhandler] Activating monitor 0x%p\n", newmonitor
));
1889 GetPrivIBase(IntuitionBase
)->NewMonitor
= NULL
;
1890 ActivateMonitor(newmonitor
, -1, -1, IntuitionBase
);
1891 iihdata
->SwitchedMonitor
= TRUE
;
1898 next_ie
= ie
->ie_NextEvent
;
1902 D(bug("iih: Handling event of class %d, code %d\n", ie
->ie_Class
, ie
->ie_Code
));
1903 reuse_event
= FALSE
;
1905 /* If the monitor has been changed, this possibly happened because of mouse click in
1906 its display window. In such a case we have to update current mouse coordinates
1907 from the first absolute mouse event. Otherwise input will misbehave. */
1908 if (iihdata
->SwitchedMonitor
&& (ie
->ie_Class
== IECLASS_RAWMOUSE
)) {
1909 iihdata
->SwitchedMonitor
= FALSE
;
1910 if (!(ie
->ie_Qualifier
& IEQUALIFIER_RELATIVEMOUSE
)) {
1911 DEBUG_MONITOR(bug("[Inputhandler] Adjusting coordinates to (%d, %d)\n", ie
->ie_X
, ie
->ie_Y
));
1912 IntuitionBase
->MouseX
= ie
->ie_X
;
1913 IntuitionBase
->MouseY
= ie
->ie_Y
;
1914 notify_mousemove_screensandwindows(IntuitionBase
);
1918 /* new event, we need to reset this */
1919 screen
= FindActiveScreen(IntuitionBase
);
1920 iihdata
->ActEventTablet
= 0;
1922 /* Set the timestamp in IntuitionBase */
1924 IntuitionBase
->Seconds
= ie
->ie_TimeStamp
.tv_secs
;
1925 IntuitionBase
->Micros
= ie
->ie_TimeStamp
.tv_micro
;
1927 #if 0 /* toolbox stuff disabled. broken. calling LockLayerinfo() for every event is broken. deadlocks */
1928 /* Use event to find the active window */
1930 toolbox
= GetToolBoxWindow(ie
, screen
, IntuitionBase
);
1934 /* Do ToolBox Window Actions */
1935 /* ToolBox Windows supports only a subset of IECLASS Actions */
1936 switch (ie
->ie_Class
) {
1938 case IECLASS_RAWMOUSE
:
1939 boxgadget
= Process_RawMouse(ie
, iihdata
, screen
, toolbox
, boxgadget
, boxgi
, 0, FALSE
, TRUE
,
1940 orig_ie
, &keep_event
, &reuse_event
,
1941 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1942 &call_setpointerpos
,
1947 } /* switch (ie->ie_Class) */
1948 } /* if (toolbox) */
1951 w
= IntuitionBase
->ActiveWindow
;
1953 if (!MENUS_ACTIVE
&& !SYSGADGET_ACTIVE
)
1955 /* lock = LockIBase(0UL); */
1958 if (ie
->ie_Class
== IECLASS_RAWMOUSE
&& ie
->ie_Code
== SELECTDOWN
)
1960 w
= FindActiveWindow(ie
, screen
, &stitlebarhit
, IntuitionBase
);
1961 DEBUG_CLICK(bug("iih:New active window: %p\n", w
));
1969 DEBUG_WINDOW(bug("Activating new window (title %s)\n", w
->Title
? w
->Title
: "<noname>"));
1971 DEBUG_WINDOW(bug("Window activated\n"));
1975 DEBUG_WINDOW(bug("Making active window inactive. Now there's no active window\n"));
1977 new_active_window
= TRUE
;
1978 iihdata
->NewActWindow
= w
;
1981 /* UnlockIBase(lock); */
1983 if (new_active_window
)
1986 (!(GetPrivScreen(w
->WScreen
)->MenuVerifyMsgCount
)) &&
1987 (!(MENUS_ACTIVE
)) && (!(SYSGADGET_ACTIVE
)))
1989 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
1992 case GTYP_CUSTOMGADGET
:
1994 struct gpGoInactive gpgi
;
1996 gpgi
.MethodID
= GM_GOINACTIVE
;
1997 gpgi
.gpgi_GInfo
= gi
;
1998 gpgi
.gpgi_Abort
= 1;
2000 Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpgi
, IntuitionBase
);
2004 case GTYP_STRGADGET
:
2005 gadget
->Flags
&= ~GFLG_SELECTED
;
2006 RefreshStrGadget(gadget
, gi
->gi_Window
, gi
->gi_Requester
, IntuitionBase
);
2009 case GTYP_BOOLGADGET
:
2010 /* That a bool gadget is active here can only happen
2011 if user used LMB to activate gadget and LAMIGA + LALT
2012 to activate other window, or viceversa */
2013 /* The gadget must be a RELVERIFY one */
2014 if (!(gadget
->Activation
& GACT_TOGGLESELECT
))
2018 inside
= InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
2019 gi
->gi_Requester
, gadget
,
2020 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
);
2024 gadget
->Flags
&= ~GFLG_SELECTED
;
2025 RefreshBoolGadgetState(gadget
, gi
->gi_Window
,
2026 gi
->gi_Requester
, IntuitionBase
);
2031 case GTYP_PROPGADGET
:
2032 /* That a prop gadget is active here can only happen
2033 if user used LMB to activate gadget and LAMIGA + LALT
2034 to activate other window, or viceversa */
2036 HandlePropSelectUp(gadget
, gi
->gi_Window
, NULL
, IntuitionBase
);
2037 if (gadget
->Activation
& GACT_RELVERIFY
)
2039 ih_fire_intuimessage(gi
->gi_Window
,
2047 } /* switch (gadget->GadgetType & GTYP_GTYPEMASK) */
2049 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
2050 iihdata
->ActiveGadget
= NULL
;
2054 /* ActivateWindow works if w = NULL */
2055 /* jacaDcaps: some gui toolkits (die reaction, die!) close the window opened by a boopsi gadget when
2056 it gets hit with lmb, so we need to check if the new active window does not go away by
2057 performing GM_GOINACTIVE on the gadget. NOTE: CloseWindow's part performed on input.device context
2058 clears the iihdata->NewActWindow if it's the actually closed one. */
2059 if (w
== iihdata
->NewActWindow
)
2065 w
= IntuitionBase
->ActiveWindow
;
2066 new_active_window
= FALSE
;
2067 ie
->ie_Class
= IECLASS_NULL
; //lose the event, otherwise the gadget will get activated again ;)
2070 iihdata
->NewActWindow
= 0;
2072 } /* if (new_active_window) */
2074 } /* if (!MENUS_ACTIVE) */
2079 req
= w
->FirstRequest
;
2082 D(bug("[Inputhandler] Screen 0x%p Window 0x%p Requester 0x%p gadget 0x%p\n", screen
, w
, req
, gadget
));
2084 switch (ie
->ie_Class
) {
2085 case IECLASS_POINTERPOS
:
2086 ie
->ie_SubClass
= IESUBCLASS_COMPATIBLE
;
2089 case IECLASS_NEWPOINTERPOS
:
2090 switch (ie
->ie_SubClass
)
2092 case IESUBCLASS_COMPATIBLE
:
2093 ie
->ie_Code
= IECODE_NOBUTTON
;
2096 case IESUBCLASS_PIXEL
:
2098 struct IEPointerPixel
*pp
= ie
->ie_EventAddress
;
2100 ie
->ie_X
= pp
->iepp_Position
.X
+ pp
->iepp_Screen
->LeftEdge
;
2101 ie
->ie_Y
= pp
->iepp_Position
.Y
+ pp
->iepp_Screen
->TopEdge
;
2103 ActivateMonitor(GetPrivScreen(pp
->iepp_Screen
)->IMonitorNode
, ie
->ie_X
, ie
->ie_Y
, IntuitionBase
);
2105 ie
->ie_Class
= IECLASS_RAWMOUSE
; /* otherwise a lot of code would ignore this message */
2106 ie
->ie_Code
= IECODE_NOBUTTON
;
2109 case IESUBCLASS_TABLET
:
2111 //unsupported - does anything use it anyway? ;)
2116 case IESUBCLASS_NEWTABLET
:
2118 struct IENewTablet
*nt
= (struct IENewTablet
*)ie
->ie_EventAddress
;
2122 iihdata
->ActEventTablet
= nt
; //cache this
2123 ie
->ie_X
= (screen
->Width
* nt
->ient_TabletX
) / nt
->ient_RangeX
;
2124 ie
->ie_Y
= (screen
->Height
* nt
->ient_TabletY
) / nt
->ient_RangeY
;
2126 ie
->ie_Class
= IECLASS_RAWMOUSE
;
2136 case IECLASS_RAWMOUSE
:
2137 gadget
= Process_RawMouse(ie
, iihdata
, screen
, w
, gadget
, gi
, stitlebarhit
, new_active_window
, FALSE
,
2138 orig_ie
, &keep_event
, &reuse_event
,
2139 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
2140 &call_setpointerpos
,
2146 case IECLASS_RAWKEY
:
2147 /* release events go only to gadgets and windows who
2148 have not set IDCMP_VANILLAKEY */
2150 DEBUG_HANDLER(dprintf("Handler: IECLASS_RAWKEY\n"));
2151 DEBUG_KEY(dprintf("Handler: Qual 0x%lx\n",iihdata
->ActQualifier
));
2153 iihdata
->ActQualifier
&= ~(KEY_QUALIFIERS
| IEQUALIFIER_REPEAT
);
2154 iihdata
->ActQualifier
|= (ie
->ie_Qualifier
& (KEY_QUALIFIERS
| IEQUALIFIER_REPEAT
));
2156 DEBUG_KEY(dprintf("Handler: real Qual 0x%lx\n",iihdata
->ActQualifier
));
2158 /* Keyboard mouse emulation and screen switching */
2161 UWORD code
= ie
->ie_Code
& ~IECODE_UP_PREFIX
;
2162 DEBUG_KEY(dprintf("Handler: code 0x%lx\n",code
));
2164 /* Left Amiga + N/M screen switching shortcut */
2165 if ((ie
->ie_Qualifier
& IEQUALIFIER_LCOMMAND
) && (code
== RAWKEY_N
|| code
== RAWKEY_M
)) {
2166 if (!(ie
->ie_Qualifier
& IEQUALIFIER_REPEAT
) && !(ie
->ie_Code
& IECODE_UP_PREFIX
)) {
2167 if (code
== RAWKEY_N
)
2169 else if (code
== RAWKEY_M
)
2170 ScreenToBack(IntuitionBase
->FirstScreen
);
2176 /* Mouse button emulation: LALT + LAMIGA = LBUTTON, RALT + RAMIGA = RBUTTON */
2177 if ((code
== RAWKEY_LAMIGA
) ||
2178 (code
== RAWKEY_LALT
) ||
2179 (code
== RAWKEY_RAMIGA
) ||
2180 (code
== RAWKEY_RALT
))
2182 DEBUG_KEY(dprintf("Handler: KeyMouseEmul\n"));
2183 iihdata
->PrevKeyMouseState
= iihdata
->ActKeyMouseState
;
2184 iihdata
->ActKeyMouseState
= 0;
2185 if ((ie
->ie_Qualifier
& (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_LALT
)) == (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_LALT
))
2187 iihdata
->ActKeyMouseState
|= IEQUALIFIER_LEFTBUTTON
;
2189 if ((ie
->ie_Qualifier
& (IEQUALIFIER_RCOMMAND
| IEQUALIFIER_RALT
)) == (IEQUALIFIER_RCOMMAND
| IEQUALIFIER_RALT
))
2191 iihdata
->ActKeyMouseState
|= IEQUALIFIER_RBUTTON
;
2194 if ((iihdata
->ActKeyMouseState
& IEQUALIFIER_LEFTBUTTON
) != (iihdata
->PrevKeyMouseState
& IEQUALIFIER_LEFTBUTTON
))
2196 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2197 orig_ie
->ie_SubClass
= 0;
2198 orig_ie
->ie_Code
= (iihdata
->ActKeyMouseState
& IEQUALIFIER_LEFTBUTTON
) ? IECODE_LBUTTON
: IECODE_LBUTTON
| IECODE_UP_PREFIX
;
2207 if ((iihdata
->ActKeyMouseState
& IEQUALIFIER_RBUTTON
) != (iihdata
->PrevKeyMouseState
& IEQUALIFIER_RBUTTON
))
2209 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2210 orig_ie
->ie_SubClass
= 0;
2211 orig_ie
->ie_Code
= (iihdata
->ActKeyMouseState
& IEQUALIFIER_RBUTTON
) ? IECODE_RBUTTON
: IECODE_RBUTTON
| IECODE_UP_PREFIX
;
2220 } /* if key is one of LAMIGA/LALT/RAMIGA/RALT */
2222 if ((iihdata
->ActQualifier
& (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_RCOMMAND
)) &&
2223 ((ie
->ie_Code
== RAWKEY_UP
) ||
2224 (ie
->ie_Code
== RAWKEY_DOWN
) ||
2225 (ie
->ie_Code
== RAWKEY_LEFT
) ||
2226 (ie
->ie_Code
== RAWKEY_RIGHT
)))
2228 static BYTE
const xmap
[] = { 0, 0, 1, -1};
2229 static BYTE
const ymap
[] = {-1, 1, 0, 0};
2232 shift
= (iihdata
->ActQualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) ? 40 : 1;
2234 /* Mouse Move Emulation */
2236 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2237 orig_ie
->ie_SubClass
= 0;
2238 orig_ie
->ie_Code
= IECODE_NOBUTTON
;
2239 orig_ie
->ie_Qualifier
= IEQUALIFIER_RELATIVEMOUSE
;
2240 orig_ie
->ie_X
= xmap
[code
- RAWKEY_UP
] * shift
;
2241 orig_ie
->ie_Y
= ymap
[code
- RAWKEY_UP
] * shift
;
2250 /* End Keyboard mouse emulation */
2254 DEBUG_KEY(dprintf("Handler: FireMenuMessage\n"));
2255 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2260 /* Hotkeys processing */
2265 if (!(ie
->ie_Code
& IECODE_UP_PREFIX
))
2266 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
2268 if (result
== RUNHOTREUSE
)
2278 w
= IntuitionBase
->ActiveWindow
;
2283 ((!(ie
->ie_Code
& IECODE_UP_PREFIX
)) ||
2285 (w
&& ((w
->IDCMPFlags
& IDCMP_VANILLAKEY
) == 0)) ))
2291 DEBUG_KEY(dprintf("Handler: Gadget 0x%lx active\n",gadget
));
2292 DEBUG_KEY(dprintf("Handler: GadgetID 0x%lx UserData 0x%lx\n",
2295 DEBUG_KEY(dprintf("Handler: GadgetType 0x%lx Flags 0x%lx Activation 0x%lx\n",
2298 gadget
->Activation
));
2299 DEBUG_KEY(dprintf("Handler: MoreFlags 0x%lx\n",
2300 ((struct ExtGadget
*)gadget
)->MoreFlags
));
2302 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
2304 case GTYP_STRGADGET
:
2307 ULONG ret
= HandleStrInput(gadget
, gi
, ie
, &imsgcode
,
2310 DEBUG_KEY(dprintf("Handler: Key GTYP_STRGADGET ret 0x%lx\n",ret
));
2311 if (ret
& (SGA_END
| SGA_NEXTACTIVE
| SGA_PREVACTIVE
))
2313 if (gadget
->Activation
& GACT_RELVERIFY
)
2315 DEBUG_KEY(dprintf("Handler: GACT_RELVERIFY\n"));
2316 ih_fire_intuimessage(w
,
2322 if (req
&& gadget
->Activation
& GACT_ENDGADGET
)
2324 DEBUG_KEY(dprintf("Handler: GACT_ENDGADGET\n"));
2327 req
= w
->FirstRequest
;
2332 if ((gadget
->Flags
& GFLG_TABCYCLE
) && (ret
& SGA_NEXTACTIVE
))
2334 gadget
= FindCycleGadget(w
, req
, gadget
, GMR_NEXTACTIVE
);
2335 DEBUG_KEY(dprintf("Handler: TabCycle next gadget 0x%lx\n",gadget
));
2337 else if ((gadget
->Flags
& GFLG_TABCYCLE
) && (ret
& SGA_PREVACTIVE
))
2339 gadget
= FindCycleGadget(w
, req
, gadget
, GMR_PREVACTIVE
);
2340 DEBUG_KEY(dprintf("Handler: TabCycle prev gadget 0x%lx\n",gadget
));
2349 gadget
= DoActivateGadget(w
, req
, gadget
, IntuitionBase
);
2352 } /* if (ret & (SGA_END | SGA_NEXTACTIVE | SGA_PREVACTIVE)) */
2357 case GTYP_CUSTOMGADGET
:
2358 DEBUG_KEY(dprintf("Handler: GTYP_CUSTOMGADGET\n"));
2359 DEBUG_KEY(dprintf("Handler: send GM_HANDLEINPUT\n"));
2360 gadget
= DoGPInput(gi
,
2366 DEBUG_KEY(dprintf("Handler: reuse %ld\n",reuse_event
));
2369 } /* switch (gadget type) */
2371 } /* if (a gadget is currently active) */
2372 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
))
2374 BOOL menushortcut
= FALSE
;
2376 DEBUG_KEY(dprintf("Handler: No Gadget active\n"));
2377 DEBUG_KEY(dprintf("Handler: Qualifier 0x%lx WinFlags 0x%lx IDCMP 0x%lx\n",ie
->ie_Qualifier
,w
->Flags
,w
->IDCMPFlags
));
2379 if ((ie
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
) &&
2380 (!(w
->Flags
& WFLG_RMBTRAP
)) &&
2381 (w
->IDCMPFlags
& IDCMP_MENUPICK
))
2383 struct Menu
*strip
= 0;
2385 DEBUG_KEY(dprintf("Handler: MenuKey\n"));
2386 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2388 strip
= w
->MenuStrip
;
2390 if (((struct IntWindow
*)w
)->menulendwindow
)
2392 strip
= ((struct IntWindow
*)w
)->menulendwindow
->MenuStrip
;
2395 DEBUG_KEY(dprintf("Handler: MenuStrip 0x%lx\n",strip
));
2400 if (MapRawKey(ie
, &key
, 1, NULL
) == 1)
2404 menucode
= FindMenuShortCut(strip
, key
, TRUE
, IntuitionBase
);
2406 DEBUG_KEY(dprintf("Handler: menucode 0x%lx\n",menucode
));
2408 if (menucode
!= MENUNULL
)
2410 DEBUG_KEY(dprintf("Handler: build menuevent\n"));
2411 ie
->ie_Class
= IECLASS_MENU
;
2412 ie
->ie_SubClass
= IESUBCLASS_MENUSTOP
;
2413 ie
->ie_EventAddress
= w
;
2414 ie
->ie_Code
= menucode
;
2417 menushortcut
= TRUE
;
2419 MENUS_ACTIVE
= TRUE
;
2420 iihdata
->MenuWindow
= w
;
2425 DEBUG_KEY(dprintf("Handler: MapRawKey failed\n"));
2428 if (!menushortcut
) /* !! */
2429 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2431 } /* if could be a menu short cut */
2433 if ((ie
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
) &&
2434 (!(w
->IDCMPFlags
& IDCMP_MENUPICK
)))
2436 struct Menu
*strip
= 0;
2437 struct Window
*window
= w
;
2439 /* not sure here about RMBTRAP */
2440 DEBUG_KEY(dprintf("Handler: no idcmp, create a MENULIST idcmp\n"));
2442 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2444 strip
= w
->MenuStrip
;
2446 if (((struct IntWindow
*)w
)->menulendwindow
)
2448 strip
= ((struct IntWindow
*)w
)->menulendwindow
->MenuStrip
;
2449 window
= ((struct IntWindow
*)w
)->menulendwindow
;
2452 DEBUG_KEY(dprintf("Handler: MenuStrip 0x%lx\n",strip
));
2457 if (MapRawKey(ie
, &key
, 1, NULL
) == 1)
2461 menucode
= FindMenuShortCut(strip
, key
, TRUE
, IntuitionBase
);
2463 DEBUG_KEY(dprintf("Handler: menucode 0x%lx\n",menucode
));
2465 if (menucode
!= MENUNULL
)
2467 DEBUG_KEY(dprintf("Handler: build menuevent\n"));
2468 ih_fire_intuimessage(window
,
2471 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machines!? */
2474 menushortcut
= TRUE
;
2479 DEBUG_KEY(dprintf("Handler: MapRawKey failed\n"));
2482 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2483 } /* if could be a menu short but current window has no idcmp cut */
2487 DEBUG_KEY(dprintf("Handler: menu shortcut..break\n"));
2491 /* This is a regular RAWKEY event (no gadget taking care
2494 if (iihdata
->ActQualifier
& IEQUALIFIER_REPEAT
)
2496 /* don't send repeat key events if repeatqueue is full */
2497 if (IW(w
)->num_repeatevents
>= IW(w
)->repeatqueue
)
2499 DEBUG_KEY(dprintf("Handler: RepeatEvents full..don't send more\n"));
2504 if (w
->IDCMPFlags
& IDCMP_VANILLAKEY
)
2508 DEBUG_KEY(dprintf("Handler: VANILLAKEY\n"));
2509 // DEBUG_KEY(dprintf("Handler: MapRawKey ie 0x%lx KeyMapBase 0x%lx IntutionBase 0x%lx\n",ie,KeymapBase,IntuitionBase));
2511 if (MapRawKey(ie
, &keyBuffer
, 1, NULL
) == 1)
2513 DEBUG_KEY(dprintf("Handler: send VANILLAKEY msg\n"));
2514 ih_fire_intuimessage(w
,
2517 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machines!? */
2519 DEBUG_KEY(dprintf("Handler: done\n"));
2523 /* If the event mapped to more than one byte, it is not
2524 a legal VANILLAKEY, so we send it as the original
2529 if (w
->IDCMPFlags
& IDCMP_RAWKEY
)
2531 DEBUG_KEY(dprintf("Handler: send IDCMP_RAWKEY Qual 0x%lx Code 0x%lx addr 0x%lx Event\n",
2532 ie
->ie_Qualifier
,ie
->ie_Code
,ie
->ie_position
.ie_addr
));
2533 ih_fire_intuimessage(w
,
2536 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machine!? */
2541 DEBUG_KEY(dprintf("Handler: done\n"));
2542 } /* regular RAWKEY */
2545 break; /* case IECLASS_RAWKEY */
2548 if (iihdata
->MouseBoundsKillTimer
)
2550 iihdata
->MouseBoundsKillTimer
--;
2551 if (iihdata
->MouseBoundsKillTimer
== 0)
2553 iihdata
->MouseBoundsActiveFlag
= FALSE
;
2557 if (GetPrivIBase(IntuitionBase
)->PointerDelay
)
2559 ULONG lock
= LockIBase(0);
2561 if (--GetPrivIBase(IntuitionBase
)->PointerDelay
== 0)
2563 struct SharedPointer
*shared_pointer
;
2564 struct Window
*window
= IntuitionBase
->ActiveWindow
;
2565 struct IntScreen
*scr
;
2567 DEBUG_POINTER(dprintf("InputHandler: PointerDelay\n"));
2568 DEBUG_POINTER(dprintf("InputHandler: Window 0x%lx\n",
2573 Object
*pointer
= ((struct IntWindow
*)window
)->pointer
;
2575 DEBUG_POINTER(dprintf("InputHandler: Pointer 0x%lx\n",
2577 scr
= GetPrivScreen(window
->WScreen
);
2580 DEBUG_POINTER(dprintf("InputHandler: Screen 0x%lx\n",
2582 if (pointer
== NULL
)
2584 pointer
= GetPrivIBase(IntuitionBase
)->DefaultPointer
;
2587 if (((struct IntWindow
*)window
)->busy
)
2589 pointer
= GetPrivIBase(IntuitionBase
)->BusyPointer
;
2592 GetAttr(POINTERA_SharedPointer
, pointer
, (IPTR
*) &shared_pointer
);
2594 DEBUG_POINTER(dprintf("InputHandler: scr 0x%lx pointer 0x%lx shared_pointer 0x%lx\n",
2595 scr
, pointer
, shared_pointer
));
2596 DEBUG_POINTER(dprintf("InputHandler: sprite 0x%lx\n",
2597 shared_pointer
->sprite
));
2599 if (DoMethod(scr
->IMonitorNode
, MM_SetPointerShape
, shared_pointer
))
2601 ObtainSharedPointer(shared_pointer
, IntuitionBase
);
2602 ReleaseSharedPointer(scr
->Pointer
, IntuitionBase
);
2603 scr
->Pointer
= shared_pointer
;
2606 window
->XOffset
= shared_pointer
->xoffset
;
2607 window
->YOffset
= shared_pointer
->yoffset
;
2612 DEBUG_POINTER(dprintf("InputHandler: can't set pointer.\n"));
2617 DEBUG_POINTER(dprintf("InputHandler: no screen.\n"));
2622 DEBUG_POINTER(dprintf("InputHandler: no window.\n"));
2629 if (GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
)
2631 struct IntScreen
*scr
= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
;
2633 if ((--scr
->MenuVerifyTimeOut
) <= 0)
2635 struct InputEvent ie
;
2637 /* currently we ONLY need the menu open time ! */
2638 ie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
2639 ie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
2641 if (FireMenuMessage(MMCODE_START
, scr
->MenuVerifyActiveWindow
, &ie
, IntuitionBase
))
2643 /* This lock will be released only when the user is
2644 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
2645 event arrives (generated by MenuHandler task) */
2647 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2648 iihdata
->MenuWindow
= scr
->MenuVerifyActiveWindow
;
2649 MENUS_ACTIVE
= TRUE
;
2652 scr
->MenuVerifyActiveWindow
= NULL
;
2653 scr
->MenuVerifyTimeOut
= 0;
2654 scr
->MenuVerifyMsgCount
= 0;
2655 scr
->MenuVerifySeconds
= 0;
2656 scr
->MenuVerifyMicros
= 0;
2657 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
2660 else if (MENUS_ACTIVE
)
2662 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2668 if (screen
->MouseY
<= screen
->BarHeight
&& GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
&& !iihdata
->TitlebarOnTop
&& iihdata
->TitlebarAppearTime
)
2670 UQUAD currenttime
= (((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50) + (UQUAD
)(ie
->ie_TimeStamp
.tv_micro
/ 20000);
2671 if (currenttime
>= iihdata
->TitlebarAppearTime
+ 10)
2673 iihdata
->TitlebarOnTop
= TRUE
;
2674 iihdata
->TitlebarAppearTime
= 0;
2676 LOCK_REFRESH(screen
);
2678 MoveLayer(0, screen
->BarLayer
, 0, screen
->BarHeight
+ 1);
2679 UpfrontLayer(0, screen
->BarLayer
);
2680 CheckLayers(screen
, IntuitionBase
);
2682 UNLOCK_REFRESH(screen
);
2688 UQUAD currenttime
= (((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50) + (UQUAD
)(ie
->ie_TimeStamp
.tv_micro
/ 20000);
2689 #define SECONDS(x) (x*50)
2690 if (iihdata
->HelpGadgetFindTime
&& (currenttime
>= iihdata
->HelpGadgetFindTime
+ SECONDS(1)))
2692 struct Gadget
*lhg
= iihdata
->LastHelpGadget
;
2693 fire_intuimessage(iihdata
->LastHelpWindow
,
2695 lhg
? lhg
->GadgetID
: 0, /* Don't know what it should be */
2698 iihdata
->HelpGadgetFindTime
= 0;
2704 if (IS_BOOPSI_GADGET(gadget
))
2706 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
2711 #if USE_NEWDISPLAYBEEP
2713 if (GetPrivIBase(IntuitionBase
)->BeepingScreens
)
2718 lock
= LockIBase(0);
2720 for (scr
= IntuitionBase
->FirstScreen
;
2721 scr
&& GetPrivIBase(IntuitionBase
)->BeepingScreens
;
2722 scr
= scr
->NextScreen
)
2724 if ((scr
->Flags
& BEEPING
) &&
2725 !GetPrivScreen(scr
)->BeepingCounter
--)
2727 GetPrivIBase(IntuitionBase
)->BeepingScreens
--;
2728 scr
->Flags
&= (UWORD
) ~BEEPING
;
2730 /* if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) <= 8)
2731 // visual beep on CLUT-screen
2733 // SetRGB4 (&screen->ViewPort, 0, scr->SaveColor0 & 0x000F, (scr->SaveColor0 & 0x00F0) >> 4, (scr->SaveColor0 & 0x0F00) >> 8);
2734 SetRGB32 (&scr->ViewPort, 0,
2735 GetPrivScreen(scr)->DisplayBeepColor0[0],
2736 GetPrivScreen(scr)->DisplayBeepColor0[1],
2737 GetPrivScreen(scr)->DisplayBeepColor0[2]
2741 // visual beep on hi- and truecolor screens
2743 RenderScreenBar(scr, FALSE, IntuitionBase);
2746 RenderScreenBar(scr
, FALSE
, IntuitionBase
);
2752 #endif /* USE_NEWDISPLAYBEEP */
2756 /* Send INTUITICK msg only if app already replied the last INTUITICK msg */
2757 if (w
->Flags
& WFLG_WINDOWTICKED
) break;
2759 if (w
->IDCMPFlags
& IDCMP_INTUITICKS
)
2761 /* Set the WINDOWTICKED flag, it will be cleared again when the app
2762 replies back the msg and the InputHandler handles the replymsg
2763 in HandleIntuiReplyPort() */
2765 ih_fire_intuimessage(w
,
2771 break; /* case IECLASS_TIMER */
2774 if (MENUS_ACTIVE
&& (ie
->ie_SubClass
== IESUBCLASS_MENUSTOP
))
2776 struct Window
*eventwin
= (struct Window
*)ie
->ie_EventAddress
;
2778 iihdata
->MenuWindow
= NULL
;
2779 MENUS_ACTIVE
= FALSE
;
2781 /* semaphore was locked when menu action started, see
2782 above where MMCODE_START MenuMessage is sent.
2784 It could have also have been locked if the user
2785 activated one of the menu key shortcuts, see
2786 "case IECLASS_RAWKEY" */
2788 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2792 if (((struct IntWindow
*)eventwin
)->menulendwindow
)
2794 eventwin
= ((struct IntWindow
*)eventwin
)->menulendwindow
;
2797 ih_fire_intuimessage((struct Window
*)eventwin
,
2800 (struct Window
*)ie
->ie_EventAddress
,
2806 case IECLASS_DISKINSERTED
:
2807 case IECLASS_DISKREMOVED
:
2808 case IECLASS_NEWPREFS
:
2814 switch (ie
->ie_Class
)
2816 case IECLASS_DISKINSERTED
:
2817 idcmp
= IDCMP_DISKINSERTED
;
2820 case IECLASS_DISKREMOVED
:
2821 idcmp
= IDCMP_DISKREMOVED
;
2825 idcmp
= IDCMP_NEWPREFS
;
2827 * Here we need to update the mouse prefs and
2828 * maybe other stuff which comes from the global prefs file.
2833 lock
= LockIBase(0);
2835 for (scr
= IntuitionBase
->FirstScreen
; scr
; scr
= scr
->NextScreen
)
2839 for (win
= scr
->FirstWindow
; win
; win
= win
->NextWindow
)
2842 CHECKME, really use fire_intuimessage() here,
2843 instead of ih_fireintuimessage? Same for
2844 IDCMP_GADGETHELP above, BTW. */
2846 fire_intuimessage(win
,
2858 case IECLASS_NEWMOUSE
:
2861 * The following is only needed on hardware not running
2862 * the NewMouse driver.
2864 if (w
->IDCMPFlags
& IDCMP_RAWKEY
&& (!SysBase
->MaxLocMem
))
2866 ih_fire_intuimessage(w
,
2869 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machine!? */
2879 case IECLASS_NEWTIMER
:
2882 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2889 if (gadget
== iihdata
->MasterSizeGadget
)
2891 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
2896 #endif /* __MORPHOS__ */
2901 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2908 "[Intui] InputHandler: Unknown IEClass: addr = %x class = %d (origclass = %d)\n",
2909 orig_ie
, ie
->ie_Class
,orig_ie
->ie_Class
2913 } /* switch (ie->ie_Class) */
2918 else if (keep_event
&& !ie_used
)
2920 *iihdata
->EndInputEventChain
= orig_ie
;
2921 iihdata
->EndInputEventChain
= &orig_ie
->ie_NextEvent
;
2926 orig_ie
->ie_NextEvent
= iihdata
->FreeInputEvents
;
2927 iihdata
->FreeInputEvents
= orig_ie
;
2930 } /* for (each event in the chain) */
2932 iihdata
->ActiveGadget
= gadget
;
2934 D(bug("Outside pollingloop\n"));
2936 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
2937 if (call_setpointerpos
)
2938 MySetPointerPos(IntuitionBase
);
2941 /* Terminate the event chain. */
2942 *iihdata
->EndInputEventChain
= NULL
;
2944 /* Transfer the list of allocated events in the list of events that should
2945 * be freed the next time the handler is entered.
2947 iihdata
->AllocatedInputEventList
= iihdata
->NewAllocatedInputEventList
;
2948 NEWLIST((struct List
*)&iihdata
->NewAllocatedInputEventList
);
2950 /* Reset the event chain here, not at the beginning of the handler, for
2951 * events that might be allocated in other handers.
2953 iihdata
->EndInputEventChain
= &iihdata
->ReturnInputEvent
;
2954 iihdata
->FreeInputEvents
= NULL
;
2956 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->InputHandlerLock
);
2958 // DEBUG_HANDLER(dprintf("Handler: ->IBase 0x%lx KeyMapBase 0x%lx\n",IntuitionBase,KeymapBase));
2960 return iihdata
->ReturnInputEvent
;
2965 /****************************************************************************************/