2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
6 Support functions for InputHandler.
9 /****************************************************************************************/
11 #include <aros/config.h>
13 #include <proto/exec.h>
14 #include <proto/execlock.h>
15 #include <proto/intuition.h>
16 #include <proto/alib.h>
17 #include <proto/layers.h>
18 #include <proto/graphics.h>
19 #include <proto/utility.h>
20 #include <proto/keymap.h>
21 #include <exec/memory.h>
22 #include <exec/alerts.h>
23 #include <exec/interrupts.h>
24 #include <exec/ports.h>
25 #include <intuition/intuition.h>
26 #include <intuition/intuitionbase.h>
27 #include <intuition/gadgetclass.h>
28 #include <intuition/cghooks.h>
29 #include <intuition/sghooks.h>
30 #include <devices/inputevent.h>
34 #include "inputhandler.h"
36 #include "boopsigadgets.h"
37 #include "boolgadgets.h"
38 #include "propgadgets.h"
39 #include "strgadgets.h"
41 #include "intuition_intern.h" /* EWFLG_xxx */
42 #include "inputhandler_actions.h"
43 #include "inputhandler_support.h"
52 #include <aros/debug.h>
54 #define DEBUG_WINDOWNEEDSREFRESH(x) ;
55 #define DEBUG_DOGPINPUT(x) ;
56 #define DEBUG_HANDLECUSTOMRETVAL(x) ;
57 #define DEBUG_ACTIVATEGADGET(x) ;
58 #define DEBUG_FIREINTUIMSG(x) ;
59 #define DEBUG_CLICK(x)
63 /****************************************************************************************/
66 All screens and windows on active monitor will be updated with the current position of
67 the mouse pointer. Windows will receive relative mouse coordinates.
70 /****************************************************************************************/
72 void notify_mousemove_screensandwindows(struct IntuitionBase
* IntuitionBase
)
74 LONG lock
= LockIBase(0);
77 for (scr
= IntuitionBase
->FirstScreen
; scr
; scr
= scr
->NextScreen
)
81 /* Ignore screens which are not on our current monitor */
82 if (GetPrivScreen(scr
)->IMonitorNode
!= GetPrivIBase(IntuitionBase
)->ActiveMonitor
)
85 scr
->MouseX
= IntuitionBase
->MouseX
- scr
->LeftEdge
;
86 scr
->MouseY
= IntuitionBase
->MouseY
- scr
->TopEdge
;
88 /* update windows belonging to this screen */
89 for (win
= scr
->FirstWindow
; win
; win
= win
->NextWindow
)
91 UpdateMouseCoords(win
);
98 /****************************************************************************************/
100 void send_intuimessage(struct IntuiMessage
*imsg
, struct Window
*w
,
101 struct IntuitionBase
*IntuitionBase
)
103 SendIntuiMessage(w
, imsg
);
106 /****************************************************************************************/
108 void free_intuimessage(struct IntuiMessage
*imsg
,
109 struct IntuitionBase
*IntuitionBase
)
111 FreeIntuiMessage(imsg
);
114 /****************************************************************************************/
116 struct IntuiMessage
*alloc_intuimessage(struct Window
*w
,
117 struct IntuitionBase
*IntuitionBase
)
119 struct IntuiMessage
*imsg
;
121 imsg
= AllocIntuiMessage(w
);
126 if (w
->IDCMPFlags
& IDCMP_DELTAMOVE
)
128 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
130 imsg
->MouseX
= iihd
->DeltaMouseX
;
131 imsg
->MouseY
= iihd
->DeltaMouseY
;
135 imsg
->MouseX
= w
->MouseX
;
136 imsg
->MouseY
= w
->MouseY
;
139 CurrentTime(&imsg
->Seconds
, &imsg
->Micros
);
145 /****************************************************************************************/
147 BOOL
fire_intuimessage(struct Window
*w
,
151 struct IntuitionBase
*IntuitionBase
)
153 struct IntuiMessage
*imsg
;
156 if ((w
->IDCMPFlags
& Class
) && (w
->UserPort
))
158 if ((imsg
= alloc_intuimessage(w
, IntuitionBase
)))
160 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
164 imsg
->Qualifier
= iihd
->ActQualifier
;
165 if (Class
== IDCMP_RAWKEY
)
167 INT_INTUIMESSAGE(imsg
)->prevCodeQuals
= IAddress
;
168 imsg
->IAddress
= &INT_INTUIMESSAGE(imsg
)->prevCodeQuals
;
172 imsg
->IAddress
= IAddress
;
175 send_intuimessage(imsg
, w
, IntuitionBase
);
181 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: can't alloc imsg\n"));
186 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: no Userport or masked out idcmpflags\n"));
192 BOOL
fire_message(struct Window
*w
,ULONG Class
, UWORD Code
, APTR IAddress
, struct IntuitionBase
*IntuitionBase
)
194 struct Library
*UtilityBase
= GetPrivIBase(IntuitionBase
)->UtilityBase
;
195 struct ExtIntuiMessage
*imsg
;
198 if ((w
->IDCMPFlags
& Class
) && (w
->UserPort
))
200 if ((imsg
= (struct ExtIntuiMessage
*)alloc_intuimessage(w
, IntuitionBase
)))
202 struct IIHData
*iihdata
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
204 imsg
->eim_IntuiMessage
.Class
= Class
;
205 imsg
->eim_IntuiMessage
.Code
= Code
;
206 imsg
->eim_IntuiMessage
.Qualifier
= iihdata
->ActQualifier
;
207 if (Class
== IDCMP_RAWKEY
)
209 INT_INTUIMESSAGE(imsg
)->prevCodeQuals
= IAddress
;
210 imsg
->eim_IntuiMessage
.IAddress
= &INT_INTUIMESSAGE(imsg
)->prevCodeQuals
;
214 imsg
->eim_IntuiMessage
.IAddress
= IAddress
;
217 if (iihdata
->ActEventTablet
&& (w
->MoreFlags
& WMFLG_TABLETMESSAGES
))
219 if ((imsg
->eim_TabletData
= AllocPooled(GetPrivIBase(IntuitionBase
)->IDCMPPool
,sizeof (struct TabletData
))))
221 memclr(imsg
->eim_TabletData
,sizeof (struct TabletData
));
222 imsg
->eim_TabletData
->td_XFraction
= iihdata
->ActEventTablet
->ient_ScaledXFraction
;
223 imsg
->eim_TabletData
->td_YFraction
= iihdata
->ActEventTablet
->ient_ScaledYFraction
;
224 imsg
->eim_TabletData
->td_TabletX
= iihdata
->ActEventTablet
->ient_TabletX
;
225 imsg
->eim_TabletData
->td_TabletY
= iihdata
->ActEventTablet
->ient_TabletY
;
226 imsg
->eim_TabletData
->td_RangeX
= iihdata
->ActEventTablet
->ient_RangeX
;
227 imsg
->eim_TabletData
->td_RangeY
= iihdata
->ActEventTablet
->ient_RangeY
;
228 imsg
->eim_TabletData
->td_TagList
= CloneTagItems(iihdata
->ActEventTablet
->ient_TagList
);
232 send_intuimessage((struct IntuiMessage
*)imsg
, w
, IntuitionBase
);
238 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: can't alloc imsg\n"));
243 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: no Userport or masked out idcmpflags\n"));
249 /****************************************************************************************/
252 use ih_fire_intuimessage if A) the inputevent because of which
253 you call this function might have to be eaten or modified
254 by Intuition or B) an inputevent might have to be created
255 by Intuition because of a deferred action.
257 In any case this function may be called only from inside Intuition's
261 /****************************************************************************************/
263 BOOL
ih_fire_intuimessage(struct Window
* w
,
267 struct IntuitionBase
*IntuitionBase
)
269 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
270 struct InputEvent
*ie
/* = iihd->ActInputEvent*/;
274 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: win 0x%lx class 0x%lx code 0x%lx IAddress 0x%lx\n",
280 result
= fire_message(w
, Class
, Code
, IAddress
, IntuitionBase
);
282 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: fire_intuimessage result 0x%lx\n",
285 if (result
/*&& ie*/)
287 /* was sent as IDCMP to window so eat inputevent */
289 //ie->ie_Class = IECLASS_NULL;
294 else if (ie
/* && (ie->ie_Class != IECLASS_NULL) && !iihd->ActInputEventUsed*/)
297 /* ih_fire_intuimessage was called from inside Intuition's event handling loop */
299 //iihd->ActInputEventUsed = TRUE;
303 //ie->ie_Qualifier = iihd->ActQualifier;
304 ie
->ie_EventAddress
= IAddress
;
309 /* Note: on the Amiga if a boopsi Gadget which is GA_Immediate
310 and GA_RelVerify immediately in GM_GOACTIVE returns GMR_VERIFY,
311 then this sends IDCMP_GADGETDOWN + IDCMP_GADGETUP. AROS does
312 the same. But for changed inputevents (if window does not have this
313 IDCMP Flags set) there will be only one IECLASS_GADGETDOWN
316 ie
->ie_Class
= IECLASS_GADGETUP
;
319 case IDCMP_GADGETDOWN
:
320 ie
->ie_Class
= IECLASS_GADGETDOWN
;
323 case IDCMP_ACTIVEWINDOW
:
324 ie
->ie_Class
= IECLASS_ACTIVEWINDOW
;
327 case IDCMP_INACTIVEWINDOW
:
328 ie
->ie_Class
= IECLASS_INACTIVEWINDOW
;
331 case IDCMP_CLOSEWINDOW
:
332 ie
->ie_Class
= IECLASS_CLOSEWINDOW
;
336 ie
->ie_Class
= IECLASS_MENUHELP
;
340 ie
->ie_Class
= IECLASS_MENULIST
;
343 case IDCMP_MOUSEBUTTONS
:
344 case IDCMP_MOUSEMOVE
:
346 case IDCMP_VANILLAKEY
:
350 D(bug("ih_fireintuimessage: unexpected IDCMP (%x) for an inputevent-handling-fireintuimessage!\n", Class
));
358 /* ih_fire_intuimessage was called from inside Intuition's defered action handling routines */
360 if ((ie
= AllocInputEvent(iihd
)))
365 ie
->ie_Class
= IECLASS_SIZEWINDOW
;
368 case IDCMP_CHANGEWINDOW
:
369 ie
->ie_Class
= IECLASS_CHANGEWINDOW
;
372 case IDCMP_ACTIVEWINDOW
:
373 ie
->ie_Class
= IECLASS_ACTIVEWINDOW
;
376 case IDCMP_INACTIVEWINDOW
:
377 ie
->ie_Class
= IECLASS_INACTIVEWINDOW
;
380 case IDCMP_CLOSEWINDOW
:
381 ie
->ie_Class
= IECLASS_CLOSEWINDOW
;
385 ie
->ie_Class
= IECLASS_GADGETUP
;
388 case IDCMP_GADGETDOWN
:
389 ie
->ie_Class
= IECLASS_GADGETDOWN
;
392 case IDCMP_REFRESHWINDOW
:
393 ie
->ie_Class
= IECLASS_REFRESHWINDOW
;
397 ie
->ie_Class
= IECLASS_MENUHELP
;
401 ie
->ie_Class
= IECLASS_MENULIST
;
405 D(bug("ih_fireintuimessage: unexpected IDCMP (0x%X) for a deferred-action-fireintuimessage!\n", Class
));
408 } /* switch(Class) */
411 ie
->ie_Qualifier
= iihd
->ActQualifier
;
412 ie
->ie_EventAddress
= IAddress
;
413 CurrentTime(&ie
->ie_TimeStamp
.tv_secs
, &ie
->ie_TimeStamp
.tv_micro
);
415 D(bug("ih_fireintuimessage: generated InputEvent. Class = 0x%X Code = %d EventAddress = 0x%X\n",
418 ie
->ie_EventAddress
));
420 } /* if ((ie = AllocInputEvent(iihd))) */
423 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: result 0x%lx\n",
429 /*********************************************************************/
431 /* This function must never be called with the layer/layerinfo locked,
432 * otherwise a deadlock with ObtainGIRPort can happen.
434 IPTR
Locked_DoMethodA (struct Window
*w
, struct Gadget
*g
, Msg message
, struct IntuitionBase
*IntuitionBase
)
436 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
438 BOOL lock
= w
&& (g
->GadgetType
& GTYP_SYSGADGET
&&
439 ((g
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
||
440 (g
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
));
444 LOCK_REFRESH(w
->WScreen
);
447 LOCKGADGET(IntuitionBase
)
448 rc
= Custom_DoMethodA(IntuitionBase
, g
, message
);
449 UNLOCKGADGET(IntuitionBase
)
453 UNLOCK_REFRESH(w
->WScreen
);
459 /*********************************************************************/
461 IPTR
Custom_DoMethodA (struct IntuitionBase
*IntuitionBase
, struct Gadget
*g
, Msg message
)
463 if (g
->MutualExclude
)
465 return AROS_UFC4(IPTR
, ((struct Hook
*)g
->MutualExclude
)->h_Entry
,
466 AROS_UFCA(struct Hook
*, (struct Hook
*)g
->MutualExclude
, A0
),
467 AROS_UFCA(struct Gadget
*, g
, A2
),
468 AROS_UFCA(APTR
, message
, A1
),
469 AROS_UFCA(struct IntuitionBase
*, IntuitionBase
, A6
));
471 else /* Not needed since gadgetclass sets MutualExclude, but doesn't hurt. */
472 return DoMethodA((Object
*)g
, message
);
475 /****************************************************************************************/
477 void NotifyDepthArrangement(struct Window
*w
, struct IntuitionBase
*IntuitionBase
)
479 if(w
->MoreFlags
& WMFLG_NOTIFYDEPTH
)
481 ih_fire_intuimessage(w
,
490 /****************************************************************************************/
492 void PrepareGadgetInfo(struct GadgetInfo
*gi
, struct Screen
*scr
, struct Window
*win
,
493 struct Requester
*req
)
497 gi
->gi_Requester
= req
;
499 gi
->gi_Pens
.DetailPen
= scr
->DetailPen
;
500 gi
->gi_Pens
.BlockPen
= scr
->BlockPen
;
501 gi
->gi_DrInfo
= (APTR
)&(((struct IntScreen
*)gi
->gi_Screen
)->DInfo
);
504 /****************************************************************************************/
506 void SetGadgetInfoGadget(struct GadgetInfo
*gi
, struct Gadget
*gad
,
507 struct IntuitionBase
*IntuitionBase
)
509 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
510 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
512 SET_GI_RPORT(gi
, gi
->gi_Window
, gi
->gi_Requester
, gad
);
513 InitRastPort(&iihd
->GadgetInfoRastPort
);
515 iihd
->GadgetInfoRastPort
.Layer
= gi
->gi_RastPort
->Layer
;
516 iihd
->GadgetInfoRastPort
.BitMap
= gi
->gi_RastPort
->BitMap
;
518 SetFont(&iihd
->GadgetInfoRastPort
, gi
->gi_DrInfo
->dri_Font
);
520 gi
->gi_Layer
= gi
->gi_RastPort
->Layer
;
521 gi
->gi_RastPort
= &iihd
->GadgetInfoRastPort
;
523 GetGadgetDomain(gad
, gi
->gi_Screen
, gi
->gi_Window
, gi
->gi_Requester
, &gi
->gi_Domain
);
526 /****************************************************************************************/
528 void SetGPIMouseCoords(struct gpInput
*gpi
, struct Gadget
*gad
)
530 struct GadgetInfo
*gi
= gpi
->gpi_GInfo
;
534 if (IS_SCREEN_GADGET(gad
) || !gi
->gi_Window
)
536 mousex
= gi
->gi_Screen
->MouseX
;
537 mousey
= gi
->gi_Screen
->MouseY
;
542 mousex
= gi
->gi_Window
->MouseX
;
543 mousey
= gi
->gi_Window
->MouseY
;
546 gpi
->gpi_Mouse
.X
= mousex
- gi
->gi_Domain
.Left
- GetGadgetLeft(gad
, gi
->gi_Screen
, gi
->gi_Window
, gi
->gi_Requester
);
547 gpi
->gpi_Mouse
.Y
= mousey
- gi
->gi_Domain
.Top
- GetGadgetTop(gad
, gi
->gi_Screen
, gi
->gi_Window
, gi
->gi_Requester
);
551 /****************************************************************************************/
553 void HandleSysGadgetVerify(struct GadgetInfo
*gi
, struct Gadget
*gadget
,
554 struct IntuitionBase
*IntuitionBase
)
556 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
558 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
560 switch(gadget
->GadgetType
& GTYP_SYSTYPEMASK
)
564 if (((struct IntWindow
*)(gi
->gi_Window
))->specialflags
& SPFLAG_IAMDEAD
)
566 CrashedDispose(gi
->gi_Window
,IntuitionBase
);
571 ih_fire_intuimessage(gi
->gi_Window
,
582 if (!IsLayerHiddenBySibling(WLAYER(gi
->gi_Window
), FALSE
)
583 || (iihd
->ActQualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) != 0)
585 /* Send window to back */
586 WindowToBack(gi
->gi_Window
);
590 /* Send window to front */
591 WindowToFront(gi
->gi_Window
);
596 ZipWindow(gi
->gi_Window
);
600 scr
= FindFirstScreen(GetPrivIBase(IntuitionBase
)->ActiveMonitor
, IntuitionBase
);
601 if (gi
->gi_Screen
== scr
602 || (iihd
->ActQualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) != 0)
604 ScreenToBack(gi
->gi_Screen
);
608 ScreenToFront(gi
->gi_Screen
);
612 } /* switch(gad->GadgetType & GTYP_SYSTYPEMASK) */
615 /****************************************************************************************/
617 struct Gadget
*HandleCustomGadgetRetVal(IPTR retval
, struct GadgetInfo
*gi
, struct Gadget
*gadget
,
618 ULONG termination
, BOOL
*reuse_event
,
619 struct IntuitionBase
*IntuitionBase
)
621 struct IIHData
*iihdata
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
623 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: retval %ld gi 0x%lx gadget 0x%lx termination %ld reuse %ld\n",
630 if (retval
!= GMR_MEACTIVE
)
632 struct gpGoInactive gpgi
;
634 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: !GMR_MEACTIVE\n"));
636 if (retval
& GMR_REUSE
)
638 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: GMR_REUSE\n"));
642 if (retval
& GMR_VERIFY
)
644 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: GMR_VERIFY\n"));
645 if (IS_SYS_GADGET(gadget
))
647 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: SysGad\n"));
648 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
652 /* Not a system gadget. Send IDCMP_GADGETUP, but not
653 if it is a screen gadget where gi->gi_Window would
656 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: no sysgad\n"));
657 if ((gadget
->Activation
& GACT_RELVERIFY
) &&
660 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: Send IDCMP_GADGETUP\n"));
661 ih_fire_intuimessage(gi
->gi_Window
,
663 termination
& 0x0000FFFF,
668 } /* switch(gad->GadgetType & GTYP_SYSTYPEMASK) */
670 } /* if (retval & GMR_VERIFY) */
672 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: Send GM_GOINACTIVE\n"));
674 gpgi
.MethodID
= GM_GOINACTIVE
;
675 gpgi
.gpgi_GInfo
= gi
;
678 Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpgi
, IntuitionBase
);
680 if (SYSGADGET_ACTIVE
)
682 /* Switch back from Master Drag or Size Gadget to
683 real/original/app Size or Drag Gadget */
685 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: SYSGADGET_ACTIVE\n"));
686 gadget
= iihdata
->ActiveSysGadget
;
687 iihdata
->ActiveSysGadget
= NULL
;
689 if (IS_BOOPSI_GADGET(gadget
))
691 Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpgi
, IntuitionBase
);
695 if ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING2
)
697 ih_fire_intuimessage(gi
->gi_Window
,
708 if (retval
& GMR_VERIFY
&& gi
->gi_Requester
&& gadget
->Activation
& GACT_ENDGADGET
)
710 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: EndRequest\n"));
711 EndRequest(gi
->gi_Requester
, gi
->gi_Window
);
715 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
717 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle 0x%lx retval 0x%lx\n",
718 (gadget
->Flags
& GFLG_TABCYCLE
),
721 if ((gadget
->Flags
& GFLG_TABCYCLE
) && (retval
& GMR_NEXTACTIVE
))
723 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle+GMR_NEXTACTIVE\n"));
724 gadget
= FindCycleGadget(gi
->gi_Window
, gi
->gi_Requester
, gadget
, GMR_NEXTACTIVE
);
726 else if ((gadget
->Flags
& GFLG_TABCYCLE
) && (retval
& GMR_PREVACTIVE
))
728 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle+GMR_PREVACTIVE\n"));
729 gadget
= FindCycleGadget(gi
->gi_Window
, gi
->gi_Requester
, gadget
, GMR_PREVACTIVE
);
734 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: No gadget\n"));
739 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: activate gadget 0x%lx\n",gadget
));
740 gadget
= DoActivateGadget(gi
->gi_Window
, gi
->gi_Requester
, gadget
, IntuitionBase
);
743 } /* if (retval != GMR_MEACTIVE) */
746 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: set GACT_ACTIVEGADGET\n"));
747 gadget
->Activation
|= GACT_ACTIVEGADGET
;
750 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: return 0x%x\n", gadget
));
754 /****************************************************************************************/
756 /* This function must never be called with the layer/layerinfo locked,
757 * otherwise a deadlock with ObtainGIRPort can happen.
759 struct Gadget
*DoGPInput(struct GadgetInfo
*gi
, struct Gadget
*gadget
,
760 struct InputEvent
*ie
, STACKULONG methodid
,
761 BOOL
*reuse_event
, struct IntuitionBase
*IntuitionBase
)
763 struct IIHData
*iihdata
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
767 ie
->ie_Qualifier
= iihdata
->ActQualifier
;
769 gpi
.MethodID
= methodid
;
772 gpi
.gpi_Termination
= &termination
;
773 gpi
.gpi_TabletData
= NULL
;
775 SetGPIMouseCoords(&gpi
, gadget
);
777 retval
= Locked_DoMethodA (gi
->gi_Window
, gadget
, (Msg
)&gpi
, IntuitionBase
);
779 DEBUG_DOGPINPUT(dprintf("DoGPInput: Locked_DoMethod gadget %p method 0x%lx retval %ld termination 0x%lx\n",
780 gadget
, methodid
, retval
, termination
));
782 return HandleCustomGadgetRetVal(retval
, gi
, gadget
, termination
,
783 reuse_event
, IntuitionBase
);
787 /****************************************************************************************/
789 struct Gadget
* FindGadget (struct Screen
*scr
, struct Window
* window
,
790 struct Requester
* req
, int x
, int y
,
791 struct GadgetInfo
* gi
,BOOL sysonly
,
792 struct IntuitionBase
*IntuitionBase
)
794 struct Gadget
*gadget
, *firstgadget
, *draggadget
= 0;
795 struct gpHitTest gpht
;
798 BOOL sys_only
= sysonly
;
800 DEBUG_CLICK(bug("[Inputhandler] FindGadget(0x%p, 0x%p, 0x%p, %d, %d, %d)\n", scr
, window
, req
, x
, y
, sysonly
));
801 gpht
.MethodID
= GM_HITTEST
;
802 gpht
.gpht_GInfo
= gi
;
804 while (req
|| window
|| scr
)
808 firstgadget
= req
->ReqGadget
;
812 firstgadget
= window
->FirstGadget
;
816 if (draggadget
) return draggadget
;
817 firstgadget
= scr
->FirstGadget
;
820 for (gadget
= firstgadget
; gadget
; gadget
= gadget
->NextGadget
)
822 if (!(gadget
->Flags
& GFLG_DISABLED
) &&
824 (gadget
->GadgetType
& GTYP_SYSGADGET
&&
825 ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
||
826 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
||
827 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
||
828 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SDEPTH
||
829 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WZOOM
||
830 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_CLOSE
))))
832 /* stegerg: domain depends on gadgettype and windowflags! */
833 GetGadgetDomain(gadget
, scr
, window
, req
, &gi
->gi_Domain
);
835 /* Get coords relative to window */
837 GetGadgetIBox(gadget
, gi
, &ibox
);
839 xrel
= x
- gi
->gi_Domain
.Left
;
840 yrel
= y
- gi
->gi_Domain
.Top
;
844 xrel -= req->LeftEdge + window->BorderLeft;
845 yrel -= req->TopEdge + window->BorderTop;
850 xrel
-= window
->LeftEdge
;
851 yrel
-= window
->TopEdge
;
854 if ((xrel
>= ibox
.Left
) &&
855 (yrel
>= ibox
.Top
) &&
856 (xrel
< ibox
.Left
+ ibox
.Width
) &&
857 (yrel
< ibox
.Top
+ ibox
.Height
))
859 if ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
)
861 if (!draggadget
) draggadget
= gadget
;
866 if ((gadget
->GadgetType
& GTYP_GTYPEMASK
) == GTYP_CUSTOMGADGET
)
869 gpht
.gpht_Mouse
.X
= xrel
- ibox
.Left
;
870 gpht
.gpht_Mouse
.Y
= yrel
- ibox
.Top
;
872 /* jDc: don't check for == GMR_GADGETHIT since some reaction classes*/
873 /* (BURN IN HELL!) return TRUE here (related to imageclass HITEST?)*/
874 if (Locked_DoMethodA (window
, gadget
, (Msg
)&gpht
, IntuitionBase
))
884 } /* if (!(gadget->Flags & GFLG_DISABLED)) */
886 } /* for (gadget = window->FirstGadget; gadget; gadget = gadget->NextGadget) */
898 draggadget
= findbordergadget(window
,draggadget
,IntuitionBase
);
911 /****************************************************************************************/
913 struct Gadget
* FindHelpGadget (struct Window
* window
,
914 int x
, int y
, struct IntuitionBase
*IntuitionBase
)
916 struct Gadget
*gadget
, *firstgadget
;
917 struct Requester
*req
= window
->FirstRequest
;
919 while (req
|| window
)
923 firstgadget
= req
->ReqGadget
;
927 firstgadget
= window
->FirstGadget
;
930 for (gadget
= firstgadget
; gadget
; gadget
= gadget
->NextGadget
)
932 if ((gadget
->Flags
& GFLG_EXTENDED
) &&
933 (((struct ExtGadget
*)gadget
)->MoreFlags
& GMORE_GADGETHELP
))
935 if (InsideGadget(window
->WScreen
, window
, req
, gadget
, x
, y
))
944 req
= req
->OlderRequest
;
951 } /* FindHelpGadget */
954 /****************************************************************************************/
956 BOOL
InsideGadget(struct Screen
*scr
, struct Window
*win
, struct Requester
*req
,
957 struct Gadget
*gad
, WORD x
, WORD y
)
962 GetScrGadgetIBox(gad
, scr
, win
, req
, &box
);
964 if ((x
>= box
.Left
) &&
966 (x
< box
.Left
+ box
.Width
) &&
967 (y
< box
.Top
+ box
.Height
))
975 /****************************************************************************************/
977 struct Gadget
*DoActivateGadget(struct Window
*win
, struct Requester
*req
, struct Gadget
*gad
,
978 struct IntuitionBase
*IntuitionBase
)
980 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
981 struct GadgetInfo
*gi
= &iihd
->GadgetInfo
;
982 struct Gadget
*result
= NULL
;
984 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Window 0x%lx Req 0x%lx Gadget 0x%lx\n",
989 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Activation 0x%lx\n",
992 if (gad
->Activation
& GACT_IMMEDIATE
)
994 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Send GADGETDOWN msg\n"));
995 ih_fire_intuimessage(win
,
1002 PrepareGadgetInfo(gi
, win
->WScreen
, win
, req
);
1003 SetGadgetInfoGadget(gi
, gad
, IntuitionBase
);
1005 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Type 0x%lx\n",
1006 gad
->GadgetType
& GTYP_GTYPEMASK
));
1008 switch(gad
->GadgetType
& GTYP_GTYPEMASK
)
1010 case GTYP_STRGADGET
:
1012 struct StringInfo
*si
= (struct StringInfo
*)gad
->SpecialInfo
;
1014 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: GTYP_STRGADGET\n"));
1016 gad
->Flags
|= GFLG_SELECTED
;
1017 if (si
&& si
->UndoBuffer
)
1019 strcpy(si
->UndoBuffer
, si
->Buffer
);
1022 gad
->Activation
|= GACT_ACTIVEGADGET
;
1023 UpdateStrGadget(gad
, win
, req
, IntuitionBase
);
1028 case GTYP_CUSTOMGADGET
:
1035 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: GTYP_CUSTOMGADGET\n"));
1037 gpi
.MethodID
= GM_GOACTIVE
;
1039 gpi
.gpi_IEvent
= NULL
;
1040 gpi
.gpi_Termination
= &termination
;
1041 gpi
.gpi_Mouse
.X
= win
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gad
, gi
->gi_Screen
, gi
->gi_Window
, NULL
);
1042 gpi
.gpi_Mouse
.Y
= win
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gad
, gi
->gi_Screen
, gi
->gi_Window
, NULL
);
1043 gpi
.gpi_TabletData
= NULL
;
1045 retval
= Locked_DoMethodA (win
, gad
, (Msg
)&gpi
, IntuitionBase
);
1047 gad
= HandleCustomGadgetRetVal(retval
, gi
, gad
,termination
,
1048 &reuse_event
, IntuitionBase
);
1052 gad
->Activation
|= GACT_ACTIVEGADGET
;
1058 } /* switch(gad->GadgetType & GTYP_GTYPEMASK) */
1060 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: result 0x%lx\n",
1063 if (result
) iihd
->ActiveGadget
= result
;
1069 /****************************************************************************************/
1071 struct Gadget
*FindCycleGadget(struct Window
*win
, struct Requester
*req
,
1072 struct Gadget
*gad
, WORD direction
)
1074 struct Gadget
*g
= NULL
, *gg
, *prev
, *first
;
1076 D(bug("FindCycleGadget: win = %p req %p gad = %p direction = %d\n", win
, req
, gad
, direction
));
1079 first
= req
->ReqGadget
;
1081 first
= win
->FirstGadget
;
1085 case GMR_NEXTACTIVE
:
1086 g
= gad
->NextGadget
;
1093 if (!(gad
->Flags
& GFLG_TABCYCLE
) || (gad
->Flags
& GFLG_DISABLED
))
1095 /* should never happen */
1100 if (!(g
->Flags
& GFLG_DISABLED
) && (g
->Flags
& GFLG_TABCYCLE
)) break;
1107 case GMR_PREVACTIVE
:
1112 /* find a TABCYCLE gadget which is before gad in window's gadgetlist */
1120 if (!(gg
->Flags
& GFLG_DISABLED
) && (gg
->Flags
& GFLG_TABCYCLE
)) prev
= gg
;
1121 gg
= gg
->NextGadget
;
1126 /* There was no TABCYCLE gadget before gad in window's gadgetlist */
1128 gg
= gg
->NextGadget
;
1131 if (!(gad
->Flags
& GFLG_DISABLED
) && (gad
->Flags
& GFLG_TABCYCLE
)) g
= gad
;
1138 if (!(gg
->Flags
& GFLG_DISABLED
) && (gg
->Flags
& GFLG_TABCYCLE
)) prev
= gg
;
1139 gg
= gg
->NextGadget
;
1148 if (!(gad
->Flags
& GFLG_DISABLED
) && (gad
->Flags
& GFLG_TABCYCLE
)) g
= gad
;
1155 default: /* Unused, but well... */
1159 } /* switch(direction) */
1164 /****************************************************************************************/
1166 void FixWindowCoords(struct Window
*win
, LONG
*left
, LONG
*top
, LONG
*width
, LONG
*height
,struct IntuitionBase
*IntuitionBase
)
1168 struct Screen
*scr
= win
->WScreen
;
1170 if (*width
< 1) *width
= 1;
1171 if (*height
< 1) *height
= 1;
1173 if (*width
> scr
->Width
) *width
= scr
->Width
;
1174 if (*height
> scr
->Height
) *height
= scr
->Height
;
1176 if ((GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_OFFSCREENLAYERS
) && (win
->WScreen
->LayerInfo
.Flags
& LIFLG_SUPPORTS_OFFSCREEN_LAYERS
))
1178 if (*left
> scr
->Width
- 1) *left
= scr
->Width
- 1;
1179 if (*top
> scr
->Height
- 1) *top
= scr
->Height
-1;
1184 if ((*left
+ *width
) > scr
->Width
)
1186 *left
= scr
->Width
- *width
;
1193 if ((*top
+ *height
) > scr
->Height
)
1195 *top
= scr
->Height
- *height
;
1204 /****************************************************************************************/
1206 void WindowNeedsRefresh(struct Window
* w
,
1207 struct IntuitionBase
* IntuitionBase
)
1209 /* Supposed to send a message to this window, saying that it needs a
1210 refresh. I will check whether there is no such a message queued in
1211 its messageport, though. It only needs one such message!
1214 /* Refresh the window's gadgetry ...
1215 ... stegerg: and in the actual implementation
1216 call RefreshWindowFrame first, as the border gadgets don't
1217 cover the whole border area.*/
1220 jDc: in actual implementation sizeevent means that we need to send
1221 idcmp, etc and do not clear the flag for smart_refresh window that
1222 has no idcmp_refreshwindow, otherwise we clear the flag!
1225 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: window 0x%lx gzz %d nocarerefresh %d\n",
1226 w
, IS_GZZWINDOW(w
), IS_NOCAREREFRESH(w
)));
1228 //trashregion means that we use delayed refreshing!
1232 (!IW(w
)->trashregion
) ||
1234 (!(w
->Flags
& WFLG_SIMPLE_REFRESH
)) ||
1236 IS_NOCAREREFRESH(w
))
1239 Gad_BeginUpdate(WLAYER(w
), IntuitionBase
);
1241 if (IS_NOCAREREFRESH(w
) || (!((!(w
->Flags
& WFLG_SIMPLE_REFRESH
)) && (!(IW(w
)->specialflags
& SPFLAG_LAYERRESIZED
)))))
1243 if (!IS_GZZWINDOW(w
))
1245 if (w
->Flags
& WFLG_BORDERLESS
)
1247 int_refreshglist(w
->FirstGadget
, w
, NULL
, -1, 0, 0, IntuitionBase
);
1251 int_refreshwindowframe(w
,0,0,IntuitionBase
);
1256 /* refresh all gadgets except border gadgets */
1257 int_refreshglist(w
->FirstGadget
, w
, NULL
, -1, 0, REFRESHGAD_BORDER
, IntuitionBase
);
1259 IW(w
)->specialflags
&= ~SPFLAG_LAYERRESIZED
;
1262 if (IS_NOCAREREFRESH(w
)) WLAYER(w
)->Flags
&= ~LAYERREFRESH
;
1264 Gad_EndUpdate(WLAYER(w
), IS_NOCAREREFRESH(w
) ? TRUE
: FALSE
, IntuitionBase
);
1268 struct Rectangle rect
;
1269 BOOL doclear
= (w
->Flags
& WFLG_BORDERLESS
) ? FALSE
: TRUE
;
1271 rect
.MinX
= w
->BorderLeft
;
1272 rect
.MinY
= w
->BorderTop
;
1273 rect
.MaxX
= w
->Width
- w
->BorderRight
- 1;
1274 rect
.MaxY
= w
->Height
- w
->BorderBottom
- 1;
1277 #ifndef BEGINUPDATEGADGETREFRESH
1278 Gad_BeginUpdate(WLAYER(w
), IntuitionBase
);
1281 LockLayer(0,WLAYER(w
));
1285 #ifndef BEGINUPDATEGADGETREFRESH
1286 if (!IS_GZZWINDOW(w
))
1288 if (w
->Flags
& WFLG_BORDERLESS
)
1290 int_refreshglist(w
->FirstGadget
, w
, NULL
, -1, 0, 0, IntuitionBase
);
1294 int_refreshwindowframe(w
,0,0,IntuitionBase
);
1299 /* refresh all gadgets except border and gadtools gadgets */
1300 int_refreshglist(w
->FirstGadget
, w
, NULL
, -1, 0, REFRESHGAD_BORDER
, IntuitionBase
);
1305 //add rects to trashregion here
1306 OrRegionRegion(WLAYER(w
)->DamageList
,IW(w
)->trashregion
);
1310 ClearRectRegion(IW(w
)->trashregion
,&rect
);
1311 AndRectRegion(WLAYER(w
)->DamageList
,&rect
);
1314 IW(w
)->specialflags
|= SPFLAG_LAYERREFRESH
;
1316 #ifdef BEGINUPDATEGADGETREFRESH
1317 IW(w
)->specialflags
|= SPFLAG_LAYERREFRESH
;
1321 #ifndef BEGINUPDATEGADGETREFRESH
1322 Gad_EndUpdate(WLAYER(w
), FALSE
, IntuitionBase
);
1325 UnlockLayer(WLAYER(w
));
1331 if (IS_DOCAREREFRESH(w
))
1333 if (w
->UserPort
&& (w
->IDCMPFlags
& IDCMP_REFRESHWINDOW
))
1335 struct IntuiMessage
*IM
;
1337 #if defined(__AROSEXEC_SMP__)
1338 struct ExecLockBase
*ExecLockBase
= GetPrivIBase(IntuitionBase
)->ExecLockBase
;
1340 /* Can use Forbid() for this */
1342 #if defined(__AROSEXEC_SMP__)
1343 if (ExecLockBase
) ObtainLock(&w
->UserPort
->mp_SpinLock
, SPINLOCK_MODE_READ
, 0);
1345 IM
= (struct IntuiMessage
*)w
->UserPort
->mp_MsgList
.lh_Head
;
1347 ForeachNode(&w
->UserPort
->mp_MsgList
, IM
)
1349 /* Does the window already have such a message? */
1350 if (IDCMP_REFRESHWINDOW
== IM
->Class
&& IM
->IAddress
== w
)
1352 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: refresh pending\n"));
1353 D(bug("Window %s already has a refresh message pending!!\n",
1354 w
->Title
? w
->Title
: (STRPTR
)"<NONAME>"));
1359 #if defined(__AROSEXEC_SMP__)
1360 if (ExecLockBase
) ReleaseLock(&w
->UserPort
->mp_SpinLock
, 0);
1366 struct InputEvent
*new_ie
;
1367 struct IIHData
*iihdata
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
1369 D(bug("Sending a refresh message to window %s %d %d %d %d!!\n",
1370 w
->Title
? w
->Title
: (STRPTR
)"<NONAME>",
1376 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: sending idcmp message\n"));
1378 if ((new_ie
= AllocInputEvent(iihdata
)))
1380 new_ie
->ie_Class
= IECLASS_EVENT
;
1381 new_ie
->ie_Code
= IECODE_REFRESH
;
1382 new_ie
->ie_EventAddress
= w
;
1383 CurrentTime(&new_ie
->ie_TimeStamp
.tv_secs
, &new_ie
->ie_TimeStamp
.tv_micro
);
1386 fire_intuimessage(w
,
1387 IDCMP_REFRESHWINDOW
,
1393 } /* if (w->UserPort && (w->IDCMPFlags & IDCMP_REFRESHWINDOW)) */
1396 struct IIHData
*iihdata
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
1398 if (FindTask(NULL
) == iihdata
->InputDeviceTask
)
1400 struct InputEvent
*new_ie
;
1402 D(bug("Sending a refresh message to window %s %d %d %d %d!!\n",
1403 w
->Title
? w
->Title
: (STRPTR
)"<NONAME>",
1408 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: sending inputevent\n"));
1410 if ((new_ie
= AllocInputEvent(iihdata
)))
1412 new_ie
->ie_Class
= IECLASS_EVENT
;
1413 new_ie
->ie_Code
= IECODE_REFRESH
;
1414 new_ie
->ie_EventAddress
= w
;
1415 CurrentTime(&new_ie
->ie_TimeStamp
.tv_secs
, &new_ie
->ie_TimeStamp
.tv_micro
);
1418 ih_fire_intuimessage(w
,
1419 IDCMP_REFRESHWINDOW
,
1426 } /* if (!IS_NOCAREREFRESH(w)) */
1430 /****************************************************************************************/
1432 struct Screen
*FindHighestScreen(struct IntuitionBase
*IntuitionBase
)
1434 struct Screen
*scr
, *highest
= IntuitionBase
->FirstScreen
;
1436 for (scr
= highest
; scr
; scr
= scr
->NextScreen
) {
1437 /* We only check screens that are on this monitor */
1438 if (GetPrivScreen(scr
)->IMonitorNode
1439 != GetPrivIBase(IntuitionBase
)->ActiveMonitor
)
1442 /* Check if top of screen is highest so far */
1443 if (scr
->TopEdge
< highest
->TopEdge
)
1449 /****************************************************************************************/
1451 struct Screen
*FindActiveScreen(struct IntuitionBase
*IntuitionBase
)
1454 WORD MinX
, MinY
, MaxX
, MaxY
;
1457 for (scr
= IntuitionBase
->FirstScreen
; scr
; scr
= scr
->NextScreen
) {
1458 /* We check only screens which are on this monitor */
1459 if (GetPrivScreen(scr
)->IMonitorNode
!= GetPrivIBase(IntuitionBase
)->ActiveMonitor
)
1462 compflags
= GetPrivScreen(scr
)->SpecialFlags
>> 8;
1464 /* adjust screen bounds if compositing */
1465 if (compflags
& COMPF_ABOVE
)
1468 MinY
= -(scr
->TopEdge
);
1470 if (compflags
& COMPF_BELOW
)
1473 MaxY
= scr
->MouseY
+ 1;
1475 if (compflags
& COMPF_LEFT
)
1478 MinX
= -(scr
->LeftEdge
);
1480 if (compflags
& COMPF_RIGHT
)
1483 MaxX
= scr
->MouseX
+ 1;
1485 D(bug("[Intuition] Bounds %d,%d->%d,%d\n", MinX
, MinY
, MaxX
, MaxY
));
1486 /* If the mouse is inside screen's bounds, we found it */
1487 if ((scr
->MouseX
>= MinX
) && (scr
->MouseY
>= MinY
) &&
1488 ((scr
->MouseX
< MaxX
) && scr
->MouseY
< MaxY
))
1494 /****************************************************************************************/
1496 struct Window
*FindActiveWindow(struct InputEvent
*ie
, struct Screen
*scr
, ULONG
*stitlebarhit
,
1497 struct IntuitionBase
*IntuitionBase
)
1499 /* The caller has checked that the input event is a IECLASS_RAWMOUSE, SELECTDOWN event */
1500 /* NOTE: may be called with NULL ie ptr! */
1501 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
1503 struct Window
*new_w
;
1506 lock
= LockIBase(0UL);
1508 new_w
= IntuitionBase
->ActiveWindow
;
1512 D(bug("FindActiveWindow: scr %p win %p\n",scr
,new_w
));
1514 if (stitlebarhit
) *stitlebarhit
= FALSE
;
1518 D(bug("FindActiveWindow: Click at (%d,%d)\n",scr
->MouseX
,scr
->MouseY
));
1521 LockLayerInfo(&scr
->LayerInfo
);
1523 l
= WhichLayer(&scr
->LayerInfo
, scr
->MouseX
, scr
->MouseY
);
1525 UnlockLayerInfo(&scr
->LayerInfo
);
1530 D(bug("FindActiveWindow: Click not inside layer\n"));
1532 else if (l
== scr
->BarLayer
)
1534 D(bug("FindActiveWindow: Click on screen bar layer -> active window stays the same\n"));
1535 if (stitlebarhit
) *stitlebarhit
= TRUE
;
1539 new_w
= (struct Window
*)l
->Window
;
1542 D(bug("FindActiveWindow: Selected layer is not a window\n"));
1545 D(bug("FindActiveWindow: Found layer %p\n", l
));
1549 D(bug("FindActiveWindow: New window %p\n", new_w
));
1553 /****************************************************************************************/
1555 struct Window
*FindDesktopWindow(struct Screen
*screen
,struct IntuitionBase
*IntuitionBase
)
1559 for (win
= screen
->FirstWindow
; win
; win
= win
->NextWindow
)
1561 if (win
->Flags
& WFLG_BACKDROP
&&
1562 win
->Width
== screen
->Width
&&
1563 win
->Height
>= screen
->Height
- (screen
->BarHeight
+ 2))
1573 /****************************************************************************************/
1575 struct InputEvent
*AllocInputEvent(struct IIHData
*iihdata
)
1577 struct GeneratedInputEvent
*gie
;
1578 struct InputEvent
*ie
;
1580 /* There might be an inputevent from someone else that our handler discarded.
1581 * We may as well use it. This can only happen inside our main loop.
1583 ie
= iihdata
->FreeInputEvents
;
1586 iihdata
->FreeInputEvents
= ie
->ie_NextEvent
;
1587 DEBUG_INPUTEVENT(dprintf("AllocInputEvent: reuse 0x%lx event\n", ie
));
1591 gie
= AllocPooled(iihdata
->InputEventMemPool
, sizeof(struct GeneratedInputEvent
));
1594 /* Allocated events are put in the list of events that have not yet been
1597 AddTail((struct List
*)&iihdata
->NewAllocatedInputEventList
, (struct Node
*)gie
);
1600 DEBUG_INPUTEVENT(dprintf("AllocInputEvent: allocated 0x%lx (0x%lx)\n", ie
, gie
));
1605 *iihdata
->EndInputEventChain
= ie
;
1606 iihdata
->EndInputEventChain
= &ie
->ie_NextEvent
;
1612 /****************************************************************************************/
1614 void FreeGeneratedInputEvents(struct IIHData
*iihdata
)
1616 struct Node
*node
, *succ
;
1618 /* Free the list of allocated events that have already been propagated. */
1619 ForeachNodeSafe(&iihdata
->AllocatedInputEventList
, node
, succ
)
1621 DEBUG_INPUTEVENT(dprintf("FreeGeneratedInputEvent: free 0x%lx\n", node
));
1622 FreePooled(iihdata
->InputEventMemPool
, node
, sizeof(struct GeneratedInputEvent
));
1625 /* The list is not in a valid state at this point, and NewList() should
1626 * be called, but since we won't use it until the list of not-yet-propagated
1627 * events is copied in it, we won't bother.
1629 //NEWLIST(&iihdata->AllocatedInputEventList);
1632 /****************************************************************************************/
1634 BOOL
FireMenuMessage(WORD code
, struct Window
*win
,
1635 struct InputEvent
*ie
, struct IntuitionBase
*IntuitionBase
)
1637 struct MenuMessage
*msg
;
1638 BOOL result
= FALSE
;
1640 if ((msg
= AllocMenuMessage(IntuitionBase
)))
1644 if (ie
) msg
->ie
= *ie
;
1645 SendMenuMessage(msg
, IntuitionBase
);
1653 /****************************************************************************************/
1655 LONG
Gad_BeginUpdate(struct Layer
*layer
, struct IntuitionBase
*IntuitionBase
)
1657 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
1659 /* Must lock GadgetLock to avoid deadlocks with ObtainGirPort
1660 from other tasks, because ObtainGirPort first obtains
1661 GadgetLock and then layer lock through LockLayer!!!! */
1662 LOCKGADGET(IntuitionBase
)
1663 return BeginUpdate(layer
);
1666 /****************************************************************************************/
1668 void Gad_EndUpdate(struct Layer
*layer
, UWORD flag
, struct IntuitionBase
*IntuitionBase
)
1670 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
1672 EndUpdate(layer
, flag
);
1673 UNLOCKGADGET(IntuitionBase
)
1676 /****************************************************************************************/