2 Copyright 1995-2003, 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"
44 # include "smallmenu.h"
45 # include "intuition_customizesupport.h"
50 #include <aros/debug.h>
52 #define DEBUG_HANDLER(x) ;
53 #define DEBUG_KEY(x) ;
54 #define DEBUG_SCREENKEY(x) ;
56 /****************************************************************************************/
58 struct Interrupt
*InitIIH(struct IntuitionBase
*IntuitionBase
)
60 struct Interrupt
*iihandler
;
62 D(bug("InitIIH(IntuitionBase=%p)\n", IntuitionBase
));
64 iihandler
= AllocMem(sizeof (struct Interrupt
), MEMF_PUBLIC
| MEMF_CLEAR
);
67 struct IIHData
*iihdata
;
69 iihdata
= AllocMem(sizeof (struct IIHData
), MEMF_PUBLIC
| MEMF_CLEAR
);
74 port
= AllocMem(sizeof (struct MsgPort
), MEMF_PUBLIC
| MEMF_CLEAR
);
77 if ((iihdata
->InputEventMemPool
= CreatePool(MEMF_PUBLIC
| MEMF_CLEAR
,
78 sizeof(struct GeneratedInputEvent
) * 10,
79 sizeof(struct GeneratedInputEvent
) * 10)) &&
80 (iihdata
->ActionsMemPool
= CreatePool(MEMF_SEM_PROTECTED
,
83 const struct TagItem dragtags
[] =
85 {GA_SysGadget
, TRUE
},
86 {GA_SysGType
, GTYP_WDRAGGING
},
90 const struct TagItem sizetags
[] =
92 {GA_SysGadget
, TRUE
},
93 {GA_SysGType
, GTYP_SIZING
},
97 iihdata
->MasterDragGadget
= (struct Gadget
*)NewObjectA(GetPrivIBase(IntuitionBase
)->dragbarclass
,
101 iihdata
->MasterSizeGadget
= (struct Gadget
*)NewObjectA(GetPrivIBase(IntuitionBase
)->sizebuttonclass
,
105 if (iihdata
->MasterDragGadget
&& iihdata
->MasterSizeGadget
)
109 /* We do not want to be woken up by message replies.
110 We are anyway woken up about 10 times a second by
113 port
->mp_Flags
= PA_IGNORE
;
115 NEWLIST( &(port
->mp_MsgList
) );
116 iihdata
->IntuiReplyPort
= port
;
118 NEWLIST((struct List
*) &iihdata
->IntuiActionQueue
);
119 NEWLIST((struct List
*)&iihdata
->NewAllocatedInputEventList
);
120 NEWLIST((struct List
*)&iihdata
->AllocatedInputEventList
);
121 iihdata
->EndInputEventChain
= &iihdata
->ReturnInputEvent
;
122 iihdata
->FreeInputEvents
= NULL
;
124 iihdata
->ActQualifier
= IEQUALIFIER_RELATIVEMOUSE
;
126 /* Note: there are several routines like CloseWindow, which
127 expect is_Data to point to the IIHData structure, so don't
130 iihandler
->is_Code
= (APTR
)AROS_ASMSYMNAME(IntuiInputHandler
);
131 iihandler
->is_Data
= iihdata
;
132 iihandler
->is_Node
.ln_Pri
= 50;
133 iihandler
->is_Node
.ln_Name
= "Intuition InputHandler";
135 lock
= LockIBase(0UL);
137 iihdata
->IntuitionBase
= IntuitionBase
;
141 GetPrivIBase(IntuitionBase
)->IntuiReplyPort
= iihdata
->IntuiReplyPort
;
142 GetPrivIBase(IntuitionBase
)->IntuiActionQueue
= &iihdata
->IntuiActionQueue
;
144 ReturnPtr ("InitIIH", struct Interrupt
*, iihandler
);
145 } /* f (iihdata->MasterDragGadget && iihdata->MasterSizeGadget) */
147 DisposeObject((Object
*)iihdata
->MasterDragGadget
);
148 DisposeObject((Object
*)iihdata
->MasterSizeGadget
);
150 DeletePool(iihdata
->ActionsMemPool
);
151 DeletePool(iihdata
->InputEventMemPool
);
153 } /* if (iihdata->InputEventMemPool = ... */
154 FreeMem(port
, sizeof(struct MsgPort
));
157 FreeMem(iihdata
, sizeof (struct IIHData
));
158 iihdata
->MouseBoundsActiveFlag
= FALSE
;
161 FreeMem(iihandler
, sizeof (struct Interrupt
));
163 } /* if (iihandler) */
165 ReturnPtr ("InitIIH", struct Interrupt
*, NULL
);
168 /****************************************************************************************/
170 VOID
CleanupIIH(struct Interrupt
*iihandler
, struct IntuitionBase
*IntuitionBase
)
172 struct IIHData
*iihdata
= (struct IIHData
*)iihandler
->is_Data
;
174 DisposeObject((Object
*)iihdata
->MasterDragGadget
);
175 DisposeObject((Object
*)iihdata
->MasterSizeGadget
);
177 FreeGeneratedInputEvents(iihdata
);
178 DeletePool(iihdata
->InputEventMemPool
);
179 DeletePool(iihdata
->ActionsMemPool
);
181 /* One might think that this port is still in use by the inputhandler.
182 ** However, if intuition is closed for the last time, there should be no
183 ** windows that IntuiMessage can be sent to.
185 FreeMem(iihdata
->IntuiReplyPort
, sizeof (struct MsgPort
));
187 FreeMem(iihdata
, sizeof (struct IIHData
));
188 FreeMem(iihandler
, sizeof (struct Interrupt
));
193 /****************************************************************************************/
195 static void HandleIntuiReplyPort(struct IIHData
*iihdata
, struct IntuitionBase
*IntuitionBase
)
197 struct IntuiMessage
*im
;
199 while ((im
= (struct IntuiMessage
*)GetMsg(iihdata
->IntuiReplyPort
)))
201 if (im
->IDCMPWindow
&& ResourceExisting(im
->IDCMPWindow
, RESOURCE_WINDOW
, IntuitionBase
))
203 struct IntWindow
*win
= (struct IntWindow
*)im
->IDCMPWindow
;
206 GetSysTime(&win
->lastmsgreplied
);
211 case IDCMP_MOUSEMOVE
:
212 IW(im
->IDCMPWindow
)->num_mouseevents
--;
215 case IDCMP_INTUITICKS
:
216 AROS_ATOMIC_AND(im
->IDCMPWindow
->Flags
, ~WFLG_WINDOWTICKED
);
219 #if USE_IDCMPUPDATE_MESSAGECACHE
220 case IDCMP_IDCMPUPDATE
:
221 IW(im
->IDCMPWindow
)->num_idcmpupdate
--;
223 if (!(IW(im
->IDCMPWindow
)->num_idcmpupdate
) && IW(im
->IDCMPWindow
)->messagecache
)
225 SendIntuiMessage(im
->IDCMPWindow
,IW(im
->IDCMPWindow
)->messagecache
);
226 IW(im
->IDCMPWindow
)->messagecache
= 0;
231 case IDCMP_MENUVERIFY
:
233 struct Window
*w
= im
->IDCMPWindow
;
234 struct IntScreen
*scr
= 0;
236 scr
= GetPrivScreen(w
->WScreen
);
238 if (scr
!= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
||
239 scr
->MenuVerifySeconds
> im
->Seconds
||
240 (scr
->MenuVerifySeconds
== im
->Seconds
&&
241 scr
->MenuVerifyMicros
> im
->Micros
))
243 /* The timeout has expired, just ignore. */
247 --scr
->MenuVerifyMsgCount
;
248 if (w
== scr
->MenuVerifyActiveWindow
&&
249 im
->Code
== MENUCANCEL
)
251 ULONG lock
= LockIBase(0);
254 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
256 if (w1
->IDCMPFlags
& IDCMP_MENUVERIFY
&& w1
!= scr
->MenuVerifyActiveWindow
)
258 ih_fire_intuimessage(w1
,
268 scr
->MenuVerifyActiveWindow
= NULL
;
269 scr
->MenuVerifyTimeOut
= 0;
270 scr
->MenuVerifyMsgCount
= 0;
271 scr
->MenuVerifySeconds
= 0;
272 scr
->MenuVerifyMicros
= 0;
273 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
275 else if (scr
->MenuVerifyMsgCount
== 0)
277 struct InputEvent ie
;
279 /* currently we ONLY need the menu open time ! */
280 ie
.ie_TimeStamp
.tv_secs
= im
->Seconds
;
281 ie
.ie_TimeStamp
.tv_micro
= im
->Micros
;
283 if (FireMenuMessage(MMCODE_START
, scr
->MenuVerifyActiveWindow
, &ie
, IntuitionBase
))
285 /* This lock will be released only when the user is
286 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
287 event arrives (generated by MenuHandler task) */
289 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
290 iihdata
->MenuWindow
= scr
->MenuVerifyActiveWindow
;
294 scr
->MenuVerifyActiveWindow
= NULL
;
295 scr
->MenuVerifyTimeOut
= 0;
296 scr
->MenuVerifyMsgCount
= 0;
297 scr
->MenuVerifySeconds
= 0;
298 scr
->MenuVerifyMicros
= 0;
299 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
305 case IDCMP_SIZEVERIFY
:
307 struct GadgetInfo
*gi
= &iihdata
->GadgetInfo
;
308 struct Window
*w
= im
->IDCMPWindow
;
309 struct Gadget
*gadget
= im
->IAddress
;
310 struct InputEvent ie
;
313 PrepareGadgetInfo(gi
, IntuitionBase
->ActiveScreen
, w
, NULL
);
314 SetGadgetInfoGadget(gi
, gadget
, IntuitionBase
);
316 if (IS_BOOPSI_GADGET(gadget
))
318 ie
.ie_NextEvent
= NULL
;
319 ie
.ie_Class
= IECLASS_RAWMOUSE
;
321 ie
.ie_Code
= IECODE_LBUTTON
;
322 ie
.ie_Qualifier
= im
->Qualifier
;
323 ie
.ie_X
= im
->MouseX
;
324 ie
.ie_Y
= im
->MouseY
;
325 ie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
326 ie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
335 /* For compatibility, send a GM_HANDLEINPUT too */
336 ie
.ie_Class
= IECLASS_RAWMOUSE
;
337 ie
.ie_Code
= IECODE_NOBUTTON
;
341 gadget
= DoGPInput(gi
,
349 /* From now on the master drag/size gadget takes over */
351 iihdata
->ActiveSysGadget
= gadget
;
352 gadget
= iihdata
->MasterSizeGadget
;
353 iihdata
->ActiveGadget
= gadget
;
355 ie
.ie_Class
= IECLASS_RAWMOUSE
;
356 ie
.ie_Code
= IECODE_LBUTTON
;
357 ie
.ie_X
= im
->MouseX
;
358 ie
.ie_Y
= im
->MouseY
;
369 case IDCMP_REQVERIFY
:
371 struct Window
*w
= im
->IDCMPWindow
;
373 EndRequest(w
->DMRequest
, w
);
375 ih_fire_intuimessage(w
,
383 case IDCMP_WBENCHMESSAGE
:
384 DEBUG_WORKBENCH(dprintf("HandleIntuiReplyPort: code 0x%lx\n",
388 } /* switch(im->Class) */
390 if (im
->Qualifier
& IEQUALIFIER_REPEAT
)
392 /* IDCMP_IDCMPUPDATE messages can also be sent from app task, therefore
393 it would be better if there was an ATOMIC_DEC macro or something */
395 if (IW(im
->IDCMPWindow
)->num_repeatevents
)
397 IW(im
->IDCMPWindow
)->num_repeatevents
--;
401 FreeIntuiMessage(im
);
403 } /* while ((im = (struct IntuiMessage *)GetMsg(iihdata->IntuiReplyPort))) */
405 /****************************************************************************************/
407 struct Window
*GetToolBoxWindow(struct InputEvent
*ie
, struct IntuitionBase
*IntuitionBase
)
409 /* The caller has checked that the input event is a IECLASS_RAWMOUSE, SELECTDOWN event */
410 /* NOTE: may be called with NULL ie ptr! */
412 struct Window
*new_w
= NULL
;
416 lock
= LockIBase(0UL);
420 scr
= IntuitionBase
->FirstScreen
;
424 D(bug("GetToolBoxWindow: Click at (%d,%d)\n",scr
->MouseX
,scr
->MouseY
));
427 LockLayerInfo(&scr
->LayerInfo
);
429 l
= WhichLayer(&scr
->LayerInfo
, scr
->MouseX
, scr
->MouseY
);
431 UnlockLayerInfo(&scr
->LayerInfo
);
436 D(bug("GetToolBoxWindow: Click not inside layer\n"));
438 else if (l
== scr
->BarLayer
)
443 new_w
= (struct Window
*)l
->Window
;
446 if ((new_w
->Flags
& WFLG_TOOLBOX
) == 0) new_w
= NULL
;
450 D(bug("GetToolBoxWindow: Selected layer is not a ToolBox window\n"));
454 D(bug("GetToolBoxWindow: Found layer %p\n", l
));
459 D(bug("GetToolBoxWindow: New window %p\n", new_w
));
463 /****************************************************************************************/
465 AROS_UFH2(struct InputEvent
*, IntuiInputHandler
,
466 AROS_UFHA(struct InputEvent
*, oldchain
, A0
),
467 AROS_UFHA(struct IIHData
*, iihdata
, A1
)
472 struct InputEvent
*ie
, *orig_ie
, *next_ie
, stackie
;
473 struct Gadget
*gadget
= NULL
, *boxgadget
= NULL
;
474 struct IntuitionBase
*IntuitionBase
= iihdata
->IntuitionBase
;
476 struct GadgetInfo
*gi
= &iihdata
->GadgetInfo
;
477 struct GadgetInfo
*boxgi
= &iihdata
->BoxGadgetInfo
;
478 BOOL reuse_event
, ie_used
;
479 struct Window
*w
, *toolbox
;
480 struct Requester
*req
;
481 ULONG stitlebarhit
= 0;
482 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
483 WORD pointerposx
, pointerposy
;
484 BOOL call_setpointerpos
= FALSE
;
487 D(bug("Inside intuition inputhandler, active window=%p\n", IntuitionBase
->ActiveWindow
));
489 // DEBUG_HANDLER(dprintf("Handler: IBase 0x%lx KeyMapBase 0x%lx\n",IntuitionBase,KeymapBase));
491 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->InputHandlerLock
);
493 if (!iihdata
->InputDeviceTask
) iihdata
->InputDeviceTask
= FindTask(NULL
);
495 /* Then free generated InputEvents done in the previous round */
497 FreeGeneratedInputEvents(iihdata
);
499 /* First handle IntuiMessages which were replied back to the IntuiReplyPort
502 HandleIntuiReplyPort(iihdata
, IntuitionBase
);
504 /* Handle action messages */
506 HandleIntuiActions(iihdata
, IntuitionBase
);
508 /* Now handle the input events */
514 /* shut up the compiler */
518 gadget
= iihdata
->ActiveGadget
;
520 while (reuse_event
|| next_ie
)
523 struct Window
*old_w
;
524 BOOL keep_event
= TRUE
;
525 BOOL new_active_window
= FALSE
;
527 /* new event, we need to reset this */
529 iihdata
->ActEventTablet
= 0;
535 next_ie
= ie
->ie_NextEvent
;
539 D(bug("iih: Handling event of class %d, code %d\n", ie
->ie_Class
, ie
->ie_Code
));
542 /* Set the timestamp in IntuitionBase */
544 IntuitionBase
->Seconds
= ie
->ie_TimeStamp
.tv_secs
;
545 IntuitionBase
->Micros
= ie
->ie_TimeStamp
.tv_micro
;
547 /* Use event to find the active window */
549 toolbox
= GetToolBoxWindow(ie
, IntuitionBase
);
554 /* Do ToolBox Window Actions */
555 /* ToolBox Windows supports only a subset of IECLASS Actions */
560 req
= w
->FirstRequest
;
562 switch (ie
->ie_Class
)
593 case IECLASS_RAWMOUSE
:
599 BOOL new_boxgadget
= FALSE
;
600 BOOL sizeverify
= FALSE
;
602 iihdata
->ActQualifier
|= IEQUALIFIER_LEFTBUTTON
;
606 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
613 /* use the *frontmost* screen rather than active one when searching
614 for sdepth gadget! */
615 boxgadget
= FindGadget (IntuitionBase
->FirstScreen
,
616 stitlebarhit
? 0 : w
, stitlebarhit
? 0 : req
,
617 IntuitionBase
->ActiveScreen
? IntuitionBase
->ActiveScreen
->MouseX
: 0,
618 IntuitionBase
->ActiveScreen
? IntuitionBase
->ActiveScreen
->MouseY
: 0,
619 boxgi
, FALSE
, IntuitionBase
);
621 D(bug("Click on gadget %p\n", boxgadget
));
622 new_boxgadget
= TRUE
;
624 } /* if (!boxgadget) */
627 if (boxgadget
&& new_boxgadget
)
629 if (w
&& (w
->IDCMPFlags
& IDCMP_SIZEVERIFY
) &&
630 ((boxgadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
/*||
631 (boxgadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WZOOM*/))
633 ih_fire_intuimessage(w
,
643 BOOL is_draggad
, is_sizegad
;
645 /* Whenever the active gadget changes the gi must be updated
646 because it is cached in iidata->GadgetInfo!!!! Don't
647 forget to do this if somewhere else the active
648 gadget is changed, for example in ActivateGadget!!! */
650 PrepareGadgetInfo(boxgi
, IntuitionBase
->ActiveScreen
, w
, req
);
651 SetGadgetInfoGadget(boxgi
, boxgadget
, IntuitionBase
);
654 is_draggad
= ((boxgadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
);
655 is_sizegad
= ((boxgadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
);
657 /* jDc: intui68k sends IDCMPs for GACT_IMMEDIATE drag&sizegads! */
658 if (boxgadget
->Activation
& GACT_IMMEDIATE
)
660 ih_fire_intuimessage(w
,
667 if (is_draggad
|| is_sizegad
)
669 if (IS_BOOPSI_GADGET(boxgadget
))
678 /* Ignoring retval of dispatcher above is what
679 AmigaOS does too for boopsi drag/resize
684 /* From now on the master drag/size gadget takes over */
685 if ((w
->MoreFlags
& WMFLG_IAMMUI
) && (w
->Flags
& WFLG_BORDERLESS
))
687 iihdata
->ActiveSysGadget
= is_draggad
? boxgadget
: 0;
691 iihdata
->ActiveSysGadget
= boxgadget
;
693 boxgadget
= is_draggad
? iihdata
->MasterDragGadget
: iihdata
->MasterSizeGadget
;
702 switch (boxgadget
->GadgetType
& GTYP_GTYPEMASK
)
704 case GTYP_BOOLGADGET
:
705 /* Only set the GFLG_SELECTED flag for RELVERIFY and
706 * TOGGLESELECT gadget. It's for the user to do it if
707 * he wants for other GADGIMMEDIATE ones.
708 * Only RELVERIFY gadgets stay active.
711 if (boxgadget
->Activation
& (GACT_TOGGLESELECT
| GACT_RELVERIFY
))
713 boxgadget
->Flags
^= GFLG_SELECTED
;
714 RefreshBoolGadgetState(boxgadget
, w
, req
, IntuitionBase
);
717 if (boxgadget
->Activation
& GACT_RELVERIFY
)
719 boxgadget
->Activation
|= GACT_ACTIVEGADGET
;
720 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
729 case GTYP_PROPGADGET
:
730 HandlePropSelectDown(boxgadget
,
733 w
->MouseX
- boxgi
->gi_Domain
.Left
- GetGadgetLeft(boxgadget
, boxgi
->gi_Screen
, boxgi
->gi_Window
, NULL
),
734 w
->MouseY
- boxgi
->gi_Domain
.Top
- GetGadgetTop(boxgadget
, boxgi
->gi_Screen
, boxgi
->gi_Window
, NULL
),
743 if (InsideGadget(boxgi->gi_Screen, boxgi->gi_Window,
744 boxgi->gi_Requester, boxgadget,
745 boxgi->gi_Screen->MouseX, boxgi->gi_Screen->MouseY))
749 HandleStrInput(boxgadget, boxgi, ie, &imsgcode,
754 boxgadget->Flags &= ~GFLG_SELECTED;
756 RefreshStrGadget(boxgadget, w, req, IntuitionBase);
762 case GTYP_CUSTOMGADGET
:
764 boxgadget
= DoGPInput(boxgi
,
767 (new_boxgadget
? GM_GOACTIVE
: GM_HANDLEINPUT
),
770 D(bug("new_boxgadget %d, goactive %p\n", new_boxgadget
, boxgadget
));
773 if (boxgadget
&& new_boxgadget
&& (!(boxgadget
->GadgetType
& GTYP_SIZING
)))
775 /* For compatibility, send a GM_HANDLEINPUT too */
776 struct InputEvent newie
;
779 newie
.ie_NextEvent
= NULL
;
780 newie
.ie_Class
= IECLASS_RAWMOUSE
;
781 newie
.ie_SubClass
= 0;
782 newie
.ie_Code
= IECODE_NOBUTTON
;
783 newie
.ie_Qualifier
= ie
->ie_Qualifier
;
786 newie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
787 newie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
789 boxgadget
= DoGPInput(boxgi
,
795 D(bug("handleinput %p\n", boxgadget
));
800 case 0: //orig gadtools / some 1.3 gadgets
802 if (IS_SYS_GADGET(boxgadget
))
804 HandleSysGadgetVerify(boxgi
, boxgadget
, IntuitionBase
);
808 if (boxgadget
->Activation
& GACT_RELVERIFY
)
810 boxgadget
->Activation
|= GACT_ACTIVEGADGET
;
811 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
812 if (boxgadget
->Flags
& GFLG_GADGHIMAGE
)
814 boxgadget
->Flags
^= GFLG_SELECTED
;
815 RefreshBoolGadgetState(boxgadget
, w
, req
, IntuitionBase
);
820 /* jDc: this is what original intuition does, before crashing after a while ;)*/
821 ih_fire_intuimessage(w
,
830 } /* switch (GadgetType) */
832 } /* if (a boxgadget is active) */
833 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && !sizeverify
&& !stitlebarhit
)
836 ih_fire_intuimessage(w
,
845 } /* case SELECTDOWN */
850 iihdata
->ActQualifier
&= ~IEQUALIFIER_LEFTBUTTON
;
855 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
862 BOOL inside
= InsideGadget(boxgi
->gi_Screen
, boxgi
->gi_Window
,
863 boxgi
->gi_Requester
, boxgadget
,
864 boxgi
->gi_Screen
->MouseX
, boxgi
->gi_Screen
->MouseY
);
866 /*int selected = (boxgadget->Flags & GFLG_SELECTED) != 0;*/
868 switch (boxgadget
->GadgetType
& GTYP_GTYPEMASK
)
870 case GTYP_BOOLGADGET
:
871 /* Must be a RELVERIFY boxgadget */
873 if (!(boxgadget
->Activation
& GACT_TOGGLESELECT
) && inside
)
875 boxgadget
->Flags
^= GFLG_SELECTED
;
876 RefreshBoolGadgetState(boxgadget
, w
, req
, IntuitionBase
);
881 if (IS_SYS_GADGET(boxgadget
))
883 HandleSysGadgetVerify(boxgi
, boxgadget
, IntuitionBase
);
887 if (req
&& boxgadget
->Activation
& GACT_ENDGADGET
)
891 req
= w
->FirstRequest
;
894 ih_fire_intuimessage(w
,
904 ih_fire_intuimessage(w
,
911 boxgadget
->Activation
&= ~GACT_ACTIVEGADGET
;
915 case GTYP_PROPGADGET
:
916 HandlePropSelectUp(boxgadget
, w
, req
, IntuitionBase
);
917 if (boxgadget
->Activation
& GACT_RELVERIFY
)
919 ih_fire_intuimessage(w
,
929 /* Intuition string gadgets don't care about SELECTUP */
931 case GTYP_CUSTOMGADGET
:
932 boxgadget
= DoGPInput(boxgi
, boxgadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
935 case 0: //orig gadtools / some 1.3 gadgets
937 boxgadget->Activation &= ~GACT_ACTIVEGADGET;
938 if (boxgadget->Activation & GACT_RELVERIFY)
940 if (boxgadget->Flags & GFLG_GADGHIMAGE)
944 boxgadget->Flags ^= GFLG_SELECTED;
945 RefreshBoolGadgetState(boxgadget, w, req, IntuitionBase);
951 ih_fire_intuimessage(w,
958 ih_fire_intuimessage(w,
968 } /* switch GadgetType */
970 } /* if (a boxgadget is currently active) */
971 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
))
973 ih_fire_intuimessage(w
,
980 break; /* case SELECTUP */
983 iihdata
->ActQualifier
|= IEQUALIFIER_RBUTTON
;
988 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
994 if (w
&& !req
&& w
->DMRequest
&& !(w
->Flags
& WFLG_RMBTRAP
))
997 DoubleClick(GetPrivIBase(IntuitionBase
)->DMStartSecs
,
998 GetPrivIBase(IntuitionBase
)->DMStartMicro
,
999 ie
->ie_TimeStamp
.tv_secs
,
1000 ie
->ie_TimeStamp
.tv_micro
))
1002 if (w
->IDCMPFlags
& IDCMP_REQVERIFY
)
1004 ih_fire_intuimessage(w
,
1010 else if (Request(w
->DMRequest
, w
))
1014 ih_fire_intuimessage(w
,
1026 if (w
&& !boxgadget
)
1028 if (!(w
->Flags
& WFLG_RMBTRAP
) && !req
)
1030 struct IntScreen
*scr
= GetPrivScreen(w
->WScreen
);
1033 BOOL mouseon
= TRUE
;
1035 scr
->MenuVerifyMsgCount
= 0;
1037 if (w
->MouseX
< 0 || w
->MouseY
< 0) mouseon
= FALSE
;
1038 if (w
->MouseX
> w
->Width
|| w
->MouseY
> w
->Height
) mouseon
= FALSE
;
1040 if (w
->IDCMPFlags
& IDCMP_MENUVERIFY
&& (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
1042 ih_fire_intuimessage(w
,
1044 mouseon
? MENUHOT
: MENUWAITING
,
1047 scr
->MenuVerifyMsgCount
++;
1050 lock
= LockIBase(0);
1052 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
1054 if ((w1
->IDCMPFlags
& IDCMP_MENUVERIFY
) && (w1
!= w
) && (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
1056 ih_fire_intuimessage(w1
,
1061 ++scr
->MenuVerifyMsgCount
;
1067 /* FIXME: when a window is opened with IDCMP_MENUVERIFY
1068 * (or this event is requested via ModifyIDCMP), and a
1069 * verify operation is pending, the window should get
1070 * a verify message too. Oh well.
1073 if (scr
->MenuVerifyMsgCount
)
1075 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= scr
;
1076 scr
->MenuVerifyActiveWindow
= w
;
1077 scr
->MenuVerifyTimeOut
= 2;
1078 scr
->MenuVerifySeconds
= IntuitionBase
->Seconds
;
1079 scr
->MenuVerifyMicros
= IntuitionBase
->Micros
;
1081 else if (FireMenuMessage(MMCODE_START
, w
, NULL
/*ie*/, IntuitionBase
))
1083 /* This lock will be released only when the user is
1084 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
1085 event arrives (generated by MenuHandler task) */
1087 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
1088 iihdata
->MenuWindow
= w
;
1089 MENUS_ACTIVE
= TRUE
;
1102 iihdata
->ActQualifier
&= ~IEQUALIFIER_RBUTTON
;
1103 if (GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
)
1106 struct IntScreen
*scr
= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
;
1107 ULONG lock
= LockIBase(0);
1109 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
1111 if (w1
->IDCMPFlags
& IDCMP_MENUVERIFY
&& w1
->IDCMPFlags
& IDCMP_MOUSEBUTTONS
)
1113 ih_fire_intuimessage(w1
,
1123 /* FIXME: when the active window replies the verifymessage,
1124 * it should get a IDCMP_MENUPICK/MENUNULL message.
1126 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
1127 scr
->MenuVerifyActiveWindow
= NULL
;
1128 scr
->MenuVerifyMsgCount
= 0;
1129 scr
->MenuVerifyTimeOut
= 0;
1130 scr
->MenuVerifySeconds
= 0;
1131 scr
->MenuVerifyMicros
= 0;
1136 iihdata
->ActQualifier
|= IEQUALIFIER_MIDBUTTON
;
1137 if (DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
1138 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
1140 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= MIDDLEDOWN
)
1142 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1143 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
1147 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
1152 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
1153 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1155 /* update last click time for doubleclicktofront */
1156 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
1157 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
1161 iihdata
->ActQualifier
&= ~IEQUALIFIER_MIDBUTTON
;
1167 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1175 if (IS_BOOPSI_GADGET(boxgadget
))
1177 boxgadget
= DoGPInput(boxgi
, boxgadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
1180 } /* if (there is an active boxgadget) */
1181 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && w
!= GetPrivScreen(w
->WScreen
)->MenuVerifyActiveWindow
)
1183 ih_fire_intuimessage(w
,
1190 break; /* case MENUDOWN */
1192 case IECODE_NOBUTTON
: /* MOUSEMOVE */
1195 if (ie
->ie_Qualifier
& IEQUALIFIER_RELATIVEMOUSE
)
1200 /* Add delta information lost in previous mousemove event. See below. */
1201 iihdata
->DeltaMouseX
= ie
->ie_X
+ iihdata
->DeltaMouseX_Correction
;
1202 iihdata
->DeltaMouseY
= ie
->ie_Y
+ iihdata
->DeltaMouseY_Correction
;
1204 #define ACCELERATOR_THRESH 2
1205 #define ACCELERATOR_MULTI 2
1207 if (GetPrivIBase(IntuitionBase
)->ActivePreferences
->EnableCLI
& MOUSE_ACCEL
)
1210 if (ABS(iihdata
->DeltaMouseX
) > ACCELERATOR_THRESH
)
1212 iihdata
->DeltaMouseX
*= ACCELERATOR_MULTI
;
1214 if (ABS(iihdata
->DeltaMouseY
) > ACCELERATOR_THRESH
)
1216 iihdata
->DeltaMouseY
*= ACCELERATOR_MULTI
;
1220 switch(GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
)
1223 iihdata
->DeltaMouseX_Correction
= 0;
1224 iihdata
->DeltaMouseX_Correction
= 0;
1228 /* Remember the delta information which gets lost because of division by PointerTicks.
1229 Will be added to prescaled deltas of next mousemove event. If this is not done, moving
1230 the mouse very slowly would cause it to not move at all */
1232 iihdata
->DeltaMouseX_Correction
= iihdata
->DeltaMouseX
% GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
1233 iihdata
->DeltaMouseY_Correction
= iihdata
->DeltaMouseY
% GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
1235 iihdata
->DeltaMouseX
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
1236 iihdata
->DeltaMouseY
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
1241 ie
->ie_X
= iihdata
->DeltaMouseX
+ iihdata
->LastMouseX
;
1242 ie
->ie_Y
= iihdata
->DeltaMouseY
+ iihdata
->LastMouseY
;
1244 //jDc: not really necessary to lock this for reading since this ptr is only modified
1245 //by functions synced with inputhandler
1246 //lock = LockIBase(0);
1247 scr
= IntuitionBase
->FirstScreen
;
1251 if (IntuitionBase
->FirstScreen
->Flags
& AUTOSCROLL
)
1254 #define VWIDTH IntuitionBase->ViewLord.ViewPort->DWidth
1255 #define VHEIGHT IntuitionBase->ViewLord.ViewPort->DHeight
1256 #define VDX IntuitionBase->ViewLord.ViewPort->DxOffset
1257 #define VDY IntuitionBase->ViewLord.ViewPort->DyOffset
1259 if ((ie
->ie_X
> VWIDTH
- scr
->LeftEdge
- 1) || (ie
->ie_X
< - scr
->LeftEdge
) ||
1260 (ie
->ie_Y
> VHEIGHT
- scr
->TopEdge
- 1) || (ie
->ie_Y
< - scr
->TopEdge
))
1262 if (ie
->ie_X
> VWIDTH
- scr
->LeftEdge
- 1)
1264 scr
->LeftEdge
= VWIDTH
- ie
->ie_X
;
1265 if (VWIDTH
- scr
->LeftEdge
> scr
->Width
) scr
->LeftEdge
= VWIDTH
- scr
->Width
;
1266 VDX
= scr
->LeftEdge
;
1269 if (ie
->ie_X
< -scr
->LeftEdge
)
1271 scr
->LeftEdge
= -ie
->ie_X
;
1272 if (scr
->LeftEdge
< VWIDTH
- scr
->Width
) scr
->LeftEdge
= VWIDTH
- scr
->Width
;
1273 if(scr
->LeftEdge
> 0) scr
->LeftEdge
= 0; // we don't support > 0 LeftEdges
1274 VDX
= scr
->LeftEdge
;
1277 if (ie
->ie_Y
> VHEIGHT
- scr
->TopEdge
- 1)
1279 scr
->TopEdge
= VHEIGHT
- ie
->ie_Y
;
1280 if (VHEIGHT
- scr
->TopEdge
> scr
->Height
) scr
->TopEdge
= VHEIGHT
- scr
->Height
;
1284 if (ie
->ie_Y
< -scr
->TopEdge
)
1286 scr
->TopEdge
= - ie
->ie_Y
;
1287 if (scr
->TopEdge
< VHEIGHT
- scr
->Height
) scr
->TopEdge
= VHEIGHT
- scr
->Height
;
1288 if(scr
->TopEdge
> 0) scr
->TopEdge
= 0;
1292 ScrollVPort(IntuitionBase
->ViewLord
.ViewPort
);
1296 if (ie
->ie_X
>= scr
->Width
+ max(scr
->LeftEdge
,0)) ie
->ie_X
= scr
->Width
+ max(scr
->LeftEdge
,0) - 1;
1297 if (ie
->ie_Y
>= scr
->Height
+ max(scr
->TopEdge
,0)) ie
->ie_Y
= scr
->Height
+ max(scr
->TopEdge
,0) - 1;
1298 if (ie
->ie_X
< - scr
->LeftEdge
) ie
->ie_X
= - scr
->LeftEdge
;
1299 if (ie
->ie_Y
< - scr
->TopEdge
) ie
->ie_Y
= - scr
->TopEdge
;
1304 if (ie
->ie_X
>= 320) ie
->ie_X
= 320 - 1;
1305 if (ie
->ie_Y
>= 200) ie
->ie_Y
= 200 - 1;
1306 if (ie
->ie_X
< 0) ie
->ie_X
= 0;
1307 if (ie
->ie_Y
< 0) ie
->ie_Y
= 0;
1309 //UnlockIBase(lock);
1313 iihdata
->DeltaMouseX
= ie
->ie_X
- iihdata
->LastMouseX
;
1314 iihdata
->DeltaMouseY
= ie
->ie_Y
- iihdata
->LastMouseY
;
1318 /* Do Mouse Bounding - mouse will be most restrictive of screen size or mouse bounds */
1319 if (iihdata
->MouseBoundsActiveFlag
)
1321 if (ie
->ie_X
< iihdata
->MouseBoundsLeft
)
1323 ie
->ie_X
= iihdata
->MouseBoundsLeft
;
1325 else if (ie
->ie_X
> iihdata
->MouseBoundsRight
)
1327 ie
->ie_X
= iihdata
->MouseBoundsRight
;
1330 if (ie
->ie_Y
< iihdata
->MouseBoundsTop
)
1332 ie
->ie_Y
= iihdata
->MouseBoundsTop
;
1334 else if (ie
->ie_Y
> iihdata
->MouseBoundsBottom
)
1336 ie
->ie_Y
= iihdata
->MouseBoundsBottom
;
1340 #if !SINGLE_SETPOINTERPOS_PER_EVENTLOOP
1341 SetPointerPos(ie
->ie_X
, ie
->ie_Y
);
1343 pointerposx
= ie
->ie_X
;
1344 pointerposy
= ie
->ie_Y
;
1345 call_setpointerpos
= TRUE
;
1348 iihdata
->LastMouseX
= ie
->ie_X
;
1349 iihdata
->LastMouseY
= ie
->ie_Y
;
1351 notify_mousemove_screensandwindows(ie
->ie_X
,
1358 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1367 switch (boxgadget
->GadgetType
& GTYP_GTYPEMASK
)
1369 case GTYP_BOOLGADGET
:
1370 case 0: //fallback for sucky gadgets
1371 /* Must be a RELVERIFY boxgadget */
1375 inside
= InsideGadget(boxgi
->gi_Screen
,
1377 boxgi
->gi_Requester
,
1379 boxgi
->gi_Screen
->MouseX
,
1380 boxgi
->gi_Screen
->MouseY
);
1382 if (inside
!= iihdata
->MouseWasInsideBoolGadget
)
1384 iihdata
->MouseWasInsideBoolGadget
= inside
;
1386 boxgadget
->Flags
^= GFLG_SELECTED
;
1387 RefreshBoolGadgetState(boxgadget
, w
, req
, IntuitionBase
);
1392 case GTYP_PROPGADGET
:
1393 HandlePropMouseMove(boxgadget
,
1396 w
->MouseX
- boxgi
->gi_Domain
.Left
- GetGadgetLeft(boxgadget
, boxgi
->gi_Screen
, boxgi
->gi_Window
, NULL
),
1397 w
->MouseY
- boxgi
->gi_Domain
.Top
- GetGadgetTop(boxgadget
, boxgi
->gi_Screen
, boxgi
->gi_Window
, NULL
),
1402 case GTYP_CUSTOMGADGET
:
1403 boxgadget
= DoGPInput(boxgi
, boxgadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
1406 } /* switch GadgetType */
1408 } /* if (a boxgadget is currently active) */
1414 if (IW(w
)->helpflags
& HELPF_GADGETHELP
&& (!(PeekQualifier() & (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_RBUTTON
|IEQUALIFIER_MIDBUTTON
))))
1419 hw
= FindActiveWindow(ie
, 0, IntuitionBase
);
1422 (!hw
|| !(IW(w
)->helpflags
& HELPF_ISHELPGROUP
) ||
1423 !(IW(hw
)->helpflags
& HELPF_ISHELPGROUP
) ||
1424 IW(w
)->helpgroup
!= IW(hw
)->helpgroup
))
1427 if (iihdata
->LastHelpWindow
)
1429 fire_intuimessage(w
,
1435 iihdata
->LastHelpGadget
= NULL
;
1436 iihdata
->LastHelpWindow
= NULL
;
1437 iihdata
->HelpGadgetFindTime
= 0;
1442 g
= FindHelpGadget (hw
,
1443 IntuitionBase
->ActiveScreen
->MouseX
,
1444 IntuitionBase
->ActiveScreen
->MouseY
,
1446 if (g
&& g
!= iihdata
->LastHelpGadget
)
1448 if (!iihdata
->LastHelpGadget
)
1450 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1451 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1455 if (hw
== iihdata
->LastHelpWindow
)
1457 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
1458 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
1459 iihdata
->HelpGadgetFindTime
+= 25;//smaller delay
1463 else if (g
!= iihdata
->LastHelpGadget
||
1464 hw
!= iihdata
->LastHelpWindow
)
1466 fire_intuimessage(hw
,
1468 0, /* Don't know what it should be */
1473 iihdata
->LastHelpGadget
= g
;
1474 iihdata
->LastHelpWindow
= hw
;
1479 iihdata
->LastHelpGadget
= NULL
;
1480 iihdata
->LastHelpWindow
= NULL
;
1481 iihdata
->HelpGadgetFindTime
= 0;
1484 if (!(w
->IDCMPFlags
& IDCMP_MOUSEMOVE
)) break;
1486 /* Send IDCMP_MOUSEMOVE if WFLG_REPORTMOUSE is set
1487 and/or active boxgadget has GACT_FOLLOWMOUSE set */
1489 /* jDc: do NOT send when sizegad is pressed */
1491 if (!(w
->Flags
& WFLG_REPORTMOUSE
))
1493 if (!boxgadget
) break;
1494 if (!(boxgadget
->Activation
& GACT_FOLLOWMOUSE
)) break;
1498 if (boxgadget
&& (boxgadget
->GadgetType
& (GTYP_SIZING
|GTYP_WDRAGGING
))) break;
1501 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
1503 /* Limit the number of IDCMP_MOUSEMOVE messages sent to intuition.
1504 note that this comes after handling gadgets, because gadgets should get all events.
1507 if (IW(w
)->num_mouseevents
>= IW(w
)->mousequeue
)
1509 BOOL old_msg_found
= FALSE
;
1511 /* Mouse Queue is full, so try looking for a not
1512 yet GetMsg()ed IntuiMessage in w->UserPort
1513 trying to modify that. */
1518 struct IntuiMessage
*im
;
1520 for (im
= (struct IntuiMessage
*)w
->UserPort
->mp_MsgList
.lh_TailPred
;
1521 im
->ExecMessage
.mn_Node
.ln_Pred
;
1522 im
= (struct IntuiMessage
*)im
->ExecMessage
.mn_Node
.ln_Pred
)
1524 if ((im
->Class
== IDCMP_MOUSEMOVE
) &&
1525 (im
->IDCMPWindow
== w
))
1527 im
->Qualifier
= iihdata
->ActQualifier
;
1529 if (w
->IDCMPFlags
& IDCMP_DELTAMOVE
)
1531 im
->MouseX
= iihdata
->DeltaMouseX
;
1532 im
->MouseY
= iihdata
->DeltaMouseY
;
1536 im
->MouseX
= w
->MouseX
;
1537 im
->MouseY
= w
->MouseY
;
1539 CurrentTime(&im
->Seconds
, &im
->Micros
);
1541 old_msg_found
= TRUE
;
1545 } /* if (w->UserPort) */
1548 /* no need to send a new message if we modified
1549 an existing one ... */
1551 if (old_msg_found
) break;
1553 /* ... otherwise we are in a strange situation. The mouse
1554 queue is full, but we did not find an existing MOUSEMOVE
1555 imsg in w->UserPort. So the app probably has removed
1556 an imsg from the UserPort with GetMsg but we did not get
1557 the ReplyMsg, yet. In this case we do send a new message */
1559 HandleIntuiReplyPort(iihdata
, IntuitionBase
);
1563 /* MouseQueue is not full, so we can send a message. We increase
1564 IntWindow->num_mouseevents which will later be decreased after
1565 the Intuition InputHandler gets the ReplyMessage from the app
1566 and handles it in HandleIntuiReplyPort() */
1568 if (ih_fire_intuimessage(w
,
1574 IW(w
)->num_mouseevents
++;
1579 } /* case IECODE_NOBUTTON */
1581 } /* switch (ie->ie_Code) (what button was pressed ?) */
1632 w
= IntuitionBase
->ActiveWindow
;
1634 if (!MENUS_ACTIVE
&& !SYSGADGET_ACTIVE
)
1636 /* lock = LockIBase(0UL); */
1639 if (ie
->ie_Class
== IECLASS_RAWMOUSE
&& ie
->ie_Code
== SELECTDOWN
)
1641 w
= FindActiveWindow(ie
, &stitlebarhit
, IntuitionBase
);
1642 D(bug("iih:New active window: %p\n", w
));
1650 D(bug("Activating new window (title %s)\n", w
->Title
? w
->Title
: "<noname>"));
1652 D(bug("Window activated\n"));
1656 D(bug("Making active window inactive. Now there's no active window\n"));
1658 new_active_window
= TRUE
;
1659 iihdata
->NewActWindow
= w
;
1662 /* UnlockIBase(lock); */
1664 if (new_active_window
)
1667 (!(GetPrivScreen(w
->WScreen
)->MenuVerifyMsgCount
)) &&
1668 (!(MENUS_ACTIVE
)) && (!(SYSGADGET_ACTIVE
)))
1670 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
1673 case GTYP_CUSTOMGADGET
:
1675 struct gpGoInactive gpgi
;
1677 gpgi
.MethodID
= GM_GOINACTIVE
;
1678 gpgi
.gpgi_GInfo
= gi
;
1679 gpgi
.gpgi_Abort
= 1;
1681 Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpgi
, IntuitionBase
);
1685 case GTYP_STRGADGET
:
1686 gadget
->Flags
&= ~GFLG_SELECTED
;
1687 RefreshStrGadget(gadget
, gi
->gi_Window
, gi
->gi_Requester
, IntuitionBase
);
1690 case GTYP_BOOLGADGET
:
1691 /* That a bool gadget is active here can only happen
1692 if user used LMB to activate gadget and LAMIGA + LALT
1693 to activate other window, or viceversa */
1694 /* The gadget must be a RELVERIFY one */
1695 if (!(gadget
->Activation
& GACT_TOGGLESELECT
))
1699 inside
= InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
1700 gi
->gi_Requester
, gadget
,
1701 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
);
1705 gadget
->Flags
&= ~GFLG_SELECTED
;
1706 RefreshBoolGadgetState(gadget
, gi
->gi_Window
,
1707 gi
->gi_Requester
, IntuitionBase
);
1712 case GTYP_PROPGADGET
:
1713 /* That a prop gadget is active here can only happen
1714 if user used LMB to activate gadget and LAMIGA + LALT
1715 to activate other window, or viceversa */
1717 HandlePropSelectUp(gadget
, gi
->gi_Window
, NULL
, IntuitionBase
);
1718 if (gadget
->Activation
& GACT_RELVERIFY
)
1720 ih_fire_intuimessage(gi
->gi_Window
,
1728 } /* switch (gadget->GadgetType & GTYP_GTYPEMASK) */
1730 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
1731 iihdata
->ActiveGadget
= NULL
;
1735 /* ActivateWindow works if w = NULL */
1736 /* jacaDcaps: some gui toolkits (die reaction, die!) close the window opened by a boopsi gadget when
1737 it gets hit with lmb, so we need to check if the new active window does not go away by
1738 performing GM_GOINACTIVE on the gadget. NOTE: CloseWindow's part performed on input.device context
1739 clears the iihdata->NewActWindow if it's the actually closed one. */
1740 if (w
== iihdata
->NewActWindow
)
1746 w
= IntuitionBase
->ActiveWindow
;
1747 new_active_window
= FALSE
;
1748 ie
->ie_Class
= IECLASS_NULL
; //lose the event, otherwise the gadget will get activated again ;)
1751 iihdata
->NewActWindow
= 0;
1753 } /* if (new_active_window) */
1755 } /* if (!MENUS_ACTIVE) */
1760 req
= w
->FirstRequest
;
1763 D(bug("w %p req %p gadget %p\n", w
, req
, gadget
));
1765 switch (ie
->ie_Class
)
1767 case IECLASS_POINTERPOS
:
1768 ie
->ie_SubClass
= IESUBCLASS_COMPATIBLE
;
1771 case IECLASS_NEWPOINTERPOS
:
1772 switch (ie
->ie_SubClass
)
1774 case IESUBCLASS_COMPATIBLE
:
1775 ie
->ie_Code
= IECODE_NOBUTTON
;
1778 case IESUBCLASS_PIXEL
:
1780 struct IEPointerPixel
*pp
= ie
->ie_EventAddress
;
1782 ie
->ie_X
= pp
->iepp_Position
.X
+ pp
->iepp_Screen
->LeftEdge
;
1783 ie
->ie_Y
= pp
->iepp_Position
.Y
+ pp
->iepp_Screen
->TopEdge
;
1785 ie
->ie_Code
= IECODE_NOBUTTON
;
1788 case IESUBCLASS_TABLET
:
1790 //unsupported - does anything use it anyway? ;)
1795 case IESUBCLASS_NEWTABLET
:
1797 struct IENewTablet
*nt
= (struct IENewTablet
*)ie
->ie_EventAddress
;
1798 struct Screen
*scr
= IntuitionBase
->FirstScreen
;
1802 iihdata
->ActEventTablet
= nt
; //cache this
1803 ie
->ie_X
= (scr
->Width
* nt
->ient_TabletX
) / nt
->ient_RangeX
;
1804 ie
->ie_Y
= (scr
->Height
* nt
->ient_TabletY
) / nt
->ient_RangeY
;
1806 ie
->ie_Class
= IECLASS_RAWMOUSE
;
1816 case IECLASS_RAWMOUSE
:
1817 switch (ie
->ie_Code
)
1821 BOOL new_gadget
= FALSE
;
1822 BOOL sizeverify
= FALSE
;
1824 iihdata
->ActQualifier
|= IEQUALIFIER_LEFTBUTTON
;
1827 iihdata
->TitlebarAppearTime
= 0;
1831 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
1839 struct Gadget
* draggadget
= 0;
1841 if ((!(w
->FirstRequest
)) && (w
->Flags
& WFLG_DRAGBAR
) && MatchHotkey(ie
,IA_ACTIVEWINDOWMOVE
,IntuitionBase
))
1843 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)
1845 for (draggadget
= w
->FirstGadget
; draggadget
; draggadget
= draggadget
->NextGadget
)
1847 if ((draggadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
)
1849 gadget
= draggadget
;
1857 if ((!(w
->FirstRequest
)) && (w
->Flags
& WFLG_SIZEGADGET
) && MatchHotkey(ie
,IA_ACTIVEWINDOWSIZE
,IntuitionBase
))
1859 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)
1861 for (draggadget
= w
->FirstGadget
; draggadget
; draggadget
= draggadget
->NextGadget
)
1863 if ((draggadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
)
1865 gadget
= draggadget
;
1877 /* use the *frontmost* screen rather than active one when searching
1878 for sdepth gadget! */
1879 gadget
= FindGadget (IntuitionBase
->FirstScreen
,
1880 stitlebarhit
? 0 : w
, stitlebarhit
? 0 : req
,
1881 IntuitionBase
->ActiveScreen
? IntuitionBase
->ActiveScreen
->MouseX
: 0,
1882 IntuitionBase
->ActiveScreen
? IntuitionBase
->ActiveScreen
->MouseY
: 0,
1883 gi
, FALSE
, IntuitionBase
);
1885 D(bug("Click on gadget %p\n", gadget
));
1888 } /* if (!gadget) */
1890 if (!gadget
&& stitlebarhit
)
1892 struct Window
*ww
= 0;
1894 if ((ww
= FindDesktopWindow(IntuitionBase
->FirstScreen
,IntuitionBase
)))
1901 if (!stitlebarhit
&& !new_active_window
&& DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
1902 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
1904 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= SELECTDOWN
)
1906 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1907 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= SELECTDOWN
;
1911 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
1916 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= SELECTDOWN
;
1917 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
1920 /* update last click time for doubleclicktofront */
1921 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
1922 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
1929 if (!(gadget
&& ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
)))
1930 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
1933 if (result
== RUNHOTREUSE
)
1944 if (gadget
&& new_gadget
)
1946 if (w
&& (w
->IDCMPFlags
& IDCMP_SIZEVERIFY
) &&
1947 ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
/*||
1948 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WZOOM*/))
1950 ih_fire_intuimessage(w
,
1960 BOOL is_draggad
, is_sizegad
;
1962 /* Whenever the active gadget changes the gi must be updated
1963 because it is cached in iidata->GadgetInfo!!!! Don't
1964 forget to do this if somewhere else the active
1965 gadget is changed, for example in ActivateGadget!!! */
1967 PrepareGadgetInfo(gi
, IntuitionBase
->ActiveScreen
, w
, req
);
1968 SetGadgetInfoGadget(gi
, gadget
, IntuitionBase
);
1971 is_draggad
= (((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
) || ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING2
));
1973 is_draggad
= ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
);
1975 is_sizegad
= ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
);
1978 /* jDc: intui68k sends IDCMPs for GACT_IMMEDIATE drag&sizegads! */
1979 if (gadget
->Activation
& GACT_IMMEDIATE
)
1981 ih_fire_intuimessage(w
,
1989 if (is_draggad
|| is_sizegad
)
1991 if (IS_BOOPSI_GADGET(gadget
))
2000 /* Ignoring retval of dispatcher above is what
2001 AmigaOS does too for boopsi drag/resize
2006 /* From now on the master drag/size gadget takes over */
2007 if ((w
->MoreFlags
& WMFLG_IAMMUI
) && (w
->Flags
& WFLG_BORDERLESS
))
2009 iihdata
->ActiveSysGadget
= is_draggad
? gadget
: 0;
2013 iihdata
->ActiveSysGadget
= gadget
;
2015 gadget
= is_draggad
? iihdata
->MasterDragGadget
: iihdata
->MasterSizeGadget
;
2023 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
2025 case GTYP_BOOLGADGET
:
2026 /* Only set the GFLG_SELECTED flag for RELVERIFY and
2027 * TOGGLESELECT gadget. It's for the user to do it if
2028 * he wants for other GADGIMMEDIATE ones.
2029 * Only RELVERIFY gadgets stay active.
2032 if (gadget
->Activation
& (GACT_TOGGLESELECT
| GACT_RELVERIFY
))
2034 gadget
->Flags
^= GFLG_SELECTED
;
2035 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
2038 if (gadget
->Activation
& GACT_RELVERIFY
)
2040 gadget
->Activation
|= GACT_ACTIVEGADGET
;
2041 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
2049 case GTYP_PROPGADGET
:
2050 HandlePropSelectDown(gadget
,
2053 w
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
2054 w
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
2060 case GTYP_STRGADGET
:
2061 /* If the click was inside the active strgad,
2062 ** then let it update cursor pos,
2063 ** else deactivate stringadget and reuse event.
2066 if (InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
2067 gi
->gi_Requester
, gadget
,
2068 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
))
2072 HandleStrInput(gadget
, gi
, ie
, &imsgcode
,
2077 gadget
->Flags
&= ~GFLG_SELECTED
;
2079 RefreshStrGadget(gadget
, w
, req
, IntuitionBase
);
2080 /* Gadget not active anymore */
2086 case GTYP_CUSTOMGADGET
:
2087 gadget
= DoGPInput(gi
,
2090 (new_gadget
? GM_GOACTIVE
: GM_HANDLEINPUT
),
2093 D(bug("new_gadget %d, goactive %p\n", new_gadget
, gadget
));
2095 if (gadget
&& new_gadget
&& (!(gadget
->GadgetType
& GTYP_SIZING
)))
2097 /* For compatibility, send a GM_HANDLEINPUT too */
2098 struct InputEvent newie
;
2101 newie
.ie_NextEvent
= NULL
;
2102 newie
.ie_Class
= IECLASS_RAWMOUSE
;
2103 newie
.ie_SubClass
= 0;
2104 newie
.ie_Code
= IECODE_NOBUTTON
;
2105 newie
.ie_Qualifier
= ie
->ie_Qualifier
;
2108 newie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
2109 newie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
2111 gadget
= DoGPInput(gi
,
2117 D(bug("handleinput %p\n", gadget
));
2121 case 0: //orig gadtools / some 1.3 gadgets
2122 if (IS_SYS_GADGET(gadget
))
2124 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
2128 if (gadget
->Activation
& GACT_RELVERIFY
)
2130 gadget
->Activation
|= GACT_ACTIVEGADGET
;
2131 iihdata
->MouseWasInsideBoolGadget
= TRUE
;
2132 if (gadget
->Flags
& GFLG_GADGHIMAGE
)
2134 gadget
->Flags
^= GFLG_SELECTED
;
2135 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
2140 /* jDc: this is what original intuition does, before crashing after a while ;)*/
2141 ih_fire_intuimessage(w
,
2149 } /* switch (GadgetType) */
2151 } /* if (a gadget is active) */
2152 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && !sizeverify
&& !stitlebarhit
)
2154 ih_fire_intuimessage(w
,
2162 } /* case SELECTDOWN */
2166 iihdata
->ActQualifier
&= ~IEQUALIFIER_LEFTBUTTON
;
2169 iihdata
->TitlebarAppearTime
= 0;
2173 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2180 BOOL inside
= InsideGadget(gi
->gi_Screen
, gi
->gi_Window
,
2181 gi
->gi_Requester
, gadget
,
2182 gi
->gi_Screen
->MouseX
, gi
->gi_Screen
->MouseY
);
2184 /*int selected = (gadget->Flags & GFLG_SELECTED) != 0;*/
2186 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
2188 case GTYP_BOOLGADGET
:
2189 /* Must be a RELVERIFY gadget */
2191 if (!(gadget
->Activation
& GACT_TOGGLESELECT
) && inside
)
2193 gadget
->Flags
^= GFLG_SELECTED
;
2194 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
2199 if (IS_SYS_GADGET(gadget
))
2201 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
2205 if (req
&& gadget
->Activation
& GACT_ENDGADGET
)
2209 req
= w
->FirstRequest
;
2212 ih_fire_intuimessage(w
,
2222 ih_fire_intuimessage(w
,
2229 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
2233 case GTYP_PROPGADGET
:
2234 HandlePropSelectUp(gadget
, w
, req
, IntuitionBase
);
2235 if (gadget
->Activation
& GACT_RELVERIFY
)
2237 ih_fire_intuimessage(w
,
2247 /* Intuition string gadgets don't care about SELECTUP */
2249 case GTYP_CUSTOMGADGET
:
2250 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
2253 case 0: //orig gadtools / some 1.3 gadgets
2254 /* jDc: adding a gadget with gtyp field set to NULL crashes intui68k
2255 ** seems we don't need compatibility on this field ;) anyway we should
2256 ** handle the case of GTYP_CLOSE, etc, set by some "cod3r"
2258 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
2259 if (gadget
->Activation
& GACT_RELVERIFY
)
2261 if (gadget
->Flags
& GFLG_GADGHIMAGE
)
2265 gadget
->Flags
^= GFLG_SELECTED
;
2266 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
2272 ih_fire_intuimessage(w
,
2279 ih_fire_intuimessage(w
,
2288 } /* switch GadgetType */
2290 } /* if (a gadget is currently active) */
2291 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
))
2293 ih_fire_intuimessage(w
,
2300 break; /* case SELECTUP */
2303 iihdata
->ActQualifier
|= IEQUALIFIER_RBUTTON
;
2306 iihdata
->TitlebarAppearTime
= 0;
2310 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2315 if (DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
2316 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
2318 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= MENUDOWN
)
2320 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
2321 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MENUDOWN
;
2325 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
2330 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MENUDOWN
;
2331 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
2334 /* update last click time for doubleclicktofront */
2335 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
2336 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
2342 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
2344 if (result
== RUNHOTREUSE
)
2354 w
= IntuitionBase
->ActiveWindow
;
2359 if ((!MENUS_ACTIVE
) && (!gadget
) && (!(iihdata
->ActQualifier
& (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_MIDBUTTON
))))
2362 struct GadgetInfo ginf
;
2364 struct Window
*wind
= FindActiveWindow(0,&hit
,IntuitionBase
);
2368 gad
= FindGadget (IntuitionBase
->FirstScreen
,
2370 IntuitionBase
->ActiveScreen
->MouseX
,
2371 IntuitionBase
->ActiveScreen
->MouseY
,
2372 &ginf
, TRUE
, IntuitionBase
);
2374 if (gad
&& ((gad
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
))
2376 CreateSmallMenuTask(wind
,SMALLMENU_TYPE_WINDOWDEPTH
,IntuitionBase
);
2381 if (gad
&& ((gad
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SDEPTH
))
2383 CreateSmallMenuTask(0,SMALLMENU_TYPE_SCREENDEPTH
,IntuitionBase
);
2391 if (w
&& !req
&& w
->DMRequest
&& !(w
->Flags
& WFLG_RMBTRAP
))
2393 if (!MENUS_ACTIVE
&&
2394 DoubleClick(GetPrivIBase(IntuitionBase
)->DMStartSecs
,
2395 GetPrivIBase(IntuitionBase
)->DMStartMicro
,
2396 ie
->ie_TimeStamp
.tv_secs
,
2397 ie
->ie_TimeStamp
.tv_micro
))
2399 if (w
->IDCMPFlags
& IDCMP_REQVERIFY
)
2401 ih_fire_intuimessage(w
,
2407 else if (Request(w
->DMRequest
, w
))
2411 ih_fire_intuimessage(w
,
2421 GetPrivIBase(IntuitionBase
)->DMStartSecs
= ie
->ie_TimeStamp
.tv_secs
;
2422 GetPrivIBase(IntuitionBase
)->DMStartMicro
= ie
->ie_TimeStamp
.tv_micro
;
2427 if (!(w
->Flags
& WFLG_RMBTRAP
) && !req
)
2429 struct IntScreen
*scr
= GetPrivScreen(w
->WScreen
);
2432 BOOL mouseon
= TRUE
;
2434 scr
->MenuVerifyMsgCount
= 0;
2436 if (w
->MouseX
< 0 || w
->MouseY
< 0) mouseon
= FALSE
;
2437 if (w
->MouseX
> w
->Width
|| w
->MouseY
> w
->Height
) mouseon
= FALSE
;
2439 if (w
->IDCMPFlags
& IDCMP_MENUVERIFY
&& (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
2441 ih_fire_intuimessage(w
,
2443 mouseon
? MENUHOT
: MENUWAITING
,
2446 scr
->MenuVerifyMsgCount
++;
2449 lock
= LockIBase(0);
2451 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
2453 if ((w1
->IDCMPFlags
& IDCMP_MENUVERIFY
) && (w1
!= w
) && (!(IW(w
)->specialflags
& SPFLAG_IAMDEAD
)))
2455 ih_fire_intuimessage(w1
,
2460 ++scr
->MenuVerifyMsgCount
;
2466 /* FIXME: when a window is opened with IDCMP_MENUVERIFY
2467 * (or this event is requested via ModifyIDCMP), and a
2468 * verify operation is pending, the window should get
2469 * a verify message too. Oh well.
2472 if (scr
->MenuVerifyMsgCount
)
2474 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= scr
;
2475 scr
->MenuVerifyActiveWindow
= w
;
2476 scr
->MenuVerifyTimeOut
= 2;
2477 scr
->MenuVerifySeconds
= IntuitionBase
->Seconds
;
2478 scr
->MenuVerifyMicros
= IntuitionBase
->Micros
;
2480 else if (FireMenuMessage(MMCODE_START
, w
, NULL
/*ie*/, IntuitionBase
))
2482 /* This lock will be released only when the user is
2483 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
2484 event arrives (generated by MenuHandler task) */
2486 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
2487 iihdata
->MenuWindow
= w
;
2488 MENUS_ACTIVE
= TRUE
;
2501 iihdata
->ActQualifier
&= ~IEQUALIFIER_RBUTTON
;
2502 if (GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
)
2505 struct IntScreen
*scr
= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
;
2506 ULONG lock
= LockIBase(0);
2508 for (w1
= scr
->Screen
.FirstWindow
; w1
; w1
= w1
->NextWindow
)
2510 if (w1
->IDCMPFlags
& IDCMP_MENUVERIFY
&& w1
->IDCMPFlags
& IDCMP_MOUSEBUTTONS
)
2512 ih_fire_intuimessage(w1
,
2522 /* FIXME: when the active window replies the verifymessage,
2523 * it should get a IDCMP_MENUPICK/MENUNULL message.
2525 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
2526 scr
->MenuVerifyActiveWindow
= NULL
;
2527 scr
->MenuVerifyMsgCount
= 0;
2528 scr
->MenuVerifyTimeOut
= 0;
2529 scr
->MenuVerifySeconds
= 0;
2530 scr
->MenuVerifyMicros
= 0;
2535 iihdata
->ActQualifier
|= IEQUALIFIER_MIDBUTTON
;
2536 if (DoubleClick(GetPrivIBase(IntuitionBase
)->LastClickSecs
,GetPrivIBase(IntuitionBase
)->LastClickMicro
,
2537 ie
->ie_TimeStamp
.tv_secs
,ie
->ie_TimeStamp
.tv_micro
))
2539 if (GetPrivIBase(IntuitionBase
)->DoubleClickButton
!= MIDDLEDOWN
)
2541 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
2542 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
2546 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
++;
2551 GetPrivIBase(IntuitionBase
)->DoubleClickButton
= MIDDLEDOWN
;
2552 GetPrivIBase(IntuitionBase
)->DoubleClickCounter
= 0;
2554 /* update last click time for doubleclicktofront */
2555 GetPrivIBase(IntuitionBase
)->LastClickSecs
= ie
->ie_TimeStamp
.tv_secs
;
2556 GetPrivIBase(IntuitionBase
)->LastClickMicro
= ie
->ie_TimeStamp
.tv_micro
;
2560 iihdata
->ActQualifier
&= ~IEQUALIFIER_MIDBUTTON
;
2565 iihdata
->TitlebarAppearTime
= 0;
2569 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2575 if (ie
->ie_Code
== MIDDLEDOWN
)
2579 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
2581 if (result
== RUNHOTREUSE
)
2591 w
= IntuitionBase
->ActiveWindow
;
2596 if (IS_BOOPSI_GADGET(gadget
))
2598 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
2601 } /* if (there is an active gadget) */
2602 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
) && w
!= GetPrivScreen(w
->WScreen
)->MenuVerifyActiveWindow
)
2604 ih_fire_intuimessage(w
,
2611 break; /* case MENUDOWN */
2613 case IECODE_NOBUTTON
: /* MOUSEMOVE */
2616 if (ie
->ie_Qualifier
& IEQUALIFIER_RELATIVEMOUSE
)
2621 /* Add delta information lost in previous mousemove event. See below. */
2622 iihdata
->DeltaMouseX
= ie
->ie_X
+ iihdata
->DeltaMouseX_Correction
;
2623 iihdata
->DeltaMouseY
= ie
->ie_Y
+ iihdata
->DeltaMouseY_Correction
;
2625 #define ACCELERATOR_THRESH 2
2626 #define ACCELERATOR_MULTI 2
2628 if (GetPrivIBase(IntuitionBase
)->ActivePreferences
->EnableCLI
& MOUSE_ACCEL
)
2631 if (ABS(iihdata
->DeltaMouseX
) > ACCELERATOR_THRESH
)
2633 iihdata
->DeltaMouseX
*= ACCELERATOR_MULTI
;
2635 if (ABS(iihdata
->DeltaMouseY
) > ACCELERATOR_THRESH
)
2637 iihdata
->DeltaMouseY
*= ACCELERATOR_MULTI
;
2641 switch(GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
)
2644 iihdata
->DeltaMouseX_Correction
= 0;
2645 iihdata
->DeltaMouseX_Correction
= 0;
2649 /* Remember the delta information which gets lost because of division by PointerTicks.
2650 Will be added to prescaled deltas of next mousemove event. If this is not done, moving
2651 the mouse very slowly would cause it to not move at all */
2653 iihdata
->DeltaMouseX_Correction
= iihdata
->DeltaMouseX
% GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
2654 iihdata
->DeltaMouseY_Correction
= iihdata
->DeltaMouseY
% GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
2656 iihdata
->DeltaMouseX
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
2657 iihdata
->DeltaMouseY
/= GetPrivIBase(IntuitionBase
)->ActivePreferences
->PointerTicks
;
2662 ie
->ie_X
= iihdata
->DeltaMouseX
+ iihdata
->LastMouseX
;
2663 ie
->ie_Y
= iihdata
->DeltaMouseY
+ iihdata
->LastMouseY
;
2665 //jDc: not really necessary to lock this for reading since this ptr is only modified
2666 //by functions synced with inputhandler
2667 //lock = LockIBase(0);
2668 scr
= IntuitionBase
->FirstScreen
;
2672 if (IntuitionBase
->FirstScreen
->Flags
& AUTOSCROLL
)
2675 #define VWIDTH IntuitionBase->ViewLord.ViewPort->DWidth
2676 #define VHEIGHT IntuitionBase->ViewLord.ViewPort->DHeight
2677 #define VDX IntuitionBase->ViewLord.ViewPort->DxOffset
2678 #define VDY IntuitionBase->ViewLord.ViewPort->DyOffset
2680 if ((ie
->ie_X
> VWIDTH
- scr
->LeftEdge
- 1) || (ie
->ie_X
< - scr
->LeftEdge
) ||
2681 (ie
->ie_Y
> VHEIGHT
- scr
->TopEdge
- 1) || (ie
->ie_Y
< - scr
->TopEdge
))
2683 if (ie
->ie_X
> VWIDTH
- scr
->LeftEdge
- 1)
2685 scr
->LeftEdge
= VWIDTH
- ie
->ie_X
;
2686 if (VWIDTH
- scr
->LeftEdge
> scr
->Width
) scr
->LeftEdge
= VWIDTH
- scr
->Width
;
2687 VDX
= scr
->LeftEdge
;
2690 if (ie
->ie_X
< -scr
->LeftEdge
)
2692 scr
->LeftEdge
= -ie
->ie_X
;
2693 if (scr
->LeftEdge
< VWIDTH
- scr
->Width
) scr
->LeftEdge
= VWIDTH
- scr
->Width
;
2694 if(scr
->LeftEdge
> 0) scr
->LeftEdge
= 0; // we don't support > 0 LeftEdges
2695 VDX
= scr
->LeftEdge
;
2698 if (ie
->ie_Y
> VHEIGHT
- scr
->TopEdge
- 1)
2700 scr
->TopEdge
= VHEIGHT
- ie
->ie_Y
;
2701 if (VHEIGHT
- scr
->TopEdge
> scr
->Height
) scr
->TopEdge
= VHEIGHT
- scr
->Height
;
2705 if (ie
->ie_Y
< -scr
->TopEdge
)
2707 scr
->TopEdge
= - ie
->ie_Y
;
2708 if (scr
->TopEdge
< VHEIGHT
- scr
->Height
) scr
->TopEdge
= VHEIGHT
- scr
->Height
;
2709 if(scr
->TopEdge
> 0) scr
->TopEdge
= 0;
2713 ScrollVPort(IntuitionBase
->ViewLord
.ViewPort
);
2717 if (ie
->ie_X
>= scr
->Width
+ max(scr
->LeftEdge
,0)) ie
->ie_X
= scr
->Width
+ max(scr
->LeftEdge
,0) - 1;
2718 if (ie
->ie_Y
>= scr
->Height
+ max(scr
->TopEdge
,0)) ie
->ie_Y
= scr
->Height
+ max(scr
->TopEdge
,0) - 1;
2719 if (ie
->ie_X
< - scr
->LeftEdge
) ie
->ie_X
= - scr
->LeftEdge
;
2720 if (ie
->ie_Y
< - scr
->TopEdge
) ie
->ie_Y
= - scr
->TopEdge
;
2725 if (ie
->ie_X
>= 320) ie
->ie_X
= 320 - 1;
2726 if (ie
->ie_Y
>= 200) ie
->ie_Y
= 200 - 1;
2727 if (ie
->ie_X
< 0) ie
->ie_X
= 0;
2728 if (ie
->ie_Y
< 0) ie
->ie_Y
= 0;
2730 //UnlockIBase(lock);
2734 iihdata
->DeltaMouseX
= ie
->ie_X
- iihdata
->LastMouseX
;
2735 iihdata
->DeltaMouseY
= ie
->ie_Y
- iihdata
->LastMouseY
;
2739 if (gadget
== iihdata
->MasterDragGadget
)
2744 gpi
.MethodID
= GM_MOVETEST
;
2746 gpi
.gpi_Mouse
.X
= ie
->ie_X
- gi
->gi_Window
->WScreen
->LeftEdge
;
2747 gpi
.gpi_Mouse
.Y
= ie
->ie_Y
- gi
->gi_Window
->WScreen
->TopEdge
;
2748 gpi
.gpi_IEvent
= ie
;
2750 retval
= Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpi
, IntuitionBase
);
2751 if (retval
== MOVETEST_ADJUSTPOS
)
2753 ie
->ie_X
= gpi
.gpi_Mouse
.X
+ gi
->gi_Window
->WScreen
->LeftEdge
;
2754 ie
->ie_Y
= gpi
.gpi_Mouse
.Y
+ gi
->gi_Window
->WScreen
->TopEdge
;
2759 /* Do Mouse Bounding - mouse will be most restrictive of screen size or mouse bounds */
2760 if (iihdata
->MouseBoundsActiveFlag
)
2762 if (ie
->ie_X
< iihdata
->MouseBoundsLeft
)
2764 ie
->ie_X
= iihdata
->MouseBoundsLeft
;
2766 else if (ie
->ie_X
> iihdata
->MouseBoundsRight
)
2768 ie
->ie_X
= iihdata
->MouseBoundsRight
;
2771 if (ie
->ie_Y
< iihdata
->MouseBoundsTop
)
2773 ie
->ie_Y
= iihdata
->MouseBoundsTop
;
2775 else if (ie
->ie_Y
> iihdata
->MouseBoundsBottom
)
2777 ie
->ie_Y
= iihdata
->MouseBoundsBottom
;
2781 #if !SINGLE_SETPOINTERPOS_PER_EVENTLOOP
2782 SetPointerPos(ie
->ie_X
, ie
->ie_Y
);
2784 pointerposx
= ie
->ie_X
;
2785 pointerposy
= ie
->ie_Y
;
2786 call_setpointerpos
= TRUE
;
2789 iihdata
->LastMouseX
= ie
->ie_X
;
2790 iihdata
->LastMouseY
= ie
->ie_Y
;
2792 notify_mousemove_screensandwindows(ie
->ie_X
,
2799 if (iihdata
->TitlebarOnTop
)
2801 if (IntuitionBase
->FirstScreen
->MouseY
> IntuitionBase
->FirstScreen
->BarHeight
&& GetPrivScreen(IntuitionBase
->FirstScreen
)->SpecialFlags
& SF_AppearingBar
)
2803 iihdata
->TitlebarOnTop
= FALSE
;
2804 iihdata
->TitlebarAppearTime
= 0;
2806 LOCK_REFRESH(IntuitionBase
->FirstScreen
);
2808 MoveLayer(0,IntuitionBase
->FirstScreen
->BarLayer
,0,-(IntuitionBase
->FirstScreen
->BarHeight
+ 1));
2809 CheckLayers(IntuitionBase
->FirstScreen
, IntuitionBase
);
2811 UNLOCK_REFRESH(IntuitionBase
->FirstScreen
);
2816 if (IntuitionBase
->FirstScreen
->MouseY
== 0 && GetPrivScreen(IntuitionBase
->FirstScreen
)->SpecialFlags
& SF_AppearingBar
&& !MENUS_ACTIVE
&& !(PeekQualifier() & (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_RBUTTON
|IEQUALIFIER_MIDBUTTON
)))
2818 if (!(iihdata
->TitlebarAppearTime
))
2820 iihdata
->TitlebarAppearTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
2821 iihdata
->TitlebarAppearTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
2826 iihdata
->TitlebarAppearTime
= 0;
2834 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
2843 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
2845 case GTYP_BOOLGADGET
:
2846 case 0: //fallback for sucky gadgets
2847 /* Must be a RELVERIFY gadget */
2851 inside
= InsideGadget(gi
->gi_Screen
,
2855 gi
->gi_Screen
->MouseX
,
2856 gi
->gi_Screen
->MouseY
);
2858 if (inside
!= iihdata
->MouseWasInsideBoolGadget
)
2860 iihdata
->MouseWasInsideBoolGadget
= inside
;
2862 gadget
->Flags
^= GFLG_SELECTED
;
2863 RefreshBoolGadgetState(gadget
, w
, req
, IntuitionBase
);
2868 case GTYP_PROPGADGET
:
2869 HandlePropMouseMove(gadget
,
2872 w
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
2873 w
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gadget
, gi
->gi_Screen
, gi
->gi_Window
, NULL
),
2878 case GTYP_CUSTOMGADGET
:
2879 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
2882 } /* switch GadgetType */
2884 } /* if (a gadget is currently active) */
2890 if (IW(w
)->helpflags
& HELPF_GADGETHELP
&& (!(PeekQualifier() & (IEQUALIFIER_LEFTBUTTON
|IEQUALIFIER_RBUTTON
|IEQUALIFIER_MIDBUTTON
))))
2895 hw
= FindActiveWindow(ie
, 0, IntuitionBase
);
2898 (!hw
|| !(IW(w
)->helpflags
& HELPF_ISHELPGROUP
) ||
2899 !(IW(hw
)->helpflags
& HELPF_ISHELPGROUP
) ||
2900 IW(w
)->helpgroup
!= IW(hw
)->helpgroup
))
2903 if (iihdata
->LastHelpWindow
)
2905 fire_intuimessage(w
,
2911 iihdata
->LastHelpGadget
= NULL
;
2912 iihdata
->LastHelpWindow
= NULL
;
2913 iihdata
->HelpGadgetFindTime
= 0;
2918 g
= FindHelpGadget (hw
,
2919 IntuitionBase
->ActiveScreen
->MouseX
,
2920 IntuitionBase
->ActiveScreen
->MouseY
,
2922 if (g
&& g
!= iihdata
->LastHelpGadget
)
2924 if (!iihdata
->LastHelpGadget
)
2926 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
2927 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
2931 if (hw
== iihdata
->LastHelpWindow
)
2933 iihdata
->HelpGadgetFindTime
= ((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50;
2934 iihdata
->HelpGadgetFindTime
+= ie
->ie_TimeStamp
.tv_micro
/ 20000;
2935 iihdata
->HelpGadgetFindTime
+= 25;//smaller delay
2939 else if (g
!= iihdata
->LastHelpGadget
||
2940 hw
!= iihdata
->LastHelpWindow
)
2942 fire_intuimessage(hw
,
2944 0, /* Don't know what it should be */
2949 iihdata
->LastHelpGadget
= g
;
2950 iihdata
->LastHelpWindow
= hw
;
2955 iihdata
->LastHelpGadget
= NULL
;
2956 iihdata
->LastHelpWindow
= NULL
;
2957 iihdata
->HelpGadgetFindTime
= 0;
2960 if (!(w
->IDCMPFlags
& IDCMP_MOUSEMOVE
)) break;
2962 /* Send IDCMP_MOUSEMOVE if WFLG_REPORTMOUSE is set
2963 and/or active gadget has GACT_FOLLOWMOUSE set */
2965 /* jDc: do NOT send when sizegad is pressed */
2967 if (!(w
->Flags
& WFLG_REPORTMOUSE
))
2970 if (!(gadget
->Activation
& GACT_FOLLOWMOUSE
)) break;
2974 if (gadget
&& (gadget
->GadgetType
& (GTYP_SIZING
|GTYP_WDRAGGING
))) break;
2977 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
2979 /* Limit the number of IDCMP_MOUSEMOVE messages sent to intuition.
2980 note that this comes after handling gadgets, because gadgets should get all events.
2983 if (IW(w
)->num_mouseevents
>= IW(w
)->mousequeue
)
2985 BOOL old_msg_found
= FALSE
;
2987 /* Mouse Queue is full, so try looking for a not
2988 yet GetMsg()ed IntuiMessage in w->UserPort
2989 trying to modify that. */
2994 struct IntuiMessage
*im
;
2996 for (im
= (struct IntuiMessage
*)w
->UserPort
->mp_MsgList
.lh_TailPred
;
2997 im
->ExecMessage
.mn_Node
.ln_Pred
;
2998 im
= (struct IntuiMessage
*)im
->ExecMessage
.mn_Node
.ln_Pred
)
3000 if ((im
->Class
== IDCMP_MOUSEMOVE
) &&
3001 (im
->IDCMPWindow
== w
))
3003 im
->Qualifier
= iihdata
->ActQualifier
;
3005 if (w
->IDCMPFlags
& IDCMP_DELTAMOVE
)
3007 im
->MouseX
= iihdata
->DeltaMouseX
;
3008 im
->MouseY
= iihdata
->DeltaMouseY
;
3012 im
->MouseX
= w
->MouseX
;
3013 im
->MouseY
= w
->MouseY
;
3015 CurrentTime(&im
->Seconds
, &im
->Micros
);
3017 old_msg_found
= TRUE
;
3021 } /* if (w->UserPort) */
3024 /* no need to send a new message if we modified
3025 an existing one ... */
3027 if (old_msg_found
) break;
3029 /* ... otherwise we are in a strange situation. The mouse
3030 queue is full, but we did not find an existing MOUSEMOVE
3031 imsg in w->UserPort. So the app probably has removed
3032 an imsg from the UserPort with GetMsg but we did not get
3033 the ReplyMsg, yet. In this case we do send a new message */
3035 HandleIntuiReplyPort(iihdata
, IntuitionBase
);
3039 /* MouseQueue is not full, so we can send a message. We increase
3040 IntWindow->num_mouseevents which will later be decreased after
3041 the Intuition InputHandler gets the ReplyMessage from the app
3042 and handles it in HandleIntuiReplyPort() */
3044 if (ih_fire_intuimessage(w
,
3050 IW(w
)->num_mouseevents
++;
3055 } /* case IECODE_NOBUTTON */
3057 } /* switch (ie->ie_Code) (what button was pressed ?) */
3060 #define KEY_QUALIFIERS (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT | \
3061 IEQUALIFIER_CAPSLOCK | IEQUALIFIER_CONTROL | \
3062 IEQUALIFIER_LALT | IEQUALIFIER_RALT | \
3063 IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND | \
3064 IEQUALIFIER_NUMERICPAD | IEQUALIFIER_REPEAT)
3066 case IECLASS_RAWKEY
:
3067 /* release events go only to gadgets and windows who
3068 have not set IDCMP_VANILLAKEY */
3070 DEBUG_HANDLER(dprintf("Handler: IECLASS_RAWKEY\n"));
3071 DEBUG_KEY(dprintf("Handler: Qual 0x%lx\n",iihdata
->ActQualifier
));
3073 iihdata
->ActQualifier
&= ~KEY_QUALIFIERS
;
3074 iihdata
->ActQualifier
|= (ie
->ie_Qualifier
& KEY_QUALIFIERS
);
3076 DEBUG_KEY(dprintf("Handler: real Qual 0x%lx\n",iihdata
->ActQualifier
));
3078 /* Keyboard mouse emulation */
3081 UWORD code
= ie
->ie_Code
& ~IECODE_UP_PREFIX
;
3083 /* Mouse button emulation: LALT + LAMIGA = LBUTTON, RALT + RAMIGA = RBUTTON */
3085 DEBUG_KEY(dprintf("Handler: code 0x%lx\n",code
));
3086 if ((code
== RAWKEY_LAMIGA
) ||
3087 (code
== RAWKEY_LALT
) ||
3088 (code
== RAWKEY_RAMIGA
) ||
3089 (code
== RAWKEY_RALT
))
3091 DEBUG_KEY(dprintf("Handler: KeyMouseEmul\n"));
3092 iihdata
->PrevKeyMouseState
= iihdata
->ActKeyMouseState
;
3093 iihdata
->ActKeyMouseState
= 0;
3094 if ((ie
->ie_Qualifier
& (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_LALT
)) == (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_LALT
))
3096 iihdata
->ActKeyMouseState
|= IEQUALIFIER_LEFTBUTTON
;
3098 if ((ie
->ie_Qualifier
& (IEQUALIFIER_RCOMMAND
| IEQUALIFIER_RALT
)) == (IEQUALIFIER_RCOMMAND
| IEQUALIFIER_RALT
))
3100 iihdata
->ActKeyMouseState
|= IEQUALIFIER_RBUTTON
;
3103 if ((iihdata
->ActKeyMouseState
& IEQUALIFIER_LEFTBUTTON
) != (iihdata
->PrevKeyMouseState
& IEQUALIFIER_LEFTBUTTON
))
3105 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
3106 orig_ie
->ie_SubClass
= 0;
3107 orig_ie
->ie_Code
= (iihdata
->ActKeyMouseState
& IEQUALIFIER_LEFTBUTTON
) ? IECODE_LBUTTON
: IECODE_LBUTTON
| IECODE_UP_PREFIX
;
3116 if ((iihdata
->ActKeyMouseState
& IEQUALIFIER_RBUTTON
) != (iihdata
->PrevKeyMouseState
& IEQUALIFIER_RBUTTON
))
3118 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
3119 orig_ie
->ie_SubClass
= 0;
3120 orig_ie
->ie_Code
= (iihdata
->ActKeyMouseState
& IEQUALIFIER_RBUTTON
) ? IECODE_RBUTTON
: IECODE_RBUTTON
| IECODE_UP_PREFIX
;
3129 } /* if key is one of LAMIGA/LALT/RAMIGA/RALT */
3131 if ((iihdata
->ActQualifier
& (IEQUALIFIER_LCOMMAND
| IEQUALIFIER_RCOMMAND
)) &&
3132 MouseCoordsRelative() &&
3133 ((ie
->ie_Code
== RAWKEY_UP
) ||
3134 (ie
->ie_Code
== RAWKEY_DOWN
) ||
3135 (ie
->ie_Code
== RAWKEY_LEFT
) ||
3136 (ie
->ie_Code
== RAWKEY_RIGHT
)))
3138 static BYTE xmap
[] = { 0, 0, 1, -1};
3139 static BYTE ymap
[] = {-1, 1, 0, 0};
3142 shift
= (iihdata
->ActQualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) ? 40 : 1;
3144 /* Mouse Move Emulation */
3146 orig_ie
->ie_Class
= IECLASS_RAWMOUSE
;
3147 orig_ie
->ie_SubClass
= 0;
3148 orig_ie
->ie_Code
= IECODE_NOBUTTON
;
3149 orig_ie
->ie_Qualifier
= IEQUALIFIER_RELATIVEMOUSE
;
3150 orig_ie
->ie_X
= xmap
[code
- RAWKEY_UP
] * shift
;
3151 orig_ie
->ie_Y
= ymap
[code
- RAWKEY_UP
] * shift
;
3160 /* End Keyboard mouse emulation */
3164 DEBUG_KEY(dprintf("Handler: FireMenuMessage\n"));
3165 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
3170 /* Hotkeys processing */
3175 if (!(ie
->ie_Code
& IECODE_UP_PREFIX
))
3176 if ((result
= RunHotkeys(ie
,IntuitionBase
)))
3178 if (result
== RUNHOTREUSE
)
3188 w
= IntuitionBase
->ActiveWindow
;
3193 ((!(ie
->ie_Code
& IECODE_UP_PREFIX
)) ||
3195 (w
&& ((w
->IDCMPFlags
& IDCMP_VANILLAKEY
) == 0)) ))
3201 DEBUG_KEY(dprintf("Handler: Gadget 0x%lx active\n",gadget
));
3202 DEBUG_KEY(dprintf("Handler: GadgetID 0x%lx UserData 0x%lx\n",
3205 DEBUG_KEY(dprintf("Handler: GadgetType 0x%lx Flags 0x%lx Activation 0x%lx\n",
3208 gadget
->Activation
));
3209 DEBUG_KEY(dprintf("Handler: MoreFlags 0x%lx\n",
3210 ((struct ExtGadget
*)gadget
)->MoreFlags
));
3212 switch (gadget
->GadgetType
& GTYP_GTYPEMASK
)
3214 case GTYP_STRGADGET
:
3217 ULONG ret
= HandleStrInput(gadget
, gi
, ie
, &imsgcode
,
3220 DEBUG_KEY(dprintf("Handler: Key GTYP_STRGADGET ret 0x%lx\n",ret
));
3221 if (ret
& (SGA_END
| SGA_NEXTACTIVE
| SGA_PREVACTIVE
))
3223 if (gadget
->Activation
& GACT_RELVERIFY
)
3225 DEBUG_KEY(dprintf("Handler: GACT_RELVERIFY\n"));
3226 ih_fire_intuimessage(w
,
3232 if (req
&& gadget
->Activation
& GACT_ENDGADGET
)
3234 DEBUG_KEY(dprintf("Handler: GACT_ENDGADGET\n"));
3237 req
= w
->FirstRequest
;
3242 if ((gadget
->Flags
& GFLG_TABCYCLE
) && (ret
& SGA_NEXTACTIVE
))
3244 gadget
= FindCycleGadget(w
, req
, gadget
, GMR_NEXTACTIVE
);
3245 DEBUG_KEY(dprintf("Handler: TabCycle next gadget 0x%lx\n",gadget
));
3247 else if ((gadget
->Flags
& GFLG_TABCYCLE
) && (ret
& SGA_PREVACTIVE
))
3249 gadget
= FindCycleGadget(w
, req
, gadget
, GMR_PREVACTIVE
);
3250 DEBUG_KEY(dprintf("Handler: TabCycle prev gadget 0x%lx\n",gadget
));
3259 gadget
= DoActivateGadget(w
, req
, gadget
, IntuitionBase
);
3262 } /* if (ret & (SGA_END | SGA_NEXTACTIVE | SGA_PREVACTIVE)) */
3267 case GTYP_CUSTOMGADGET
:
3268 DEBUG_KEY(dprintf("Handler: GTYP_CUSTOMGADGET\n"));
3269 DEBUG_KEY(dprintf("Handler: send GM_HANDLEINPUT\n"));
3270 gadget
= DoGPInput(gi
,
3276 DEBUG_KEY(dprintf("Handler: reuse %ld\n",reuse_event
));
3279 } /* switch (gadget type) */
3281 } /* if (a gadget is currently active) */
3282 else if (w
&& (!req
|| req
->Flags
& NOISYREQ
))
3284 BOOL menushortcut
= FALSE
;
3286 DEBUG_KEY(dprintf("Handler: No Gadget active\n"));
3287 DEBUG_KEY(dprintf("Handler: Qualifier 0x%lx WinFlags 0x%lx IDCMP 0x%lx\n",ie
->ie_Qualifier
,w
->Flags
,w
->IDCMPFlags
));
3289 if ((ie
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
) &&
3290 (!(w
->Flags
& WFLG_RMBTRAP
)) &&
3291 (w
->IDCMPFlags
& IDCMP_MENUPICK
))
3293 struct Menu
*strip
= 0;
3295 DEBUG_KEY(dprintf("Handler: MenuKey\n"));
3296 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
3298 strip
= w
->MenuStrip
;
3300 if (((struct IntWindow
*)w
)->menulendwindow
)
3302 strip
= ((struct IntWindow
*)w
)->menulendwindow
->MenuStrip
;
3305 DEBUG_KEY(dprintf("Handler: MenuStrip 0x%lx\n",strip
));
3310 if (MapRawKey(ie
, &key
, 1, NULL
) == 1)
3314 menucode
= FindMenuShortCut(strip
, key
, TRUE
, IntuitionBase
);
3316 DEBUG_KEY(dprintf("Handler: menucode 0x%lx\n",menucode
));
3318 if (menucode
!= MENUNULL
)
3320 DEBUG_KEY(dprintf("Handler: build menuevent\n"));
3321 ie
->ie_Class
= IECLASS_MENU
;
3322 ie
->ie_SubClass
= IESUBCLASS_MENUSTOP
;
3323 ie
->ie_EventAddress
= w
;
3324 ie
->ie_Code
= menucode
;
3327 menushortcut
= TRUE
;
3329 MENUS_ACTIVE
= TRUE
;
3330 iihdata
->MenuWindow
= w
;
3335 DEBUG_KEY(dprintf("Handler: MapRawKey failed\n"));
3338 if (!menushortcut
) /* !! */
3339 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
3341 } /* if could be a menu short cut */
3343 if ((ie
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
) &&
3344 (!(w
->IDCMPFlags
& IDCMP_MENUPICK
)))
3346 struct Menu
*strip
= 0;
3347 struct Window
*window
= w
;
3349 /* not sure here about RMBTRAP */
3350 DEBUG_KEY(dprintf("Handler: no idcmp, create a MENULIST idcmp\n"));
3352 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
3354 strip
= w
->MenuStrip
;
3356 if (((struct IntWindow
*)w
)->menulendwindow
)
3358 strip
= ((struct IntWindow
*)w
)->menulendwindow
->MenuStrip
;
3359 window
= ((struct IntWindow
*)w
)->menulendwindow
;
3362 DEBUG_KEY(dprintf("Handler: MenuStrip 0x%lx\n",strip
));
3367 if (MapRawKey(ie
, &key
, 1, NULL
) == 1)
3371 menucode
= FindMenuShortCut(strip
, key
, TRUE
, IntuitionBase
);
3373 DEBUG_KEY(dprintf("Handler: menucode 0x%lx\n",menucode
));
3375 if (menucode
!= MENUNULL
)
3377 DEBUG_KEY(dprintf("Handler: build menuevent\n"));
3378 ih_fire_intuimessage(window
,
3381 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machines!? */
3384 menushortcut
= TRUE
;
3389 DEBUG_KEY(dprintf("Handler: MapRawKey failed\n"));
3392 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
3393 } /* if could be a menu short but current window has no idcmp cut */
3397 DEBUG_KEY(dprintf("Handler: menu shortcut..break\n"));
3401 /* This is a regular RAWKEY event (no gadget taking care
3404 if (iihdata
->ActQualifier
& IEQUALIFIER_REPEAT
)
3406 /* don't send repeat key events if repeatqueue is full */
3407 if (IW(w
)->num_repeatevents
>= IW(w
)->repeatqueue
)
3409 DEBUG_KEY(dprintf("Handler: RepeatEvents full..don't send more\n"));
3414 if (w
->IDCMPFlags
& IDCMP_VANILLAKEY
)
3418 DEBUG_KEY(dprintf("Handler: VANILLAKEY\n"));
3419 // DEBUG_KEY(dprintf("Handler: MapRawKey ie 0x%lx KeyMapBase 0x%lx IntutionBase 0x%lx\n",ie,KeymapBase,IntuitionBase));
3421 if (MapRawKey(ie
, &keyBuffer
, 1, NULL
) == 1)
3423 DEBUG_KEY(dprintf("Handler: send VANILLAKEY msg\n"));
3424 ih_fire_intuimessage(w
,
3427 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machines!? */
3429 DEBUG_KEY(dprintf("Handler: done\n"));
3433 /* If the event mapped to more than one byte, it is not
3434 a legal VANILLAKEY, so we send it as the original
3439 if (w
->IDCMPFlags
& IDCMP_RAWKEY
)
3441 DEBUG_KEY(dprintf("Handler: send IDCMP_RAWKEY Qual 0x%lx Code 0x%lx addr 0x%lx Event\n",
3442 ie
->ie_Qualifier
,ie
->ie_Code
,ie
->ie_position
.ie_addr
));
3443 ih_fire_intuimessage(w
,
3446 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machine!? */
3451 DEBUG_KEY(dprintf("Handler: done\n"));
3452 } /* regular RAWKEY */
3455 break; /* case IECLASS_RAWKEY */
3458 if (iihdata
->MouseBoundsKillTimer
)
3460 iihdata
->MouseBoundsKillTimer
--;
3461 if (iihdata
->MouseBoundsKillTimer
== 0)
3463 iihdata
->MouseBoundsActiveFlag
= FALSE
;
3467 if (GetPrivIBase(IntuitionBase
)->PointerDelay
)
3469 ULONG lock
= LockIBase(0);
3471 if (--GetPrivIBase(IntuitionBase
)->PointerDelay
== 0)
3473 struct SharedPointer
*shared_pointer
;
3474 struct Window
*window
= IntuitionBase
->ActiveWindow
;
3475 struct IntScreen
*scr
;
3476 Object
*pointer
= ((struct IntWindow
*)window
)->pointer
;
3478 DEBUG_POINTER(dprintf("InputHandler: PointerDelay\n"));
3479 DEBUG_POINTER(dprintf("InputHandler: Pointer 0x%lx\n",
3484 DEBUG_POINTER(dprintf("InputHandler: Window 0x%lx\n",
3486 scr
= GetPrivScreen(window
->WScreen
);
3489 DEBUG_POINTER(dprintf("InputHandler: Screen 0x%lx\n",
3491 if (pointer
== NULL
)
3493 pointer
= GetPrivIBase(IntuitionBase
)->DefaultPointer
;
3496 if (((struct IntWindow
*)window
)->busy
)
3498 pointer
= GetPrivIBase(IntuitionBase
)->BusyPointer
;
3501 GetAttr(POINTERA_SharedPointer
, pointer
, (IPTR
*) &shared_pointer
);
3503 DEBUG_POINTER(dprintf("InputHandler: scr 0x%lx pointer 0x%lx shared_pointer 0x%lx\n",
3504 scr
, pointer
, shared_pointer
));
3505 DEBUG_POINTER(dprintf("InputHandler: sprite 0x%lx\n",
3506 shared_pointer
->sprite
));
3508 if (ChangeExtSpriteA(&scr
->Screen
.ViewPort
,
3509 scr
->Pointer
->sprite
, shared_pointer
->sprite
, NULL
))
3511 ObtainSharedPointer(shared_pointer
, IntuitionBase
);
3512 ReleaseSharedPointer(scr
->Pointer
, IntuitionBase
);
3513 scr
->Pointer
= shared_pointer
;
3516 window
->XOffset
= shared_pointer
->xoffset
;
3517 window
->YOffset
= shared_pointer
->yoffset
;
3522 DEBUG_POINTER(dprintf("InputHandler: can't set pointer.\n"));
3527 DEBUG_POINTER(dprintf("InputHandler: no screen.\n"));
3532 DEBUG_POINTER(dprintf("InputHandler: no window.\n"));
3539 if (GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
)
3541 struct IntScreen
*scr
= GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
;
3543 if ((--scr
->MenuVerifyTimeOut
) <= 0)
3545 struct InputEvent ie
;
3547 /* currently we ONLY need the menu open time ! */
3548 ie
.ie_TimeStamp
.tv_secs
= IntuitionBase
->Seconds
;
3549 ie
.ie_TimeStamp
.tv_micro
= IntuitionBase
->Micros
;
3551 if (FireMenuMessage(MMCODE_START
, scr
->MenuVerifyActiveWindow
, &ie
, IntuitionBase
))
3553 /* This lock will be released only when the user is
3554 done with menus = when IECLASS_MENU + IESUBCLASS_MENUSTOP
3555 event arrives (generated by MenuHandler task) */
3557 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
3558 iihdata
->MenuWindow
= scr
->MenuVerifyActiveWindow
;
3559 MENUS_ACTIVE
= TRUE
;
3562 scr
->MenuVerifyActiveWindow
= NULL
;
3563 scr
->MenuVerifyTimeOut
= 0;
3564 scr
->MenuVerifyMsgCount
= 0;
3565 scr
->MenuVerifySeconds
= 0;
3566 scr
->MenuVerifyMicros
= 0;
3567 GetPrivIBase(IntuitionBase
)->MenuVerifyScreen
= NULL
;
3570 else if (MENUS_ACTIVE
)
3572 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
3578 if (IntuitionBase
->FirstScreen
->MouseY
<= IntuitionBase
->FirstScreen
->BarHeight
&& GetPrivScreen(IntuitionBase
->FirstScreen
)->SpecialFlags
& SF_AppearingBar
&& !iihdata
->TitlebarOnTop
&& iihdata
->TitlebarAppearTime
)
3580 UQUAD currenttime
= (((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50) + (UQUAD
)(ie
->ie_TimeStamp
.tv_micro
/ 20000);
3581 if (currenttime
>= iihdata
->TitlebarAppearTime
+ 10)
3583 iihdata
->TitlebarOnTop
= TRUE
;
3584 iihdata
->TitlebarAppearTime
= 0;
3586 LOCK_REFRESH(IntuitionBase
->FirstScreen
);
3588 MoveLayer(0,IntuitionBase
->FirstScreen
->BarLayer
,0,IntuitionBase
->FirstScreen
->BarHeight
+ 1);
3589 UpfrontLayer(0,IntuitionBase
->FirstScreen
->BarLayer
);
3590 CheckLayers(IntuitionBase
->FirstScreen
, IntuitionBase
);
3592 UNLOCK_REFRESH(IntuitionBase
->FirstScreen
);
3598 UQUAD currenttime
= (((UQUAD
)ie
->ie_TimeStamp
.tv_secs
) * 50) + (UQUAD
)(ie
->ie_TimeStamp
.tv_micro
/ 20000);
3599 #define SECONDS(x) (x*50)
3600 if (iihdata
->HelpGadgetFindTime
&& (currenttime
>= iihdata
->HelpGadgetFindTime
+ SECONDS(1)))
3602 struct Gadget
*lhg
= iihdata
->LastHelpGadget
;
3603 fire_intuimessage(iihdata
->LastHelpWindow
,
3605 lhg
? lhg
->GadgetID
: 0, /* Don't know what it should be */
3608 iihdata
->HelpGadgetFindTime
= 0;
3614 if (IS_BOOPSI_GADGET(gadget
))
3616 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
3621 #if USE_NEWDISPLAYBEEP
3623 if (GetPrivIBase(IntuitionBase
)->BeepingScreens
)
3628 lock
= LockIBase(0);
3630 for (scr
= IntuitionBase
->FirstScreen
;
3631 scr
&& GetPrivIBase(IntuitionBase
)->BeepingScreens
;
3632 scr
= scr
->NextScreen
)
3634 if ((scr
->Flags
& BEEPING
) &&
3635 !GetPrivScreen(scr
)->BeepingCounter
--)
3637 GetPrivIBase(IntuitionBase
)->BeepingScreens
--;
3638 scr
->Flags
&= (UWORD
) ~BEEPING
;
3640 /* if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) <= 8)
3641 // visual beep on CLUT-screen
3643 // SetRGB4 (&screen->ViewPort, 0, scr->SaveColor0 & 0x000F, (scr->SaveColor0 & 0x00F0) >> 4, (scr->SaveColor0 & 0x0F00) >> 8);
3644 SetRGB32 (&scr->ViewPort, 0,
3645 GetPrivScreen(scr)->DisplayBeepColor0[0],
3646 GetPrivScreen(scr)->DisplayBeepColor0[1],
3647 GetPrivScreen(scr)->DisplayBeepColor0[2]
3651 // visual beep on hi- and truecolor screens
3653 RenderScreenBar(scr, FALSE, IntuitionBase);
3656 RenderScreenBar(scr
, FALSE
, IntuitionBase
);
3662 #endif /* USE_NEWDISPLAYBEEP */
3665 /* stegerg: on the Amiga, Intuition's InputHandler seems to always
3666 swallow IECLASS_TIMER InputEvents. They never reach InputHandlers with
3667 lower priorities. So we mark the event as eaten by Intuition */
3672 /* Send INTUITICK msg only if app already replied the last INTUITICK msg */
3673 if (w
->Flags
& WFLG_WINDOWTICKED
) break;
3675 if (w
->IDCMPFlags
& IDCMP_INTUITICKS
)
3677 /* Set the WINDOWTICKED flag, it will be cleared again when the app
3678 replies back the msg and the InputHandler handles the replymsg
3679 in HandleIntuiReplyPort() */
3681 ih_fire_intuimessage(w
,
3687 break; /* case IECLASS_TIMER */
3690 if (MENUS_ACTIVE
&& (ie
->ie_SubClass
== IESUBCLASS_MENUSTOP
))
3692 struct Window
*eventwin
= (struct Window
*)ie
->ie_EventAddress
;
3694 iihdata
->MenuWindow
= NULL
;
3695 MENUS_ACTIVE
= FALSE
;
3697 /* semaphore was locked when menu action started, see
3698 above where MMCODE_START MenuMessage is sent.
3700 It could have also have been looked if the user
3701 activated one of the menu key shortcuts, see
3702 "case IECLASS_RAWKEY" */
3704 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->MenuLock
);
3708 if (((struct IntWindow
*)eventwin
)->menulendwindow
)
3710 eventwin
= ((struct IntWindow
*)eventwin
)->menulendwindow
;
3713 ih_fire_intuimessage((struct Window
*)eventwin
,
3716 (struct Window
*)ie
->ie_EventAddress
,
3722 case IECLASS_DISKINSERTED
:
3723 case IECLASS_DISKREMOVED
:
3724 case IECLASS_NEWPREFS
:
3730 switch (ie
->ie_Class
)
3732 case IECLASS_DISKINSERTED
:
3733 idcmp
= IDCMP_DISKINSERTED
;
3736 case IECLASS_DISKREMOVED
:
3737 idcmp
= IDCMP_DISKREMOVED
;
3741 idcmp
= IDCMP_NEWPREFS
;
3743 * Here we need to update the mouse prefs and
3744 * maybe other stuff which comes from the global prefs file.
3749 lock
= LockIBase(0);
3751 for (scr
= IntuitionBase
->FirstScreen
; scr
; scr
= scr
->NextScreen
)
3755 for (win
= scr
->FirstWindow
; win
; win
= win
->NextWindow
)
3758 CHECKME, really use fire_intuimessage() here,
3759 instead of ih_fireintuimessage? Same for
3760 IDCMP_GADGETHELP above, BTW. */
3762 fire_intuimessage(win
,
3775 #define NEWMOUSEIDCMP !SysBase->MaxLocMem
3777 #define NEWMOUSEIDCMP FALSE
3779 case IECLASS_NEWMOUSE
:
3781 * The following is only needed on hardware not running
3782 * the NewMouse driver.
3784 if (w
->IDCMPFlags
& IDCMP_RAWKEY
&& NEWMOUSEIDCMP
)
3786 ih_fire_intuimessage(w
,
3789 ie
->ie_position
.ie_addr
, /* ie_dead.ie_prev[1|2]Down[Code|Qual]. 64 bit machine!? */
3799 case IECLASS_NEWTIMER
:
3802 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
3809 if (gadget
== iihdata
->MasterSizeGadget
)
3811 gadget
= DoGPInput(gi
, gadget
, ie
, GM_HANDLEINPUT
, &reuse_event
, IntuitionBase
);
3816 #endif /* __MORPHOS__ */
3821 FireMenuMessage(MMCODE_EVENT
, 0, ie
, IntuitionBase
);
3828 "[Intui] InputHandler: Unknown IEClass: addr = %x class = %d (origclass = %d)\n",
3829 orig_ie
, ie
->ie_Class
,orig_ie
->ie_Class
3833 } /* switch (ie->ie_Class) */
3838 else if (keep_event
&& !ie_used
)
3840 *iihdata
->EndInputEventChain
= orig_ie
;
3841 iihdata
->EndInputEventChain
= &orig_ie
->ie_NextEvent
;
3846 orig_ie
->ie_NextEvent
= iihdata
->FreeInputEvents
;
3847 iihdata
->FreeInputEvents
= orig_ie
;
3850 } /* for (each event in the chain) */
3852 iihdata
->ActiveGadget
= gadget
;
3854 D(bug("Outside pollingloop\n"));
3856 #if SINGLE_SETPOINTERPOS_PER_EVENTLOOP
3857 if (call_setpointerpos
)
3859 SetPointerPos(pointerposx
, pointerposy
);
3863 /* Terminate the event chain. */
3864 *iihdata
->EndInputEventChain
= NULL
;
3866 /* Transfer the list of allocated events in the list of events that should
3867 * be freed the next time the handler is entered.
3869 iihdata
->AllocatedInputEventList
= iihdata
->NewAllocatedInputEventList
;
3870 NEWLIST((struct List
*)&iihdata
->NewAllocatedInputEventList
);
3872 /* Reset the event chain here, not at the beginning of the handler, for
3873 * events that might be allocated in other handers.
3875 iihdata
->EndInputEventChain
= &iihdata
->ReturnInputEvent
;
3876 iihdata
->FreeInputEvents
= NULL
;
3878 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->InputHandlerLock
);
3880 // DEBUG_HANDLER(dprintf("Handler: ->IBase 0x%lx KeyMapBase 0x%lx\n",IntuitionBase,KeymapBase));
3882 return iihdata
->ReturnInputEvent
;
3887 /****************************************************************************************/