2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
7 /****************************************************************************************/
9 #include <proto/exec.h>
10 #include <proto/intuition.h>
11 #include <proto/alib.h>
12 #include <proto/layers.h>
13 #include <proto/graphics.h>
14 #include <proto/keymap.h>
15 #include <proto/utility.h>
16 #include <proto/input.h>
17 #include <proto/timer.h>
18 #include <exec/memory.h>
19 #include <exec/alerts.h>
20 #include <exec/interrupts.h>
21 #include <exec/ports.h>
22 #include <intuition/intuition.h>
23 #include <intuition/intuitionbase.h>
24 #include <intuition/gadgetclass.h>
25 #include <intuition/pointerclass.h>
26 #include <intuition/cghooks.h>
27 #include <intuition/sghooks.h>
28 #include <devices/inputevent.h>
29 #include <devices/rawkeycodes.h>
30 #include <clib/macros.h>
31 #include "inputhandler.h"
33 #include "boopsigadgets.h"
34 #include "boolgadgets.h"
35 #include "propgadgets.h"
36 #include "strgadgets.h"
38 #include "intuition_intern.h" /* EWFLG_xxx */
39 #include "inputhandler_support.h"
40 #include "inputhandler_actions.h"
42 #include "monitorclass_private.h"
45 # include "smallmenu.h"
46 # include "intuition_customizesupport.h"
51 #include <aros/debug.h>
53 #define DEBUG_HANDLER(x) ;
54 #define DEBUG_KEY(x) ;
55 #define DEBUG_SCREENKEY(x) ;
56 #define DEBUG_AUTOSCROLL(x)
57 #define DEBUG_CLICK(x)
59 #define DEBUG_GADGET(x)
60 #define DEBUG_MONITOR(x)
61 #define DEBUG_MOUSE(x)
62 #define DEBUG_WINDOW(x)
64 /****************************************************************************************/
66 struct Interrupt
*InitIIH(struct IntuitionBase
*IntuitionBase
)
68 struct Interrupt
*iihandler
;
70 D(bug("InitIIH(IntuitionBase=%p)\n", IntuitionBase
));
72 iihandler
= AllocMem(sizeof (struct Interrupt
), MEMF_PUBLIC
| MEMF_CLEAR
);
75 struct IIHData
*iihdata
;
77 iihdata
= AllocMem(sizeof (struct IIHData
), MEMF_PUBLIC
| MEMF_CLEAR
);
82 port
= AllocMem(sizeof (struct MsgPort
), MEMF_PUBLIC
| MEMF_CLEAR
);
85 if ((iihdata
->InputEventMemPool
= CreatePool(MEMF_PUBLIC
| MEMF_CLEAR
,
86 sizeof(struct GeneratedInputEvent
) * 10,
87 sizeof(struct GeneratedInputEvent
) * 10)) &&
88 (iihdata
->ActionsMemPool
= CreatePool(MEMF_SEM_PROTECTED
,
91 const struct TagItem dragtags
[] =
93 {GA_SysGadget
, TRUE
},
94 {GA_SysGType
, GTYP_WDRAGGING
},
98 const struct TagItem sizetags
[] =
100 {GA_SysGadget
, TRUE
},
101 {GA_SysGType
, GTYP_SIZING
},
105 iihdata
->MasterDragGadget
= (struct Gadget
*)NewObjectA(GetPrivIBase(IntuitionBase
)->dragbarclass
,
107 (struct TagItem
*)dragtags
);
109 iihdata
->MasterSizeGadget
= (struct Gadget
*)NewObjectA(GetPrivIBase(IntuitionBase
)->sizebuttonclass
,
111 (struct TagItem
*)sizetags
);
113 if (iihdata
->MasterDragGadget
&& iihdata
->MasterSizeGadget
)
117 /* We do not want to be woken up by message replies.
118 We are anyway woken up about 10 times a second by
121 port
->mp_Flags
= PA_IGNORE
;
123 NEWLIST( &(port
->mp_MsgList
) );
124 iihdata
->IntuiReplyPort
= port
;
126 NEWLIST((struct List
*) &iihdata
->IntuiActionQueue
);
127 NEWLIST((struct List
*)&iihdata
->NewAllocatedInputEventList
);
128 NEWLIST((struct List
*)&iihdata
->AllocatedInputEventList
);
129 iihdata
->EndInputEventChain
= &iihdata
->ReturnInputEvent
;
130 iihdata
->FreeInputEvents
= NULL
;
132 iihdata
->ActQualifier
= IEQUALIFIER_RELATIVEMOUSE
;
134 /* Note: there are several routines like CloseWindow, which
135 expect is_Data to point to the IIHData structure, so don't
138 iihandler
->is_Code
= (VOID_FUNC
)AROS_ASMSYMNAME(IntuiInputHandler
);
139 iihandler
->is_Data
= iihdata
;
140 iihandler
->is_Node
.ln_Pri
= 50;
141 iihandler
->is_Node
.ln_Name
= "Intuition InputHandler";
143 lock
= LockIBase(0UL);
145 iihdata
->IntuitionBase
= IntuitionBase
;
149 GetPrivIBase(IntuitionBase
)->IntuiReplyPort
= iihdata
->IntuiReplyPort
;
150 GetPrivIBase(IntuitionBase
)->IntuiActionQueue
= &iihdata
->IntuiActionQueue
;
152 ReturnPtr ("InitIIH", struct Interrupt
*, iihandler
);
153 } /* f (iihdata->MasterDragGadget && iihdata->MasterSizeGadget) */
155 DisposeObject((Object
*)iihdata
->MasterDragGadget
);
156 DisposeObject((Object
*)iihdata
->MasterSizeGadget
);
158 DeletePool(iihdata
->ActionsMemPool
);
159 DeletePool(iihdata
->InputEventMemPool
);
161 } /* if (iihdata->InputEventMemPool = ... */
162 FreeMem(port
, sizeof(struct MsgPort
));
165 FreeMem(iihdata
, sizeof (struct IIHData
));
166 iihdata
->MouseBoundsActiveFlag
= FALSE
;
169 FreeMem(iihandler
, sizeof (struct Interrupt
));
171 } /* if (iihandler) */
173 ReturnPtr ("InitIIH", struct Interrupt
*, NULL
);
176 /****************************************************************************************/
178 VOID
CleanupIIH(struct Interrupt
*iihandler
, struct IntuitionBase
*IntuitionBase
)
180 struct IIHData
*iihdata
= (struct IIHData
*)iihandler
->is_Data
;
182 DisposeObject((Object
*)iihdata
->MasterDragGadget
);
183 DisposeObject((Object
*)iihdata
->MasterSizeGadget
);
185 FreeGeneratedInputEvents(iihdata
);
186 DeletePool(iihdata
->InputEventMemPool
);
187 DeletePool(iihdata
->ActionsMemPool
);
189 /* One might think that this port is still in use by the inputhandler.
190 ** However, if intuition is closed for the last time, there should be no
191 ** windows that IntuiMessage can be sent to.
193 FreeMem(iihdata
->IntuiReplyPort
, sizeof (struct MsgPort
));
195 FreeMem(iihdata
, sizeof (struct IIHData
));
196 FreeMem(iihandler
, sizeof (struct Interrupt
));
201 /****************************************************************************************/
203 static void HandleIntuiReplyPort(struct IIHData
*iihdata
, struct IntuitionBase
*IntuitionBase
)
205 struct Library
*TimerBase
= GetPrivIBase(IntuitionBase
)->TimerBase
;
206 struct IntuiMessage
*im
;
208 while ((im
= (struct IntuiMessage
*)GetMsg(iihdata
->IntuiReplyPort
)))
210 if (im
->IDCMPWindow
&& ResourceExisting(im
->IDCMPWindow
, RESOURCE_WINDOW
, IntuitionBase
))
212 struct IntWindow
*win
= (struct IntWindow
*)im
->IDCMPWindow
;
215 GetSysTime(&win
->lastmsgreplied
);
220 case IDCMP_MOUSEMOVE
:
221 IW(im
->IDCMPWindow
)->num_mouseevents
--;
224 case IDCMP_INTUITICKS
:
225 AROS_ATOMIC_AND(im
->IDCMPWindow
->Flags
, ~WFLG_WINDOWTICKED
);
228 #if USE_IDCMPUPDATE_MESSAGECACHE
229 case IDCMP_IDCMPUPDATE
:
230 IW(im
->IDCMPWindow
)->num_idcmpupdate
--;
232 if (!(IW(im
->IDCMPWindow
)->num_idcmpupdate
) && IW(im
->IDCMPWindow
)->messagecache
)
234 SendIntuiMessage(im
->IDCMPWindow
,IW(im
->IDCMPWindow
)->messagecache
);
235 IW(im
->IDCMPWindow
)->messagecache
= 0;
240 case IDCMP_MENUVERIFY
:
242 struct Window
*w
= im
->IDCMPWindow
;
243 struct IntScreen
*scr
= 0;
245 scr
= GetPrivScreen(w
->WScreen
);
247 if (scr
!= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
||
248 scr
->MenuVerifySeconds
> im
->Seconds
||
249 (scr
->MenuVerifySeconds
== im
->Seconds
&&
250 scr
->MenuVerifyMicros
> im
->Micros
))
252 /* The timeout has expired, just ignore. */
256 --scr
->MenuVerifyMsgCount
;
257 if (w
== scr
->MenuVerifyActiveWindow
&&
258 im
->Code
== MENUCANCEL
)
260 ULONG lock
= LockIBase(0);
263 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
265 if (w1
->IDCMPFlags
& IDCMP_MENUVERIFY
&& w1
!= scr
->MenuVerifyActiveWindow
)
267 ih_fire_intuimessage(w1
,
277 scr
->MenuVerifyActiveWindow
= NULL
;
278 scr
->MenuVerifyTimeOut
= 0;
279 scr
->MenuVerifyMsgCount
= 0;
280 scr
->MenuVerifySeconds
= 0;
281 scr
->MenuVerifyMicros
= 0;
282 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
284 else if (scr
->MenuVerifyMsgCount
== 0)
286 struct InputEvent ie
;
288 /* currently we ONLY need the menu open time ! */
289 ie
.ie_TimeStamp
.tv_secs
= im
->Seconds
;
290 ie
.ie_TimeStamp
.tv_micro
= im
->Micros
;
292 if (FireMenuMessage(MMCODE_START
, scr
->MenuVerifyActiveWindow
, &ie
, IntuitionBase
))
294 /* This lock will be released only when the user is
295 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
296 event arrives (generated by MenuHandler task) */
298 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
299 iihdata
->MenuWindow
= scr
->MenuVerifyActiveWindow
;
303 scr
->MenuVerifyActiveWindow
= NULL
;
304 scr
->MenuVerifyTimeOut
= 0;
305 scr
->MenuVerifyMsgCount
= 0;
306 scr
->MenuVerifySeconds
= 0;
307 scr
->MenuVerifyMicros
= 0;
308 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
314 case IDCMP_SIZEVERIFY
:
316 struct GadgetInfo
*gi
= &iihdata
->GadgetInfo
;
317 struct Window
*w
= im
->IDCMPWindow
;
318 struct Gadget
*gadget
= im
->IAddress
;
319 struct InputEvent ie
;
322 PrepareGadgetInfo(gi
, IntuitionBase
->ActiveScreen
, w
, NULL
);
323 SetGadgetInfoGadget(gi
, gadget
, IntuitionBase
);
325 if (IS_BOOPSI_GADGET(gadget
))
327 ie
.ie_NextEvent
= NULL
;
328 ie
.ie_Class
= IECLASS_RAWMOUSE
;
330 ie
.ie_Code
= IECODE_LBUTTON
;
331 ie
.ie_Qualifier
= im
->Qualifier
;
332 ie
.ie_X
= im
->MouseX
;
333 ie
.ie_Y
= im
->MouseY
;
334 ie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
335 ie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
344 /* For compatibility, send a GM_HANDLEINPUT too */
345 ie
.ie_Class
= IECLASS_RAWMOUSE
;
346 ie
.ie_Code
= IECODE_NOBUTTON
;
350 gadget
= DoGPInput(gi
,
358 /* From now on the master drag/size gadget takes over */
360 iihdata
->ActiveSysGadget
= gadget
;
361 gadget
= iihdata
->MasterSizeGadget
;
362 iihdata
->ActiveGadget
= gadget
;
364 ie
.ie_Class
= IECLASS_RAWMOUSE
;
365 ie
.ie_Code
= IECODE_LBUTTON
;
366 ie
.ie_X
= im
->MouseX
;
367 ie
.ie_Y
= im
->MouseY
;
378 case IDCMP_REQVERIFY
:
380 struct Window
*w
= im
->IDCMPWindow
;
382 EndRequest(w
->DMRequest
, w
);
384 ih_fire_intuimessage(w
,
392 case IDCMP_WBENCHMESSAGE
:
393 DEBUG_WORKBENCH(dprintf("HandleIntuiReplyPort: code 0x%lx\n",
397 } /* switch(im->Class) */
399 if (im
->Qualifier
& IEQUALIFIER_REPEAT
)
401 /* IDCMP_IDCMPUPDATE messages can also be sent from app task, therefore
402 it would be better if there was an ATOMIC_DEC macro or something */
404 if (IW(im
->IDCMPWindow
)->num_repeatevents
)
406 IW(im
->IDCMPWindow
)->num_repeatevents
--;
410 FreeIntuiMessage(im
);
412 } /* while ((im = (struct IntuiMessage *)GetMsg(iihdata->IntuiReplyPort))) */
414 /****************************************************************************************/
416 struct Window
*GetToolBoxWindow(struct InputEvent
*ie
, struct Screen
*scr
, struct IntuitionBase
*IntuitionBase
)
418 /* The caller has checked that the input event is a IECLASS_RAWMOUSE, SELECTDOWN event */
419 /* NOTE: may be called with NULL ie ptr! */
420 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
422 struct Window
*new_w
= NULL
;
426 D(bug("GetToolBoxWindow: Click at (%d,%d)\n",scr
->MouseX
,scr
->MouseY
));
429 LockLayerInfo(&scr
->LayerInfo
);
431 l
= WhichLayer(&scr
->LayerInfo
, scr
->MouseX
, scr
->MouseY
);
433 UnlockLayerInfo(&scr
->LayerInfo
);
438 D(bug("GetToolBoxWindow: Click not inside layer\n"));
440 else if (l
== scr
->BarLayer
)
445 new_w
= (struct Window
*)l
->Window
;
448 if ((new_w
->Flags
& WFLG_TOOLBOX
) == 0) new_w
= NULL
;
452 D(bug("GetToolBoxWindow: Selected layer is not a ToolBox window\n"));
456 D(bug("GetToolBoxWindow: Found layer %p\n", l
));
461 D(bug("GetToolBoxWindow: New window %p\n", new_w
));
465 /****************************************************************************************/
467 #define KEY_QUALIFIERS (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT | \
468 IEQUALIFIER_CAPSLOCK | IEQUALIFIER_CONTROL | \
469 IEQUALIFIER_LALT | IEQUALIFIER_RALT | \
470 IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND | \
471 IEQUALIFIER_NUMERICPAD)
473 #define BUTTON_QUALIFIERS (IEQUALIFIER_MIDBUTTON | IEQUALIFIER_RBUTTON | IEQUALIFIER_LEFTBUTTON)
475 static struct Gadget
*Process_RawMouse(struct InputEvent
*ie
, struct IIHData
*iihdata
, struct Screen
*screen
,
476 struct Window
*w
, struct Gadget
*gadget
, struct GadgetInfo
*gi
,
477 ULONG stitlebarhit
, BOOL new_active_window
, BOOL IsToolbox
,
478 struct InputEvent
*orig_ie
, BOOL
*keep_event
, BOOL
*reuse_event
,
479 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
480 BOOL
*call_setpointerpos
,
482 struct IntuitionBase
*IntuitionBase
)
484 struct Library
*InputBase
= GetPrivIBase(IntuitionBase
)->InputBase
;
485 struct Requester
*req
= w
? w
->FirstRequest
: NULL
;
487 switch (ie
->ie_Code
) {
490 BOOL new_gadget
= FALSE
;
491 BOOL sizeverify
= FALSE
;
492 UWORD MetaDrag
= GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_MetaDrag
;
494 DEBUG_CLICK(bug("[Inputhandler] Screen 0x%p, Window 0x%p, Gadget 0x%p, screen titlebar %d, new active window %d\n", screen
, w
, gadget
, stitlebarhit
, new_active_window
));
495 DEBUG_CLICK(if (screen
) bug("[Inputhandler] Coordinates: (%d, %d)\n", screen
->MouseX
, screen
->MouseY
));
497 iihdata
->ActQualifier
|= IEQUALIFIER_LEFTBUTTON
;
499 /* Enter screen dragging mode if LButton + MetaDrag are pressed. */
500 if (MetaDrag
&& ((iihdata
->ActQualifier
& KEY_QUALIFIERS
) == MetaDrag
)) {
501 iihdata
->ScreenDrag
= screen
;
502 iihdata
->ScreenDragPointX
= screen
->MouseX
;
503 iihdata
->ScreenDragPointY
= screen
->MouseY
;
509 iihdata
->TitlebarAppearTime
= 0;
513 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
521 struct Gadget
* draggadget
= 0;
523 if ((!(w
->FirstRequest
)) && (w
->Flags
& WFLG_DRAGBAR
) && MatchHotkey(ie
,IA_ACTIVEWINDOWMOVE
,IntuitionBase
))
525 if (w
->MouseX
< IW(w
)->sizeimage_width
|| w
->MouseX
> w
->Width
- IW(w
)->sizeimage_width
- 1 || w
->MouseY
< ((IW(w
)->sizeimage_height
> w
->BorderTop
) ? IW(w
)->sizeimage_height
: w
->BorderTop
) || w
->MouseY
> w
->Height
- IW(w
)->sizeimage_height
- 1)
527 for (draggadget
= w
->FirstGadget
; draggadget
; draggadget
= draggadget
->NextGadget
)
529 if ((draggadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
)
539 if ((!(w
->FirstRequest
)) && (w
->Flags
& WFLG_SIZEGADGET
) && MatchHotkey(ie
,IA_ACTIVEWINDOWSIZE
,IntuitionBase
))
541 if (w
->MouseX
< IW(w
)->sizeimage_width
|| w
->MouseX
> w
->Width
- IW(w
)->sizeimage_width
- 1 || w
->MouseY
< ((IW(w
)->sizeimage_height
> w
->BorderTop
) ? IW(w
)->sizeimage_height
: w
->BorderTop
) || w
->MouseY
> w
->Height
- IW(w
)->sizeimage_height
- 1)
543 for (draggadget
= w
->FirstGadget
; draggadget
; draggadget
= draggadget
->NextGadget
)
545 if ((draggadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
)
559 /* use the *current* screen rather than active one when searching
560 for sdepth gadget! */
562 gadget
= FindGadget (screen
, stitlebarhit
? NULL
: w
, stitlebarhit
? NULL
: req
,
563 screen
->MouseX
, screen
->MouseY
, gi
, FALSE
, IntuitionBase
);
564 DEBUG_CLICK(bug("Click on gadget %p\n", gadget
));
569 /* If we clicked screen titlebar outside of any gadget, enter drag mode */
570 if ((!gadget
) && stitlebarhit
) {
571 DEBUG_CLICK(bug("[Inputhandler] Entering drag state for screen 0x%p\n", screen
));
572 iihdata
->ScreenDrag
= screen
;
573 iihdata
->ScreenDragPointX
= screen
->MouseX
;
574 iihdata
->ScreenDragPointY
= screen
->MouseY
;
580 if (!gadget
&& stitlebarhit
)
582 struct Window
*ww
= 0;
584 ww
= FindDesktopWindow(screen
, IntuitionBase
);
585 DEBUG_CLICK(bug("[Inputhandler] Clicked on backdrop window 0x%p\n", ww
));
592 if (!stitlebarhit
&& !new_active_window
&& DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
593 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
595 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= SELECTDOWN
)
597 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
598 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= SELECTDOWN
;
602 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
607 DEBUG_CLICK(bug("[Inputhandler] Resetting doubleclick counter\n"));
608 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= SELECTDOWN
;
609 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
612 /* update last click time for doubleclicktofront */
613 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
614 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
621 if (!(gadget
&& ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
)))
622 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
625 if (result
== RUNHOTREUSE
)
637 if (gadget
&& new_gadget
)
639 DEBUG_GADGET(bug("[Inputhandler] Activate gadget: 0x%p\n", gadget
));
640 if (w
&& (w
->IDCMPFlags
& IDCMP_SIZEVERIFY
) &&
641 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
/*||
642 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WZOOM*/)
644 ih_fire_intuimessage(w
,
654 BOOL is_draggad
, is_sizegad
;
657 /* Whenever the active gadget changes the gi must be updated
658 because it is cached in iidata->GadgetInfo!!!! Don't
659 forget to do this if somewhere else the active
660 gadget is changed, for example in ActivateGadget!!! */
662 PrepareGadgetInfo(gi
, screen
, w
, req
);
663 SetGadgetInfoGadget(gi
, gadget
, IntuitionBase
);
665 gsystype
= gadget
->GadgetType
& GTYP_SYSTYPEMASK
;
666 is_draggad
= ((gsystype
== GTYP_WDRAGGING
)
668 || (gsystype
== GTYP_WDRAGGING2
)
671 is_sizegad
= (gsystype
== GTYP_SIZING
);
673 /* jDc: intui68k sends IDCMPs for GACT_IMMEDIATE drag&sizegads! */
674 if (gadget
->Activation
& GACT_IMMEDIATE
)
676 ih_fire_intuimessage(w
,
683 if (is_draggad
|| is_sizegad
)
685 if (IS_BOOPSI_GADGET(gadget
))
694 /* Ignoring retval of dispatcher above is what
695 AmigaOS does too for boopsi drag/resize
700 /* From now on the master drag/size gadget takes over */
701 if ((w
->MoreFlags
& WMFLG_IAMMUI
) && (w
->Flags
& WFLG_BORDERLESS
))
702 iihdata
->ActiveSysGadget
= is_draggad
? gadget
: 0;
704 iihdata
->ActiveSysGadget
= gadget
;
705 gadget
= is_draggad
? iihdata
->MasterDragGadget
: iihdata
->MasterSizeGadget
;
713 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
715 case GTYP_BOOLGADGET
:
716 /* Only set the GFLG_SELECTED flag for RELVERIFY and
717 * TOGGLESELECT gadget. It's for the user to do it if
718 * he wants for other GADGIMMEDIATE ones.
719 * Only RELVERIFY gadgets stay active.
722 if (gadget
->Activation
& (GACT_TOGGLESELECT
| GACT_RELVERIFY
))
724 gadget
->Flags
^= GFLG_SELECTED
;
725 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
728 if (gadget
->Activation
& GACT_RELVERIFY
)
730 gadget
->Activation
|= GACT_ACTIVEGADGET
;
731 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
739 case GTYP_PROPGADGET
:
740 HandlePropSelectDown(gadget
,
743 w
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
744 w
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
751 /* If the click was inside the active strgad,
752 ** then let it update cursor pos,
753 ** else deactivate stringadget and reuse event.
756 if (InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
757 gi
->gi_Requester
, gadget
,
758 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
))
762 HandleStrInput(gadget
, gi
, ie
, &imsgcode
,
767 gadget
->Flags
&= ~GFLG_SELECTED
;
769 RefreshStrGadget(gadget
, w
, req
, IntuitionBase
);
770 /* Gadget not active anymore */
776 case GTYP_CUSTOMGADGET
:
777 gadget
= DoGPInput(gi
,
780 (new_gadget
? GM_GOACTIVE
: GM_HANDLEINPUT
),
783 D(bug("new_gadget %d, goactive %p\n", new_gadget
, gadget
));
785 if (gadget
&& new_gadget
&& (!(gadget
->GadgetType
& GTYP_SIZING
)))
787 /* For compatibility, send a GM_HANDLEINPUT too */
788 struct InputEvent newie
;
791 newie
.ie_NextEvent
= NULL
;
792 newie
.ie_Class
= IECLASS_RAWMOUSE
;
793 newie
.ie_SubClass
= 0;
794 newie
.ie_Code
= IECODE_NOBUTTON
;
795 newie
.ie_Qualifier
= ie
->ie_Qualifier
;
798 newie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
799 newie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
801 gadget
= DoGPInput(gi
,
807 D(bug("handleinput %p\n", gadget
));
811 case 0: //orig gadtools / some 1.3 gadgets
812 if (IS_SYS_GADGET(gadget
))
814 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
818 if (gadget
->Activation
& GACT_RELVERIFY
)
820 gadget
->Activation
|= GACT_ACTIVEGADGET
;
821 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
822 if (gadget
->Flags
& GFLG_GADGHIMAGE
)
824 gadget
->Flags
^= GFLG_SELECTED
;
825 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
830 /* jDc: this is what original intuition does, before crashing after a while ;)*/
831 DEBUG_CLICK(bug("[Inputhandler] Sending SELECTDOWN (old gadget), window 0x%p\n", w
));
832 ih_fire_intuimessage(w
,
840 } /* switch (GadgetType) */
842 } /* if (a gadget is active) */
843 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && !sizeverify
&& !stitlebarhit
)
845 DEBUG_CLICK(bug("[Inputhandler] Sending SELECTDOWN, window 0x%p\n", w
));
846 ih_fire_intuimessage(w
,
853 } /* case SELECTDOWN */
857 iihdata
->ActQualifier
&= ~IEQUALIFIER_LEFTBUTTON
;
859 /* Ignore this event if screen drag qualifier is pressed */
860 if (iihdata
->ScreenDrag
) {
861 iihdata
->ScreenDrag
= NULL
;
867 iihdata
->TitlebarAppearTime
= 0;
871 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
878 BOOL inside
= InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
879 gi
->gi_Requester
, gadget
,
880 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
);
882 /*int selected = (gadget->Flags & GFLG_SELECTED) != 0;*/
884 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
886 case GTYP_BOOLGADGET
:
887 /* Must be a RELVERIFY gadget */
889 if (!(gadget
->Activation
& GACT_TOGGLESELECT
) && inside
)
891 gadget
->Flags
^= GFLG_SELECTED
;
892 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
897 if (IS_SYS_GADGET(gadget
))
899 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
903 if (req
&& gadget
->Activation
& GACT_ENDGADGET
)
907 req
= w
->FirstRequest
;
910 ih_fire_intuimessage(w
,
920 ih_fire_intuimessage(w
,
927 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
931 case GTYP_PROPGADGET
:
932 HandlePropSelectUp(gadget
, w
, req
, IntuitionBase
);
933 if (gadget
->Activation
& GACT_RELVERIFY
)
935 ih_fire_intuimessage(w
,
945 /* Intuition string gadgets don't care about SELECTUP */
947 case GTYP_CUSTOMGADGET
:
948 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
951 case 0: //orig gadtools / some 1.3 gadgets
952 /* jDc: adding a gadget with gtyp field set to NULL crashes intui68k
953 ** seems we don't need compatibility on this field ;) anyway we should
954 ** handle the case of GTYP_CLOSE, etc, set by some "cod3r"
956 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
957 if (gadget
->Activation
& GACT_RELVERIFY
)
959 if (gadget
->Flags
& GFLG_GADGHIMAGE
)
963 gadget
->Flags
^= GFLG_SELECTED
;
964 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
970 ih_fire_intuimessage(w
,
977 ih_fire_intuimessage(w
,
986 } /* switch GadgetType */
988 } /* if (a gadget is currently active) */
989 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
))
991 ih_fire_intuimessage(w
,
998 break; /* case SELECTUP */
1001 iihdata
->ActQualifier
|= IEQUALIFIER_RBUTTON
;
1004 iihdata
->TitlebarAppearTime
= 0;
1008 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1009 *keep_event
= FALSE
;
1013 if (DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
1014 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
1016 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= MENUDOWN
)
1018 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1019 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MENUDOWN
;
1023 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
1028 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MENUDOWN
;
1029 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1032 /* update last click time for doubleclicktofront */
1033 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
1034 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
1040 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
1042 if (result
== RUNHOTREUSE
)
1044 *reuse_event
= TRUE
;
1048 *keep_event
= FALSE
;
1052 w
= IntuitionBase
->ActiveWindow
;
1057 if ((!MENUS_ACTIVE
) && (!gadget
) && (!(iihdata
->ActQualifier
& (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_MIDBUTTON
))))
1060 struct GadgetInfo ginf
;
1062 struct Window
*wind
= FindActiveWindow(0, screen
, &hit
,IntuitionBase
);
1066 gad
= FindGadget (screen
,
1068 IntuitionBase
->ActiveScreen
->MouseX
,
1069 IntuitionBase
->ActiveScreen
->MouseY
,
1070 &ginf
, TRUE
, IntuitionBase
);
1072 if (gad
&& ((gad
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
))
1074 CreateSmallMenuTask(wind
,SMALLMENU_TYPE_WINDOWDEPTH
,IntuitionBase
);
1075 *keep_event
= FALSE
;
1079 if (gad
&& ((gad
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SDEPTH
))
1081 CreateSmallMenuTask(0,SMALLMENU_TYPE_SCREENDEPTH
,IntuitionBase
);
1082 *keep_event
= FALSE
;
1089 if (w
&& !req
&& w
->DMRequest
&& !(w
->Flags
& WFLG_RMBTRAP
))
1091 if (!MENUS_ACTIVE
&&
1092 DoubleClick(GetPrivIBase(IntuitionBase
)->DMStartSecs
,
1093 GetPrivIBase(IntuitionBase
)->DMStartMicro
,
1094 ie
->ie_TimeStamp
.tv_secs
,
1095 ie
->ie_TimeStamp
.tv_micro
))
1097 if (w
->IDCMPFlags
& IDCMP_REQVERIFY
)
1099 ih_fire_intuimessage(w
,
1105 else if (Request(w
->DMRequest
, w
))
1109 ih_fire_intuimessage(w
,
1115 *keep_event
= FALSE
;
1119 GetPrivIBase(IntuitionBase
)->DMStartSecs
= ie
->ie_TimeStamp
.tv_secs
;
1120 GetPrivIBase(IntuitionBase
)->DMStartMicro
= ie
->ie_TimeStamp
.tv_micro
;
1125 if (!(w
->Flags
& WFLG_RMBTRAP
) && !req
)
1127 struct IntScreen
*scr
= GetPrivScreen(w
->WScreen
);
1130 BOOL mouseon
= TRUE
;
1132 scr
->MenuVerifyMsgCount
= 0;
1134 if (w
->MouseX
< 0 || w
->MouseY
< 0) mouseon
= FALSE
;
1135 if (w
->MouseX
> w
->Width
|| w
->MouseY
> w
->Height
) mouseon
= FALSE
;
1137 if (w
->IDCMPFlags
& IDCMP_MENUVERIFY
&& (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
1139 ih_fire_intuimessage(w
,
1141 mouseon
? MENUHOT
: MENUWAITING
,
1144 scr
->MenuVerifyMsgCount
++;
1147 lock
= LockIBase(0);
1149 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
1151 if ((w1
->IDCMPFlags
& IDCMP_MENUVERIFY
) && (w1
!= w
) && (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
1153 ih_fire_intuimessage(w1
,
1158 ++scr
->MenuVerifyMsgCount
;
1164 /* FIXME: when a window is opened with IDCMP_MENUVERIFY
1165 * (or this event is requested via ModifyIDCMP), and a
1166 * verify operation is pending, the window should get
1167 * a verify message too. Oh well.
1170 if (scr
->MenuVerifyMsgCount
)
1172 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= scr
;
1173 scr
->MenuVerifyActiveWindow
= w
;
1174 scr
->MenuVerifyTimeOut
= 2;
1175 scr
->MenuVerifySeconds
= IntuitionBase
->Seconds
;
1176 scr
->MenuVerifyMicros
= IntuitionBase
->Micros
;
1178 else if (FireMenuMessage(MMCODE_START
, w
, NULL
/*ie*/, IntuitionBase
))
1180 /* This lock will be released only when the user is
1181 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
1182 event arrives (generated by MenuHandler task) */
1184 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
1185 iihdata
->MenuWindow
= w
;
1186 MENUS_ACTIVE
= TRUE
;
1196 switch(ie
->ie_Code
) {
1198 iihdata
->ActQualifier
&= ~IEQUALIFIER_RBUTTON
;
1199 if (GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
)
1202 struct IntScreen
*scr
= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
;
1203 ULONG lock
= LockIBase(0);
1205 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
1207 if (w1
->IDCMPFlags
& IDCMP_MENUVERIFY
&& w1
->IDCMPFlags
& IDCMP_MOUSEBUTTONS
)
1209 ih_fire_intuimessage(w1
,
1219 /* FIXME: when the active window replies the verifymessage,
1220 * it should get a IDCMP_MENUPICK/MENUNULL message.
1222 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
1223 scr
->MenuVerifyActiveWindow
= NULL
;
1224 scr
->MenuVerifyMsgCount
= 0;
1225 scr
->MenuVerifyTimeOut
= 0;
1226 scr
->MenuVerifySeconds
= 0;
1227 scr
->MenuVerifyMicros
= 0;
1232 iihdata
->ActQualifier
|= IEQUALIFIER_MIDBUTTON
;
1233 if (DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
1234 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
1236 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= MIDDLEDOWN
)
1238 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1239 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
1241 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
1243 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
1244 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1246 /* update last click time for doubleclicktofront */
1247 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
1248 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
1252 iihdata
->ActQualifier
&= ~IEQUALIFIER_MIDBUTTON
;
1257 iihdata
->TitlebarAppearTime
= 0;
1261 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1262 *keep_event
= FALSE
;
1267 if (ie
->ie_Code
== MIDDLEDOWN
)
1271 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
1273 if (result
== RUNHOTREUSE
)
1275 *reuse_event
= TRUE
;
1279 *keep_event
= FALSE
;
1283 w
= IntuitionBase
->ActiveWindow
;
1288 if (IS_BOOPSI_GADGET(gadget
))
1290 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
1293 } /* if (there is an active gadget) */
1294 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && w
!= GetPrivScreen(w
->WScreen
)->MenuVerifyActiveWindow
)
1296 ih_fire_intuimessage(w
,
1303 break; /* case MENUDOWN */
1305 case IECODE_NOBUTTON
: /* MOUSEMOVE */
1308 UWORD DWidth
, DHeight
;
1310 if (ie
->ie_Qualifier
& IEQUALIFIER_RELATIVEMOUSE
) {
1313 /* Add delta information lost in previous mousemove event. See below. */
1314 iihdata
->DeltaMouseX
= ie
->ie_X
+ iihdata
->DeltaMouseX_Correction
;
1315 iihdata
->DeltaMouseY
= ie
->ie_Y
+ iihdata
->DeltaMouseY_Correction
;
1317 #define ACCELERATOR_THRESH 2
1318 #define ACCELERATOR_MULTI 2
1320 if (GetPrivIBase(IntuitionBase
)->ActivePreferences
->EnableCLI
& MOUSE_ACCEL
) {
1322 if (ABS(iihdata
->DeltaMouseX
) > ACCELERATOR_THRESH
)
1323 iihdata
->DeltaMouseX
*= ACCELERATOR_MULTI
;
1324 if (ABS(iihdata
->DeltaMouseY
) > ACCELERATOR_THRESH
)
1325 iihdata
->DeltaMouseY
*= ACCELERATOR_MULTI
;
1328 switch(GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
) {
1330 iihdata
->DeltaMouseX_Correction
= 0;
1331 iihdata
->DeltaMouseX_Correction
= 0;
1335 /* Remember the delta information which gets lost because of division by PointerTicks.
1336 Will be added to prescaled deltas of next mousemove event. If this is not done, moving
1337 the mouse very slowly would cause it to not move at all */
1339 iihdata
->DeltaMouseX_Correction
= iihdata
->DeltaMouseX
% GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
1340 iihdata
->DeltaMouseY_Correction
= iihdata
->DeltaMouseY
% GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
1342 iihdata
->DeltaMouseX
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
1343 iihdata
->DeltaMouseY
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
1348 ie
->ie_X
= iihdata
->DeltaMouseX
+ IntuitionBase
->MouseX
;
1349 ie
->ie_Y
= iihdata
->DeltaMouseY
+ IntuitionBase
->MouseY
;
1351 DEBUG_MOUSE(bug("[Inputhandler] Last mouse position: (%d, %d), new mouse position: (%d, %d)\n",
1352 IntuitionBase
->MouseX
, IntuitionBase
->MouseY
, ie
->ie_X
, ie
->ie_Y
));
1353 iihdata
->DeltaMouseX
= ie
->ie_X
- IntuitionBase
->MouseX
;
1354 iihdata
->DeltaMouseY
= ie
->ie_Y
- IntuitionBase
->MouseY
;
1355 DEBUG_MOUSE(bug("[InputHandler] Delta is (%d, %d)\n", iihdata
->DeltaMouseX
, iihdata
->DeltaMouseY
));
1358 /* Calculate current display size.
1359 It's determined by the first screen on this monitor.
1360 TODO: perhaps we should just ask display driver about its current display mode? */
1361 scr
= FindFirstScreen(GetPrivIBase(IntuitionBase
)->ActiveMonitor
, IntuitionBase
);
1364 DWidth
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxX
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinX
+ 1;
1365 DHeight
= scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MaxY
- scr
->ViewPort
.ColorMap
->cm_vpe
->DisplayClip
.MinY
+ 1;
1369 /* If there's no active screen, we take 160x160 as a limit */
1374 scr
= iihdata
->ScreenDrag
;
1376 WORD dx
= iihdata
->DeltaMouseX
;
1377 WORD dy
= iihdata
->DeltaMouseY
;
1379 UWORD spFlags
= GetPrivScreen(scr
)->SpecialFlags
;
1380 UWORD DragMode
= GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_VDragModes
[0];
1382 DEBUG_DRAG(bug("[InputHandler] Screen drag, delta is (%d, %d)\n", dx
, dy
));
1384 /* Restrict dragging to a physical display area if the driver does not allow composition or if the user wants it*/
1385 if (((spFlags
& SF_HorCompose
) != SF_HorCompose
) || (DragMode
& ICVDM_HBOUND
)) {
1386 /* Calculate limits */
1387 if (scr
->Width
> DWidth
) {
1388 min
= DWidth
- scr
->Width
;
1392 max
= DWidth
- scr
->Width
;
1394 /* The purpose of the following complex check is to prevent jumping if the
1395 screen was positioned out of user drag limits by the program itself using
1396 ScreenPosition() or OpenScreen(). We apply restrictions in parts depending
1397 on the dragging direction.
1398 Maybe the user should also be able to drag the screen back off-display in such
1400 Calculate the position we would go to */
1401 val
= scr
->LeftEdge
+ dx
;
1402 /* Determine the direction */
1403 if ((dx
< 0) && ((!(spFlags
& SF_ComposeRight
)) || (DragMode
& ICVDM_LBOUND
))) {
1404 /* Can we move at all in this direction ? */
1405 if (scr
->LeftEdge
> min
) {
1406 /* If too far, restrict it */
1408 dx
= min
- scr
->LeftEdge
;
1410 /* Just don't move if we can't */
1412 } else if ((!(spFlags
& SF_ComposeLeft
)) || (DragMode
& ICVDM_RBOUND
)) {
1413 if (scr
->LeftEdge
< max
) {
1415 dx
= max
- scr
->LeftEdge
;
1420 if (((spFlags
& SF_VertCompose
) != SF_VertCompose
) || (DragMode
& ICVDM_VBOUND
)) {
1421 DEBUG_DRAG(bug("[Inputhandler] Restricting vertical drag\n"));
1422 DEBUG_DRAG(bug("[Inputhandler] Screen size: %d, display size: %d\n", scr
->Height
, DHeight
));
1423 if (scr
->Height
> DHeight
) {
1424 min
= DHeight
- scr
->Height
;
1428 max
= DHeight
- scr
->Height
;
1430 DEBUG_DRAG(bug("[Inputhandler] Limits: min %d max %d\n", min
, max
));
1431 val
= scr
->TopEdge
+ dy
;
1432 DEBUG_DRAG(bug("[Inputhandler] New position would be %d\n", val
));
1433 if ((dy
< 0) && ((!(spFlags
& SF_ComposeBelow
)) || (DragMode
& ICVDM_TBOUND
))) {
1434 if (scr
->TopEdge
> min
) {
1436 dy
= min
- scr
->TopEdge
;
1439 } else if ((!(spFlags
& SF_ComposeAbove
)) || (DragMode
& ICVDM_BBOUND
)) {
1440 if (scr
->TopEdge
< max
) {
1442 dy
= max
- scr
->TopEdge
;
1446 DEBUG_DRAG(bug("[Inputhandler] Restricted delta will be %d\n", dy
));
1448 ScreenPosition(scr
, SPOS_RELATIVE
, dx
, dy
, 0, 0);
1451 /* Autoscroll the active screen */
1452 scr
= IntuitionBase
->ActiveScreen
;
1453 if (scr
&& (scr
->Flags
& AUTOSCROLL
) &&
1454 (GetPrivScreen(scr
)->MonitorObject
== GetPrivIBase(IntuitionBase
)->ActiveMonitor
))
1456 WORD xval
= scr
->LeftEdge
;
1457 WORD yval
= scr
->TopEdge
;
1460 DEBUG_AUTOSCROLL(bug("[Inputhandler] Autoscroll screen 0x%p, event at (%d, %d)\n",
1461 scr
, ie
->ie_X
, ie
->ie_Y
));
1463 if ((ie
->ie_X
< 0) || (ie
->ie_X
>= DWidth
)) {
1464 DEBUG_AUTOSCROLL(bug("[InputHandler] X delta: %d pixels\n", iihdata
->DeltaMouseX
));
1465 xval
-= iihdata
->DeltaMouseX
;
1470 } else if (ie
->ie_X
>= DWidth
) {
1471 min
= DWidth
- scr
->Width
;
1477 if ((ie
->ie_Y
< 0) || (ie
->ie_Y
>= DHeight
)) {
1478 yval
-= iihdata
->DeltaMouseY
;
1481 /* If screen is dragged down and user touched upper screen
1482 boundary, do nothing */
1483 if (scr
->TopEdge
>= 0)
1484 yval
= scr
->TopEdge
;
1486 /* If scrolled down screen is being scrolled up, make sure it
1487 does not go over 0 */
1490 } else if (ie
->ie_Y
>= DHeight
) {
1491 min
= DHeight
- scr
->Height
;
1497 if ((xval
!= scr
->LeftEdge
) || (yval
!= scr
->TopEdge
))
1498 ScreenPosition(scr
, SPOS_ABSOLUTE
, xval
, yval
, 0, 0);
1501 /* Restrict mouse coordinates to the physical display area */
1502 if (ie
->ie_X
>= DWidth
) ie
->ie_X
= DWidth
- 1;
1503 if (ie
->ie_Y
>= DHeight
) ie
->ie_Y
= DHeight
- 1;
1504 if (ie
->ie_X
< 0) ie
->ie_X
= 0;
1505 if (ie
->ie_Y
< 0) ie
->ie_Y
= 0;
1508 if (gadget
== iihdata
->MasterDragGadget
) {
1512 gpi
.MethodID
= GM_MOVETEST
;
1514 gpi
.gpi_Mouse
.X
= ie
->ie_X
- gi
->gi_Window
->WScreen
->LeftEdge
;
1515 gpi
.gpi_Mouse
.Y
= ie
->ie_Y
- gi
->gi_Window
->WScreen
->TopEdge
;
1516 gpi
.gpi_IEvent
= ie
;
1518 retval
= Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpi
, IntuitionBase
);
1519 if (retval
== MOVETEST_ADJUSTPOS
)
1521 ie
->ie_X
= gpi
.gpi_Mouse
.X
+ gi
->gi_Window
->WScreen
->LeftEdge
;
1522 ie
->ie_Y
= gpi
.gpi_Mouse
.Y
+ gi
->gi_Window
->WScreen
->TopEdge
;
1527 /* Do Mouse Bounding - mouse will be most restrictive of screen size or mouse bounds */
1528 if (iihdata
->MouseBoundsActiveFlag
) {
1529 if (ie
->ie_X
< iihdata
->MouseBoundsLeft
)
1530 ie
->ie_X
= iihdata
->MouseBoundsLeft
;
1531 else if (ie
->ie_X
> iihdata
->MouseBoundsRight
)
1532 ie
->ie_X
= iihdata
->MouseBoundsRight
;
1534 if (ie
->ie_Y
< iihdata
->MouseBoundsTop
)
1535 ie
->ie_Y
= iihdata
->MouseBoundsTop
;
1536 else if (ie
->ie_Y
> iihdata
->MouseBoundsBottom
)
1537 ie
->ie_Y
= iihdata
->MouseBoundsBottom
;
1540 /* Prevent mouse going above all screens */
1541 scr
= FindHighestScreen(IntuitionBase
);
1543 if (ie
->ie_Y
< scr
->TopEdge
)
1544 ie
->ie_Y
= scr
->TopEdge
;
1547 /* Store new mouse coords. If a screen is being dragged, lock drag point */
1548 scr
= iihdata
->ScreenDrag
;
1550 IntuitionBase
->MouseX
= scr
->LeftEdge
+ iihdata
->ScreenDragPointX
;
1551 IntuitionBase
->MouseY
= scr
->TopEdge
+ iihdata
->ScreenDragPointY
;
1553 IntuitionBase
->MouseX
= ie
->ie_X
;
1554 IntuitionBase
->MouseY
= ie
->ie_Y
;
1556 notify_mousemove_screensandwindows(IntuitionBase
);
1557 #if !SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1558 MySetPointerPos(IntuitionBase
);
1560 *call_setpointerpos
= TRUE
;
1563 screen
= FindActiveScreen(IntuitionBase
); /* The mouse was moved, so current screen may have changed */
1567 if (iihdata
->TitlebarOnTop
)
1569 if (screen
->MouseY
> screen
->BarHeight
&& GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
)
1571 iihdata
->TitlebarOnTop
= FALSE
;
1572 iihdata
->TitlebarAppearTime
= 0;
1574 LOCK_REFRESH(screen
);
1576 MoveLayer(0, screen
->BarLayer
, 0, -(screen
->BarHeight
+ 1));
1577 CheckLayers(screen
, IntuitionBase
);
1579 UNLOCK_REFRESH(screen
);
1584 if (screen
->MouseY
== 0 && GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
&& !MENUS_ACTIVE
&& !(PeekQualifier() & (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_RBUTTON
|IEQUALIFIER_MIDBUTTON
)))
1586 if (!(iihdata
->TitlebarAppearTime
))
1588 iihdata
->TitlebarAppearTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1589 iihdata
->TitlebarAppearTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1594 iihdata
->TitlebarAppearTime
= 0;
1600 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1601 *keep_event
= FALSE
;
1606 *keep_event
= FALSE
;
1608 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
1610 case GTYP_BOOLGADGET
:
1611 case 0: //fallback for sucky gadgets
1612 /* Must be a RELVERIFY gadget */
1616 inside
= InsideGadget(gi
->gi_Screen
,
1620 gi
->gi_Screen
->MouseX
,
1621 gi
->gi_Screen
->MouseY
);
1623 if (inside
!= iihdata
->MouseWasInsideBoolGadget
) {
1624 iihdata
->MouseWasInsideBoolGadget
= inside
;
1626 gadget
->Flags
^= GFLG_SELECTED
;
1627 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
1632 case GTYP_PROPGADGET
:
1633 HandlePropMouseMove(gadget
,
1636 w
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
1637 w
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
1642 case GTYP_CUSTOMGADGET
:
1643 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, reuse_event
, IntuitionBase
);
1646 } /* switch GadgetType */
1648 } /* if (a gadget is currently active) */
1650 *keep_event
= FALSE
;
1655 if (IW(w
)->helpflags
& HELPF_GADGETHELP
&& (!(PeekQualifier() & (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_RBUTTON
|IEQUALIFIER_MIDBUTTON
)))) {
1659 hw
= FindActiveWindow(ie
, screen
, 0, IntuitionBase
);
1662 (!hw
|| !(IW(w
)->helpflags
& HELPF_ISHELPGROUP
) ||
1663 !(IW(hw
)->helpflags
& HELPF_ISHELPGROUP
) ||
1664 IW(w
)->helpgroup
!= IW(hw
)->helpgroup
))
1667 if (iihdata
->LastHelpWindow
)
1669 fire_intuimessage(w
,
1675 iihdata
->LastHelpGadget
= NULL
;
1676 iihdata
->LastHelpWindow
= NULL
;
1677 iihdata
->HelpGadgetFindTime
= 0;
1682 g
= FindHelpGadget (hw
,
1683 IntuitionBase
->ActiveScreen
->MouseX
,
1684 IntuitionBase
->ActiveScreen
->MouseY
,
1686 if (g
&& g
!= iihdata
->LastHelpGadget
)
1688 if (!iihdata
->LastHelpGadget
)
1690 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1691 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1693 if (hw
== iihdata
->LastHelpWindow
)
1695 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1696 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1697 iihdata
->HelpGadgetFindTime
+= 25;//smaller delay
1701 else if (g
!= iihdata
->LastHelpGadget
||
1702 hw
!= iihdata
->LastHelpWindow
)
1704 fire_intuimessage(hw
,
1706 0, /* Don't know what it should be */
1711 iihdata
->LastHelpGadget
= g
;
1712 iihdata
->LastHelpWindow
= hw
;
1715 iihdata
->LastHelpGadget
= NULL
;
1716 iihdata
->LastHelpWindow
= NULL
;
1717 iihdata
->HelpGadgetFindTime
= 0;
1720 if (!(w
->IDCMPFlags
& IDCMP_MOUSEMOVE
))
1723 /* Send IDCMP_MOUSEMOVE if WFLG_REPORTMOUSE is set
1724 and/or active gadget has GACT_FOLLOWMOUSE set */
1726 /* jDc: do NOT send when sizegad is pressed */
1727 if (!(w
->Flags
& WFLG_REPORTMOUSE
)) {
1730 if (!(gadget
->Activation
& GACT_FOLLOWMOUSE
))
1733 if (gadget
&& (gadget
->GadgetType
& (GTYP_SIZING
|GTYP_WDRAGGING
)))
1737 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
1739 /* Limit the number of IDCMP_MOUSEMOVE messages sent to intuition.
1740 note that this comes after handling gadgets, because gadgets should get all events.
1743 if (IW(w
)->num_mouseevents
>= IW(w
)->mousequeue
) {
1744 BOOL old_msg_found
= FALSE
;
1746 /* Mouse Queue is full, so try looking for a not
1747 yet GetMsg()ed IntuiMessage in w->UserPort
1748 trying to modify that. */
1753 struct IntuiMessage
*im
;
1755 for (im
= (struct IntuiMessage
*)w
->UserPort
->mp_MsgList
.lh_TailPred
;
1756 im
->ExecMessage
.mn_Node
.ln_Pred
;
1757 im
= (struct IntuiMessage
*)im
->ExecMessage
.mn_Node
.ln_Pred
)
1759 if ((im
->Class
== IDCMP_MOUSEMOVE
) &&
1760 (im
->IDCMPWindow
== w
))
1762 im
->Qualifier
= iihdata
->ActQualifier
;
1764 if (w
->IDCMPFlags
& IDCMP_DELTAMOVE
)
1766 im
->MouseX
= iihdata
->DeltaMouseX
;
1767 im
->MouseY
= iihdata
->DeltaMouseY
;
1771 im
->MouseX
= w
->MouseX
;
1772 im
->MouseY
= w
->MouseY
;
1774 CurrentTime(&im
->Seconds
, &im
->Micros
);
1776 old_msg_found
= TRUE
;
1780 } /* if (w->UserPort) */
1783 /* no need to send a new message if we modified
1784 an existing one ... */
1786 if (old_msg_found
) break;
1788 /* ... otherwise we are in a strange situation. The mouse
1789 queue is full, but we did not find an existing MOUSEMOVE
1790 imsg in w->UserPort. So the app probably has removed
1791 an imsg from the UserPort with GetMsg but we did not get
1792 the ReplyMsg, yet. In this case we do send a new message */
1794 HandleIntuiReplyPort(iihdata
, IntuitionBase
);
1798 /* MouseQueue is not full, so we can send a message. We increase
1799 IntWindow->num_mouseevents which will later be decreased after
1800 the Intuition InputHandler gets the ReplyMessage from the app
1801 and handles it in HandleIntuiReplyPort() */
1803 if (ih_fire_intuimessage(w
, IDCMP_MOUSEMOVE
, IECODE_NOBUTTON
, w
, IntuitionBase
))
1804 IW(w
)->num_mouseevents
++;
1808 } /* case IECODE_NOBUTTON */
1809 } /* switch (ie->ie_Code) (what button was pressed ?) */
1814 /****************************************************************************************/
1816 AROS_UFH2(struct InputEvent
*, IntuiInputHandler
,
1817 AROS_UFHA(struct InputEvent
*, oldchain
, A0
),
1818 AROS_UFHA(struct IIHData
*, iihdata
, A1
)
1823 struct InputEvent
*ie
, *orig_ie
, *next_ie
, stackie
;
1824 struct Gadget
*gadget
= NULL
;
1825 struct IntuitionBase
*IntuitionBase
= iihdata
->IntuitionBase
;
1826 struct Library
*KeymapBase
= GetPrivIBase(IntuitionBase
)->KeymapBase
;
1827 struct Screen
*screen
;
1829 struct GadgetInfo
*gi
= &iihdata
->GadgetInfo
;
1830 BOOL reuse_event
, ie_used
;
1832 struct Requester
*req
;
1833 ULONG stitlebarhit
= 0;
1834 #if 0 /* Toolbox is broken-as-designed */
1835 struct Window
*toolbox
;
1836 struct GadgetInfo
*boxgi
= &iihdata
->BoxGadgetInfo
;
1837 struct Gadget
*boxgadget
= NULL
;
1839 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1840 BOOL call_setpointerpos
= FALSE
;
1843 D(bug("Inside intuition inputhandler, active window=%p\n", IntuitionBase
->ActiveWindow
));
1844 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->InputHandlerLock
);
1846 if (!iihdata
->InputDeviceTask
) iihdata
->InputDeviceTask
= FindTask(NULL
);
1848 /* Then free generated InputEvents done in the previous round */
1850 FreeGeneratedInputEvents(iihdata
);
1852 /* First handle IntuiMessages which were replied back to the IntuiReplyPort
1855 HandleIntuiReplyPort(iihdata
, IntuitionBase
);
1857 /* Handle action messages */
1859 HandleIntuiActions(iihdata
, IntuitionBase
);
1861 /* Now handle the input events */
1864 reuse_event
= FALSE
;
1867 /* shut up the compiler */
1871 gadget
= iihdata
->ActiveGadget
;
1873 while (reuse_event
|| next_ie
)
1875 struct Window
*old_w
;
1876 BOOL keep_event
= TRUE
;
1877 BOOL new_active_window
= FALSE
;
1878 Object
*newmonitor
= GetPrivIBase(IntuitionBase
)->NewMonitor
;
1880 /* Process hosted display activation event (if any).
1881 This is experimental. If this works badly, we'll possibly have to put it into
1882 input events queue */
1884 DEBUG_MONITOR(bug("[Inputhandler] Activating monitor 0x%p\n", newmonitor
));
1885 GetPrivIBase(IntuitionBase
)->NewMonitor
= NULL
;
1886 ActivateMonitor(newmonitor
, -1, -1, IntuitionBase
);
1887 iihdata
->SwitchedMonitor
= TRUE
;
1894 next_ie
= ie
->ie_NextEvent
;
1898 D(bug("iih: Handling event of class %d, code %d\n", ie
->ie_Class
, ie
->ie_Code
));
1899 reuse_event
= FALSE
;
1901 /* If the monitor has been changed, this possibly happened because of mouse click in
1902 its display window. In such a case we have to update current mouse coordinates
1903 from the first absolute mouse event. Otherwise input will misbehave. */
1904 if (iihdata
->SwitchedMonitor
&& (ie
->ie_Class
== IECLASS_RAWMOUSE
)) {
1905 iihdata
->SwitchedMonitor
= FALSE
;
1906 if (!(ie
->ie_Qualifier
& IEQUALIFIER_RELATIVEMOUSE
)) {
1907 DEBUG_MONITOR(bug("[Inputhandler] Adjusting coordinates to (%d, %d)\n", ie
->ie_X
, ie
->ie_Y
));
1908 IntuitionBase
->MouseX
= ie
->ie_X
;
1909 IntuitionBase
->MouseY
= ie
->ie_Y
;
1910 notify_mousemove_screensandwindows(IntuitionBase
);
1914 /* new event, we need to reset this */
1915 screen
= FindActiveScreen(IntuitionBase
);
1916 iihdata
->ActEventTablet
= 0;
1918 /* Set the timestamp in IntuitionBase */
1920 IntuitionBase
->Seconds
= ie
->ie_TimeStamp
.tv_secs
;
1921 IntuitionBase
->Micros
= ie
->ie_TimeStamp
.tv_micro
;
1923 #if 0 /* toolbox stuff disabled. broken. calling LockLayerinfo() for every event is broken. deadlocks */
1924 /* Use event to find the active window */
1926 toolbox
= GetToolBoxWindow(ie
, screen
, IntuitionBase
);
1930 /* Do ToolBox Window Actions */
1931 /* ToolBox Windows supports only a subset of IECLASS Actions */
1932 switch (ie
->ie_Class
) {
1934 case IECLASS_RAWMOUSE
:
1935 boxgadget
= Process_RawMouse(ie
, iihdata
, screen
, toolbox
, boxgadget
, boxgi
, 0, FALSE
, TRUE
,
1936 orig_ie
, &keep_event
, &reuse_event
,
1937 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1938 &call_setpointerpos
,
1943 } /* switch (ie->ie_Class) */
1944 } /* if (toolbox) */
1947 w
= IntuitionBase
->ActiveWindow
;
1949 if (!MENUS_ACTIVE
&& !SYSGADGET_ACTIVE
)
1951 /* lock = LockIBase(0UL); */
1954 if (ie
->ie_Class
== IECLASS_RAWMOUSE
&& ie
->ie_Code
== SELECTDOWN
)
1956 w
= FindActiveWindow(ie
, screen
, &stitlebarhit
, IntuitionBase
);
1957 DEBUG_CLICK(bug("iih:New active window: %p\n", w
));
1965 DEBUG_WINDOW(bug("Activating new window (title %s)\n", w
->Title
? w
->Title
: "<noname>"));
1967 DEBUG_WINDOW(bug("Window activated\n"));
1971 DEBUG_WINDOW(bug("Making active window inactive. Now there's no active window\n"));
1973 new_active_window
= TRUE
;
1974 iihdata
->NewActWindow
= w
;
1977 /* UnlockIBase(lock); */
1979 if (new_active_window
)
1982 (!(GetPrivScreen(w
->WScreen
)->MenuVerifyMsgCount
)) &&
1983 (!(MENUS_ACTIVE
)) && (!(SYSGADGET_ACTIVE
)))
1985 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
1988 case GTYP_CUSTOMGADGET
:
1990 struct gpGoInactive gpgi
;
1992 gpgi
.MethodID
= GM_GOINACTIVE
;
1993 gpgi
.gpgi_GInfo
= gi
;
1994 gpgi
.gpgi_Abort
= 1;
1996 Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpgi
, IntuitionBase
);
2000 case GTYP_STRGADGET
:
2001 gadget
->Flags
&= ~GFLG_SELECTED
;
2002 RefreshStrGadget(gadget
, gi
->gi_Window
, gi
->gi_Requester
, IntuitionBase
);
2005 case GTYP_BOOLGADGET
:
2006 /* That a bool gadget is active here can only happen
2007 if user used LMB to activate gadget and LAMIGA + LALT
2008 to activate other window, or viceversa */
2009 /* The gadget must be a RELVERIFY one */
2010 if (!(gadget
->Activation
& GACT_TOGGLESELECT
))
2014 inside
= InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
2015 gi
->gi_Requester
, gadget
,
2016 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
);
2020 gadget
->Flags
&= ~GFLG_SELECTED
;
2021 RefreshBoolGadgetState(gadget
, gi
->gi_Window
,
2022 gi
->gi_Requester
, IntuitionBase
);
2027 case GTYP_PROPGADGET
:
2028 /* That a prop gadget is active here can only happen
2029 if user used LMB to activate gadget and LAMIGA + LALT
2030 to activate other window, or viceversa */
2032 HandlePropSelectUp(gadget
, gi
->gi_Window
, NULL
, IntuitionBase
);
2033 if (gadget
->Activation
& GACT_RELVERIFY
)
2035 ih_fire_intuimessage(gi
->gi_Window
,
2043 } /* switch (gadget->GadgetType & GTYP_GTYPEMASK) */
2045 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
2046 iihdata
->ActiveGadget
= NULL
;
2050 /* ActivateWindow works if w = NULL */
2051 /* jacaDcaps: some gui toolkits (die reaction, die!) close the window opened by a boopsi gadget when
2052 it gets hit with lmb, so we need to check if the new active window does not go away by
2053 performing GM_GOINACTIVE on the gadget. NOTE: CloseWindow's part performed on input.device context
2054 clears the iihdata->NewActWindow if it's the actually closed one. */
2055 if (w
== iihdata
->NewActWindow
)
2061 w
= IntuitionBase
->ActiveWindow
;
2062 new_active_window
= FALSE
;
2063 ie
->ie_Class
= IECLASS_NULL
; //lose the event, otherwise the gadget will get activated again ;)
2066 iihdata
->NewActWindow
= 0;
2068 } /* if (new_active_window) */
2070 } /* if (!MENUS_ACTIVE) */
2075 req
= w
->FirstRequest
;
2078 D(bug("[Inputhandler] Screen 0x%p Window 0x%p Requester 0x%p gadget 0x%p\n", screen
, w
, req
, gadget
));
2080 switch (ie
->ie_Class
) {
2081 case IECLASS_POINTERPOS
:
2082 ie
->ie_SubClass
= IESUBCLASS_COMPATIBLE
;
2085 case IECLASS_NEWPOINTERPOS
:
2086 switch (ie
->ie_SubClass
)
2088 case IESUBCLASS_COMPATIBLE
:
2089 ie
->ie_Code
= IECODE_NOBUTTON
;
2092 case IESUBCLASS_PIXEL
:
2094 struct IEPointerPixel
*pp
= ie
->ie_EventAddress
;
2096 ie
->ie_X
= pp
->iepp_Position
.X
+ pp
->iepp_Screen
->LeftEdge
;
2097 ie
->ie_Y
= pp
->iepp_Position
.Y
+ pp
->iepp_Screen
->TopEdge
;
2099 ActivateMonitor(GetPrivScreen(pp
->iepp_Screen
)->MonitorObject
, ie
->ie_X
, ie
->ie_Y
, IntuitionBase
);
2101 ie
->ie_Class
= IECLASS_RAWMOUSE
; /* otherwise a lot of code would ignore this message */
2102 ie
->ie_Code
= IECODE_NOBUTTON
;
2105 case IESUBCLASS_TABLET
:
2107 //unsupported - does anything use it anyway? ;)
2112 case IESUBCLASS_NEWTABLET
:
2114 struct IENewTablet
*nt
= (struct IENewTablet
*)ie
->ie_EventAddress
;
2118 iihdata
->ActEventTablet
= nt
; //cache this
2119 ie
->ie_X
= (screen
->Width
* nt
->ient_TabletX
) / nt
->ient_RangeX
;
2120 ie
->ie_Y
= (screen
->Height
* nt
->ient_TabletY
) / nt
->ient_RangeY
;
2122 ie
->ie_Class
= IECLASS_RAWMOUSE
;
2132 case IECLASS_RAWMOUSE
:
2133 gadget
= Process_RawMouse(ie
, iihdata
, screen
, w
, gadget
, gi
, stitlebarhit
, new_active_window
, FALSE
,
2134 orig_ie
, &keep_event
, &reuse_event
,
2135 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
2136 &call_setpointerpos
,
2142 case IECLASS_RAWKEY
:
2143 /* release events go only to gadgets and windows who
2144 have not set IDCMP_VANILLAKEY */
2146 DEBUG_HANDLER(dprintf("Handler: IECLASS_RAWKEY\n"));
2147 DEBUG_KEY(dprintf("Handler: Qual 0x%lx\n",iihdata
->ActQualifier
));
2149 iihdata
->ActQualifier
&= ~(KEY_QUALIFIERS
| IEQUALIFIER_REPEAT
);
2150 iihdata
->ActQualifier
|= (ie
->ie_Qualifier
& (KEY_QUALIFIERS
| IEQUALIFIER_REPEAT
));
2152 DEBUG_KEY(dprintf("Handler: real Qual 0x%lx\n",iihdata
->ActQualifier
));
2154 /* Keyboard mouse emulation and screen switching */
2157 UWORD code
= ie
->ie_Code
& ~IECODE_UP_PREFIX
;
2158 DEBUG_KEY(dprintf("Handler: code 0x%lx\n",code
));
2160 /* Left Amiga + N/M screen switching shortcut */
2161 if ((ie
->ie_Qualifier
& IEQUALIFIER_LCOMMAND
) && (code
== RAWKEY_N
|| code
== RAWKEY_M
)) {
2162 if (!(ie
->ie_Qualifier
& IEQUALIFIER_REPEAT
) && !(ie
->ie_Code
& IECODE_UP_PREFIX
)) {
2163 if (code
== RAWKEY_N
)
2165 else if (code
== RAWKEY_M
)
2166 ScreenToBack(IntuitionBase
->FirstScreen
);
2172 /* Mouse button emulation: LALT + LAMIGA = LBUTTON, RALT + RAMIGA = RBUTTON */
2173 if ((code
== RAWKEY_LAMIGA
) ||
2174 (code
== RAWKEY_LALT
) ||
2175 (code
== RAWKEY_RAMIGA
) ||
2176 (code
== RAWKEY_RALT
))
2178 DEBUG_KEY(dprintf("Handler: KeyMouseEmul\n"));
2179 iihdata
->PrevKeyMouseState
= iihdata
->ActKeyMouseState
;
2180 iihdata
->ActKeyMouseState
= 0;
2181 if ((ie
->ie_Qualifier
& (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_LALT
)) == (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_LALT
))
2183 iihdata
->ActKeyMouseState
|= IEQUALIFIER_LEFTBUTTON
;
2185 if ((ie
->ie_Qualifier
& (IEQUALIFIER_RCOMMAND
| IEQUALIFIER_RALT
)) == (IEQUALIFIER_RCOMMAND
| IEQUALIFIER_RALT
))
2187 iihdata
->ActKeyMouseState
|= IEQUALIFIER_RBUTTON
;
2190 if ((iihdata
->ActKeyMouseState
& IEQUALIFIER_LEFTBUTTON
) != (iihdata
->PrevKeyMouseState
& IEQUALIFIER_LEFTBUTTON
))
2192 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2193 orig_ie
->ie_SubClass
= 0;
2194 orig_ie
->ie_Code
= (iihdata
->ActKeyMouseState
& IEQUALIFIER_LEFTBUTTON
) ? IECODE_LBUTTON
: IECODE_LBUTTON
| IECODE_UP_PREFIX
;
2203 if ((iihdata
->ActKeyMouseState
& IEQUALIFIER_RBUTTON
) != (iihdata
->PrevKeyMouseState
& IEQUALIFIER_RBUTTON
))
2205 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2206 orig_ie
->ie_SubClass
= 0;
2207 orig_ie
->ie_Code
= (iihdata
->ActKeyMouseState
& IEQUALIFIER_RBUTTON
) ? IECODE_RBUTTON
: IECODE_RBUTTON
| IECODE_UP_PREFIX
;
2216 } /* if key is one of LAMIGA/LALT/RAMIGA/RALT */
2218 if ((iihdata
->ActQualifier
& (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_RCOMMAND
)) &&
2219 ((ie
->ie_Code
== RAWKEY_UP
) ||
2220 (ie
->ie_Code
== RAWKEY_DOWN
) ||
2221 (ie
->ie_Code
== RAWKEY_LEFT
) ||
2222 (ie
->ie_Code
== RAWKEY_RIGHT
)))
2224 static BYTE
const xmap
[] = { 0, 0, 1, -1};
2225 static BYTE
const ymap
[] = {-1, 1, 0, 0};
2228 shift
= (iihdata
->ActQualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) ? 40 : 1;
2230 /* Mouse Move Emulation */
2232 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2233 orig_ie
->ie_SubClass
= 0;
2234 orig_ie
->ie_Code
= IECODE_NOBUTTON
;
2235 orig_ie
->ie_Qualifier
= IEQUALIFIER_RELATIVEMOUSE
;
2236 orig_ie
->ie_X
= xmap
[code
- RAWKEY_UP
] * shift
;
2237 orig_ie
->ie_Y
= ymap
[code
- RAWKEY_UP
] * shift
;
2246 /* End Keyboard mouse emulation */
2250 DEBUG_KEY(dprintf("Handler: FireMenuMessage\n"));
2251 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2256 /* Hotkeys processing */
2261 if (!(ie
->ie_Code
& IECODE_UP_PREFIX
))
2262 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
2264 if (result
== RUNHOTREUSE
)
2274 w
= IntuitionBase
->ActiveWindow
;
2279 ((!(ie
->ie_Code
& IECODE_UP_PREFIX
)) ||
2281 (w
&& ((w
->IDCMPFlags
& IDCMP_VANILLAKEY
) == 0)) ))
2287 DEBUG_KEY(dprintf("Handler: Gadget 0x%lx active\n",gadget
));
2288 DEBUG_KEY(dprintf("Handler: GadgetID 0x%lx UserData 0x%lx\n",
2291 DEBUG_KEY(dprintf("Handler: GadgetType 0x%lx Flags 0x%lx Activation 0x%lx\n",
2294 gadget
->Activation
));
2295 DEBUG_KEY(dprintf("Handler: MoreFlags 0x%lx\n",
2296 ((struct ExtGadget
*)gadget
)->MoreFlags
));
2298 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
2300 case GTYP_STRGADGET
:
2303 ULONG ret
= HandleStrInput(gadget
, gi
, ie
, &imsgcode
,
2306 DEBUG_KEY(dprintf("Handler: Key GTYP_STRGADGET ret 0x%lx\n",ret
));
2307 if (ret
& (SGA_END
| SGA_NEXTACTIVE
| SGA_PREVACTIVE
))
2309 if (gadget
->Activation
& GACT_RELVERIFY
)
2311 DEBUG_KEY(dprintf("Handler: GACT_RELVERIFY\n"));
2312 ih_fire_intuimessage(w
,
2318 if (req
&& gadget
->Activation
& GACT_ENDGADGET
)
2320 DEBUG_KEY(dprintf("Handler: GACT_ENDGADGET\n"));
2323 req
= w
->FirstRequest
;
2328 if ((gadget
->Flags
& GFLG_TABCYCLE
) && (ret
& SGA_NEXTACTIVE
))
2330 gadget
= FindCycleGadget(w
, req
, gadget
, GMR_NEXTACTIVE
);
2331 DEBUG_KEY(dprintf("Handler: TabCycle next gadget 0x%lx\n",gadget
));
2333 else if ((gadget
->Flags
& GFLG_TABCYCLE
) && (ret
& SGA_PREVACTIVE
))
2335 gadget
= FindCycleGadget(w
, req
, gadget
, GMR_PREVACTIVE
);
2336 DEBUG_KEY(dprintf("Handler: TabCycle prev gadget 0x%lx\n",gadget
));
2345 gadget
= DoActivateGadget(w
, req
, gadget
, IntuitionBase
);
2348 } /* if (ret & (SGA_END | SGA_NEXTACTIVE | SGA_PREVACTIVE)) */
2353 case GTYP_CUSTOMGADGET
:
2354 DEBUG_KEY(dprintf("Handler: GTYP_CUSTOMGADGET\n"));
2355 DEBUG_KEY(dprintf("Handler: send GM_HANDLEINPUT\n"));
2356 gadget
= DoGPInput(gi
,
2362 DEBUG_KEY(dprintf("Handler: reuse %ld\n",reuse_event
));
2365 } /* switch (gadget type) */
2367 } /* if (a gadget is currently active) */
2368 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
))
2370 BOOL menushortcut
= FALSE
;
2372 DEBUG_KEY(dprintf("Handler: No Gadget active\n"));
2373 DEBUG_KEY(dprintf("Handler: Qualifier 0x%lx WinFlags 0x%lx IDCMP 0x%lx\n",ie
->ie_Qualifier
,w
->Flags
,w
->IDCMPFlags
));
2375 if ((ie
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
) &&
2376 (!(w
->Flags
& WFLG_RMBTRAP
)) &&
2377 (w
->IDCMPFlags
& IDCMP_MENUPICK
))
2379 struct Menu
*strip
= 0;
2381 DEBUG_KEY(dprintf("Handler: MenuKey\n"));
2382 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2384 strip
= w
->MenuStrip
;
2386 if (((struct IntWindow
*)w
)->menulendwindow
)
2388 strip
= ((struct IntWindow
*)w
)->menulendwindow
->MenuStrip
;
2391 DEBUG_KEY(dprintf("Handler: MenuStrip 0x%lx\n",strip
));
2396 if (MapRawKey(ie
, &key
, 1, NULL
) == 1)
2400 menucode
= FindMenuShortCut(strip
, key
, TRUE
, IntuitionBase
);
2402 DEBUG_KEY(dprintf("Handler: menucode 0x%lx\n",menucode
));
2404 if (menucode
!= MENUNULL
)
2406 DEBUG_KEY(dprintf("Handler: build menuevent\n"));
2407 ie
->ie_Class
= IECLASS_MENU
;
2408 ie
->ie_SubClass
= IESUBCLASS_MENUSTOP
;
2409 ie
->ie_EventAddress
= w
;
2410 ie
->ie_Code
= menucode
;
2413 menushortcut
= TRUE
;
2415 MENUS_ACTIVE
= TRUE
;
2416 iihdata
->MenuWindow
= w
;
2421 DEBUG_KEY(dprintf("Handler: MapRawKey failed\n"));
2424 if (!menushortcut
) /* !! */
2425 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2427 } /* if could be a menu short cut */
2429 if ((ie
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
) &&
2430 (!(w
->IDCMPFlags
& IDCMP_MENUPICK
)))
2432 struct Menu
*strip
= 0;
2433 struct Window
*window
= w
;
2435 /* not sure here about RMBTRAP */
2436 DEBUG_KEY(dprintf("Handler: no idcmp, create a MENULIST idcmp\n"));
2438 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2440 strip
= w
->MenuStrip
;
2442 if (((struct IntWindow
*)w
)->menulendwindow
)
2444 strip
= ((struct IntWindow
*)w
)->menulendwindow
->MenuStrip
;
2445 window
= ((struct IntWindow
*)w
)->menulendwindow
;
2448 DEBUG_KEY(dprintf("Handler: MenuStrip 0x%lx\n",strip
));
2453 if (MapRawKey(ie
, &key
, 1, NULL
) == 1)
2457 menucode
= FindMenuShortCut(strip
, key
, TRUE
, IntuitionBase
);
2459 DEBUG_KEY(dprintf("Handler: menucode 0x%lx\n",menucode
));
2461 if (menucode
!= MENUNULL
)
2463 DEBUG_KEY(dprintf("Handler: build menuevent\n"));
2464 ih_fire_intuimessage(window
,
2467 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machines!? */
2470 menushortcut
= TRUE
;
2475 DEBUG_KEY(dprintf("Handler: MapRawKey failed\n"));
2478 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2479 } /* if could be a menu short but current window has no idcmp cut */
2483 DEBUG_KEY(dprintf("Handler: menu shortcut..break\n"));
2487 /* This is a regular RAWKEY event (no gadget taking care
2490 if (iihdata
->ActQualifier
& IEQUALIFIER_REPEAT
)
2492 /* don't send repeat key events if repeatqueue is full */
2493 if (IW(w
)->num_repeatevents
>= IW(w
)->repeatqueue
)
2495 DEBUG_KEY(dprintf("Handler: RepeatEvents full..don't send more\n"));
2500 if (w
->IDCMPFlags
& IDCMP_VANILLAKEY
)
2504 DEBUG_KEY(dprintf("Handler: VANILLAKEY\n"));
2505 // DEBUG_KEY(dprintf("Handler: MapRawKey ie 0x%lx KeyMapBase 0x%lx IntutionBase 0x%lx\n",ie,KeymapBase,IntuitionBase));
2507 if (MapRawKey(ie
, &keyBuffer
, 1, NULL
) == 1)
2509 DEBUG_KEY(dprintf("Handler: send VANILLAKEY msg\n"));
2510 ih_fire_intuimessage(w
,
2513 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machines!? */
2515 DEBUG_KEY(dprintf("Handler: done\n"));
2519 /* If the event mapped to more than one byte, it is not
2520 a legal VANILLAKEY, so we send it as the original
2525 if (w
->IDCMPFlags
& IDCMP_RAWKEY
)
2527 DEBUG_KEY(dprintf("Handler: send IDCMP_RAWKEY Qual 0x%lx Code 0x%lx addr 0x%lx Event\n",
2528 ie
->ie_Qualifier
,ie
->ie_Code
,ie
->ie_position
.ie_addr
));
2529 ih_fire_intuimessage(w
,
2532 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machine!? */
2537 DEBUG_KEY(dprintf("Handler: done\n"));
2538 } /* regular RAWKEY */
2541 break; /* case IECLASS_RAWKEY */
2544 if (iihdata
->MouseBoundsKillTimer
)
2546 iihdata
->MouseBoundsKillTimer
--;
2547 if (iihdata
->MouseBoundsKillTimer
== 0)
2549 iihdata
->MouseBoundsActiveFlag
= FALSE
;
2553 if (GetPrivIBase(IntuitionBase
)->PointerDelay
)
2555 ULONG lock
= LockIBase(0);
2557 if (--GetPrivIBase(IntuitionBase
)->PointerDelay
== 0)
2559 struct SharedPointer
*shared_pointer
;
2560 struct Window
*window
= IntuitionBase
->ActiveWindow
;
2561 struct IntScreen
*scr
;
2562 Object
*pointer
= ((struct IntWindow
*)window
)->pointer
;
2564 DEBUG_POINTER(dprintf("InputHandler: PointerDelay\n"));
2565 DEBUG_POINTER(dprintf("InputHandler: Pointer 0x%lx\n",
2570 DEBUG_POINTER(dprintf("InputHandler: Window 0x%lx\n",
2572 scr
= GetPrivScreen(window
->WScreen
);
2575 DEBUG_POINTER(dprintf("InputHandler: Screen 0x%lx\n",
2577 if (pointer
== NULL
)
2579 pointer
= GetPrivIBase(IntuitionBase
)->DefaultPointer
;
2582 if (((struct IntWindow
*)window
)->busy
)
2584 pointer
= GetPrivIBase(IntuitionBase
)->BusyPointer
;
2587 GetAttr(POINTERA_SharedPointer
, pointer
, (IPTR
*) &shared_pointer
);
2589 DEBUG_POINTER(dprintf("InputHandler: scr 0x%lx pointer 0x%lx shared_pointer 0x%lx\n",
2590 scr
, pointer
, shared_pointer
));
2591 DEBUG_POINTER(dprintf("InputHandler: sprite 0x%lx\n",
2592 shared_pointer
->sprite
));
2594 if (DoMethod(scr
->MonitorObject
, MM_SetPointerShape
, shared_pointer
))
2596 ObtainSharedPointer(shared_pointer
, IntuitionBase
);
2597 ReleaseSharedPointer(scr
->Pointer
, IntuitionBase
);
2598 scr
->Pointer
= shared_pointer
;
2601 window
->XOffset
= shared_pointer
->xoffset
;
2602 window
->YOffset
= shared_pointer
->yoffset
;
2607 DEBUG_POINTER(dprintf("InputHandler: can't set pointer.\n"));
2612 DEBUG_POINTER(dprintf("InputHandler: no screen.\n"));
2617 DEBUG_POINTER(dprintf("InputHandler: no window.\n"));
2624 if (GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
)
2626 struct IntScreen
*scr
= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
;
2628 if ((--scr
->MenuVerifyTimeOut
) <= 0)
2630 struct InputEvent ie
;
2632 /* currently we ONLY need the menu open time ! */
2633 ie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
2634 ie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
2636 if (FireMenuMessage(MMCODE_START
, scr
->MenuVerifyActiveWindow
, &ie
, IntuitionBase
))
2638 /* This lock will be released only when the user is
2639 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
2640 event arrives (generated by MenuHandler task) */
2642 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2643 iihdata
->MenuWindow
= scr
->MenuVerifyActiveWindow
;
2644 MENUS_ACTIVE
= TRUE
;
2647 scr
->MenuVerifyActiveWindow
= NULL
;
2648 scr
->MenuVerifyTimeOut
= 0;
2649 scr
->MenuVerifyMsgCount
= 0;
2650 scr
->MenuVerifySeconds
= 0;
2651 scr
->MenuVerifyMicros
= 0;
2652 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
2655 else if (MENUS_ACTIVE
)
2657 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2663 if (screen
->MouseY
<= screen
->BarHeight
&& GetPrivScreen(screen
)->SpecialFlags
& SF_AppearingBar
&& !iihdata
->TitlebarOnTop
&& iihdata
->TitlebarAppearTime
)
2665 UQUAD currenttime
= (((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50) + (UQUAD
)(ie
->ie_TimeStamp
.tv_micro
/ 20000);
2666 if (currenttime
>= iihdata
->TitlebarAppearTime
+ 10)
2668 iihdata
->TitlebarOnTop
= TRUE
;
2669 iihdata
->TitlebarAppearTime
= 0;
2671 LOCK_REFRESH(screen
);
2673 MoveLayer(0, screen
->BarLayer
, 0, screen
->BarHeight
+ 1);
2674 UpfrontLayer(0, screen
->BarLayer
);
2675 CheckLayers(screen
, IntuitionBase
);
2677 UNLOCK_REFRESH(screen
);
2683 UQUAD currenttime
= (((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50) + (UQUAD
)(ie
->ie_TimeStamp
.tv_micro
/ 20000);
2684 #define SECONDS(x) (x*50)
2685 if (iihdata
->HelpGadgetFindTime
&& (currenttime
>= iihdata
->HelpGadgetFindTime
+ SECONDS(1)))
2687 struct Gadget
*lhg
= iihdata
->LastHelpGadget
;
2688 fire_intuimessage(iihdata
->LastHelpWindow
,
2690 lhg
? lhg
->GadgetID
: 0, /* Don't know what it should be */
2693 iihdata
->HelpGadgetFindTime
= 0;
2699 if (IS_BOOPSI_GADGET(gadget
))
2701 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
2706 #if USE_NEWDISPLAYBEEP
2708 if (GetPrivIBase(IntuitionBase
)->BeepingScreens
)
2713 lock
= LockIBase(0);
2715 for (scr
= IntuitionBase
->FirstScreen
;
2716 scr
&& GetPrivIBase(IntuitionBase
)->BeepingScreens
;
2717 scr
= scr
->NextScreen
)
2719 if ((scr
->Flags
& BEEPING
) &&
2720 !GetPrivScreen(scr
)->BeepingCounter
--)
2722 GetPrivIBase(IntuitionBase
)->BeepingScreens
--;
2723 scr
->Flags
&= (UWORD
) ~BEEPING
;
2725 /* if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) <= 8)
2726 // visual beep on CLUT-screen
2728 // SetRGB4 (&screen->ViewPort, 0, scr->SaveColor0 & 0x000F, (scr->SaveColor0 & 0x00F0) >> 4, (scr->SaveColor0 & 0x0F00) >> 8);
2729 SetRGB32 (&scr->ViewPort, 0,
2730 GetPrivScreen(scr)->DisplayBeepColor0[0],
2731 GetPrivScreen(scr)->DisplayBeepColor0[1],
2732 GetPrivScreen(scr)->DisplayBeepColor0[2]
2736 // visual beep on hi- and truecolor screens
2738 RenderScreenBar(scr, FALSE, IntuitionBase);
2741 RenderScreenBar(scr
, FALSE
, IntuitionBase
);
2747 #endif /* USE_NEWDISPLAYBEEP */
2751 /* Send INTUITICK msg only if app already replied the last INTUITICK msg */
2752 if (w
->Flags
& WFLG_WINDOWTICKED
) break;
2754 if (w
->IDCMPFlags
& IDCMP_INTUITICKS
)
2756 /* Set the WINDOWTICKED flag, it will be cleared again when the app
2757 replies back the msg and the InputHandler handles the replymsg
2758 in HandleIntuiReplyPort() */
2760 ih_fire_intuimessage(w
,
2766 break; /* case IECLASS_TIMER */
2769 if (MENUS_ACTIVE
&& (ie
->ie_SubClass
== IESUBCLASS_MENUSTOP
))
2771 struct Window
*eventwin
= (struct Window
*)ie
->ie_EventAddress
;
2773 iihdata
->MenuWindow
= NULL
;
2774 MENUS_ACTIVE
= FALSE
;
2776 /* semaphore was locked when menu action started, see
2777 above where MMCODE_START MenuMessage is sent.
2779 It could have also have been locked if the user
2780 activated one of the menu key shortcuts, see
2781 "case IECLASS_RAWKEY" */
2783 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2787 if (((struct IntWindow
*)eventwin
)->menulendwindow
)
2789 eventwin
= ((struct IntWindow
*)eventwin
)->menulendwindow
;
2792 ih_fire_intuimessage((struct Window
*)eventwin
,
2795 (struct Window
*)ie
->ie_EventAddress
,
2801 case IECLASS_DISKINSERTED
:
2802 case IECLASS_DISKREMOVED
:
2803 case IECLASS_NEWPREFS
:
2809 switch (ie
->ie_Class
)
2811 case IECLASS_DISKINSERTED
:
2812 idcmp
= IDCMP_DISKINSERTED
;
2815 case IECLASS_DISKREMOVED
:
2816 idcmp
= IDCMP_DISKREMOVED
;
2820 idcmp
= IDCMP_NEWPREFS
;
2822 * Here we need to update the mouse prefs and
2823 * maybe other stuff which comes from the global prefs file.
2828 lock
= LockIBase(0);
2830 for (scr
= IntuitionBase
->FirstScreen
; scr
; scr
= scr
->NextScreen
)
2834 for (win
= scr
->FirstWindow
; win
; win
= win
->NextWindow
)
2837 CHECKME, really use fire_intuimessage() here,
2838 instead of ih_fireintuimessage? Same for
2839 IDCMP_GADGETHELP above, BTW. */
2841 fire_intuimessage(win
,
2853 case IECLASS_NEWMOUSE
:
2856 * The following is only needed on hardware not running
2857 * the NewMouse driver.
2859 if (w
->IDCMPFlags
& IDCMP_RAWKEY
&& (!SysBase
->MaxLocMem
))
2861 ih_fire_intuimessage(w
,
2864 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machine!? */
2874 case IECLASS_NEWTIMER
:
2877 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2884 if (gadget
== iihdata
->MasterSizeGadget
)
2886 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
2891 #endif /* __MORPHOS__ */
2896 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2903 "[Intui] InputHandler: Unknown IEClass: addr = %x class = %d (origclass = %d)\n",
2904 orig_ie
, ie
->ie_Class
,orig_ie
->ie_Class
2908 } /* switch (ie->ie_Class) */
2913 else if (keep_event
&& !ie_used
)
2915 *iihdata
->EndInputEventChain
= orig_ie
;
2916 iihdata
->EndInputEventChain
= &orig_ie
->ie_NextEvent
;
2921 orig_ie
->ie_NextEvent
= iihdata
->FreeInputEvents
;
2922 iihdata
->FreeInputEvents
= orig_ie
;
2925 } /* for (each event in the chain) */
2927 iihdata
->ActiveGadget
= gadget
;
2929 D(bug("Outside pollingloop\n"));
2931 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
2932 if (call_setpointerpos
)
2933 MySetPointerPos(IntuitionBase
);
2936 /* Terminate the event chain. */
2937 *iihdata
->EndInputEventChain
= NULL
;
2939 /* Transfer the list of allocated events in the list of events that should
2940 * be freed the next time the handler is entered.
2942 iihdata
->AllocatedInputEventList
= iihdata
->NewAllocatedInputEventList
;
2943 NEWLIST((struct List
*)&iihdata
->NewAllocatedInputEventList
);
2945 /* Reset the event chain here, not at the beginning of the handler, for
2946 * events that might be allocated in other handers.
2948 iihdata
->EndInputEventChain
= &iihdata
->ReturnInputEvent
;
2949 iihdata
->FreeInputEvents
= NULL
;
2951 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->InputHandlerLock
);
2953 // DEBUG_HANDLER(dprintf("Handler: ->IBase 0x%lx KeyMapBase 0x%lx\n",IntuitionBase,KeymapBase));
2955 return iihdata
->ReturnInputEvent
;
2960 /****************************************************************************************/