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 <proto/exec.h>
12 #include <proto/intuition.h>
13 #include <proto/alib.h>
14 #include <proto/layers.h>
15 #include <proto/graphics.h>
16 #include <proto/utility.h>
17 #include <proto/keymap.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/cghooks.h>
26 #include <intuition/sghooks.h>
27 #include <devices/inputevent.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_actions.h"
40 #include "inputhandler_support.h"
49 #include <aros/debug.h>
51 #define DEBUG_WINDOWNEEDSREFRESH(x) ;
52 #define DEBUG_DOGPINPUT(x) ;
53 #define DEBUG_HANDLECUSTOMRETVAL(x) ;
54 #define DEBUG_ACTIVATEGADGET(x) ;
55 #define DEBUG_FIREINTUIMSG(x) ;
56 #define DEBUG_CLICK(x)
60 /****************************************************************************************/
63 All screens and windows on active monitor will be updated with the current position of
64 the mouse pointer. Windows will receive relative mouse coordinates.
67 /****************************************************************************************/
69 void notify_mousemove_screensandwindows(struct IntuitionBase
* IntuitionBase
)
71 LONG lock
= LockIBase(0);
74 for (scr
= IntuitionBase
->FirstScreen
; scr
; scr
= scr
->NextScreen
)
78 /* Ignore screens which are not on our current monitor */
79 if (GetPrivScreen(scr
)->IMonitorNode
!= GetPrivIBase(IntuitionBase
)->ActiveMonitor
)
82 scr
->MouseX
= IntuitionBase
->MouseX
- scr
->LeftEdge
;
83 scr
->MouseY
= IntuitionBase
->MouseY
- scr
->TopEdge
;
85 /* update windows belonging to this screen */
86 for (win
= scr
->FirstWindow
; win
; win
= win
->NextWindow
)
88 UpdateMouseCoords(win
);
95 /****************************************************************************************/
97 void send_intuimessage(struct IntuiMessage
*imsg
, struct Window
*w
,
98 struct IntuitionBase
*IntuitionBase
)
100 SendIntuiMessage(w
, imsg
);
103 /****************************************************************************************/
105 void free_intuimessage(struct IntuiMessage
*imsg
,
106 struct IntuitionBase
*IntuitionBase
)
108 FreeIntuiMessage(imsg
);
111 /****************************************************************************************/
113 struct IntuiMessage
*alloc_intuimessage(struct Window
*w
,
114 struct IntuitionBase
*IntuitionBase
)
116 struct IntuiMessage
*imsg
;
118 imsg
= AllocIntuiMessage(w
);
123 if (w
->IDCMPFlags
& IDCMP_DELTAMOVE
)
125 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
127 imsg
->MouseX
= iihd
->DeltaMouseX
;
128 imsg
->MouseY
= iihd
->DeltaMouseY
;
132 imsg
->MouseX
= w
->MouseX
;
133 imsg
->MouseY
= w
->MouseY
;
136 CurrentTime(&imsg
->Seconds
, &imsg
->Micros
);
142 /****************************************************************************************/
144 BOOL
fire_intuimessage(struct Window
*w
,
148 struct IntuitionBase
*IntuitionBase
)
150 struct IntuiMessage
*imsg
;
153 if ((w
->IDCMPFlags
& Class
) && (w
->UserPort
))
155 if ((imsg
= alloc_intuimessage(w
, IntuitionBase
)))
157 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
161 imsg
->Qualifier
= iihd
->ActQualifier
;
162 if (Class
== IDCMP_RAWKEY
)
164 INT_INTUIMESSAGE(imsg
)->prevCodeQuals
= IAddress
;
165 imsg
->IAddress
= &INT_INTUIMESSAGE(imsg
)->prevCodeQuals
;
169 imsg
->IAddress
= IAddress
;
172 send_intuimessage(imsg
, w
, IntuitionBase
);
178 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: can't alloc imsg\n"));
183 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: no Userport or masked out idcmpflags\n"));
189 BOOL
fire_message(struct Window
*w
,ULONG Class
, UWORD Code
, APTR IAddress
, struct IntuitionBase
*IntuitionBase
)
191 struct Library
*UtilityBase
= GetPrivIBase(IntuitionBase
)->UtilityBase
;
192 struct ExtIntuiMessage
*imsg
;
195 if ((w
->IDCMPFlags
& Class
) && (w
->UserPort
))
197 if ((imsg
= (struct ExtIntuiMessage
*)alloc_intuimessage(w
, IntuitionBase
)))
199 struct IIHData
*iihdata
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
201 imsg
->eim_IntuiMessage
.Class
= Class
;
202 imsg
->eim_IntuiMessage
.Code
= Code
;
203 imsg
->eim_IntuiMessage
.Qualifier
= iihdata
->ActQualifier
;
204 if (Class
== IDCMP_RAWKEY
)
206 INT_INTUIMESSAGE(imsg
)->prevCodeQuals
= IAddress
;
207 imsg
->eim_IntuiMessage
.IAddress
= &INT_INTUIMESSAGE(imsg
)->prevCodeQuals
;
211 imsg
->eim_IntuiMessage
.IAddress
= IAddress
;
214 if (iihdata
->ActEventTablet
&& (w
->MoreFlags
& WMFLG_TABLETMESSAGES
))
216 if ((imsg
->eim_TabletData
= AllocPooled(GetPrivIBase(IntuitionBase
)->IDCMPPool
,sizeof (struct TabletData
))))
218 memclr(imsg
->eim_TabletData
,sizeof (struct TabletData
));
219 imsg
->eim_TabletData
->td_XFraction
= iihdata
->ActEventTablet
->ient_ScaledXFraction
;
220 imsg
->eim_TabletData
->td_YFraction
= iihdata
->ActEventTablet
->ient_ScaledYFraction
;
221 imsg
->eim_TabletData
->td_TabletX
= iihdata
->ActEventTablet
->ient_TabletX
;
222 imsg
->eim_TabletData
->td_TabletY
= iihdata
->ActEventTablet
->ient_TabletY
;
223 imsg
->eim_TabletData
->td_RangeX
= iihdata
->ActEventTablet
->ient_RangeX
;
224 imsg
->eim_TabletData
->td_RangeY
= iihdata
->ActEventTablet
->ient_RangeY
;
225 imsg
->eim_TabletData
->td_TagList
= CloneTagItems(iihdata
->ActEventTablet
->ient_TagList
);
229 send_intuimessage((struct IntuiMessage
*)imsg
, w
, IntuitionBase
);
235 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: can't alloc imsg\n"));
240 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: no Userport or masked out idcmpflags\n"));
246 /****************************************************************************************/
249 use ih_fire_intuimessage if A) the inputevent because of which
250 you call this function might have to be eaten or modified
251 by Intuition or B) an inputevent might have to be created
252 by Intuition because of a deferred action.
254 In any case this function may be called only from inside Intuition's
258 /****************************************************************************************/
260 BOOL
ih_fire_intuimessage(struct Window
* w
,
264 struct IntuitionBase
*IntuitionBase
)
266 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
267 struct InputEvent
*ie
/* = iihd->ActInputEvent*/;
271 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: win 0x%lx class 0x%lx code 0x%lx IAddress 0x%lx\n",
277 result
= fire_message(w
, Class
, Code
, IAddress
, IntuitionBase
);
279 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: fire_intuimessage result 0x%lx\n",
282 if (result
/*&& ie*/)
284 /* was sent as IDCMP to window so eat inputevent */
286 //ie->ie_Class = IECLASS_NULL;
291 else if (ie
/* && (ie->ie_Class != IECLASS_NULL) && !iihd->ActInputEventUsed*/)
294 /* ih_fire_intuimessage was called from inside Intuition's event handling loop */
296 //iihd->ActInputEventUsed = TRUE;
300 //ie->ie_Qualifier = iihd->ActQualifier;
301 ie
->ie_EventAddress
= IAddress
;
306 /* Note: on the Amiga if a boopsi Gadget which is GA_Immediate
307 and GA_RelVerify immediately in GM_GOACTIVE returns GMR_VERIFY,
308 then this sends IDCMP_GADGETDOWN + IDCMP_GADGETUP. AROS does
309 the same. But for changed inputevents (if window does not have this
310 IDCMP Flags set) there will be only one IECLASS_GADGETDOWN
313 ie
->ie_Class
= IECLASS_GADGETUP
;
316 case IDCMP_GADGETDOWN
:
317 ie
->ie_Class
= IECLASS_GADGETDOWN
;
320 case IDCMP_ACTIVEWINDOW
:
321 ie
->ie_Class
= IECLASS_ACTIVEWINDOW
;
324 case IDCMP_INACTIVEWINDOW
:
325 ie
->ie_Class
= IECLASS_INACTIVEWINDOW
;
328 case IDCMP_CLOSEWINDOW
:
329 ie
->ie_Class
= IECLASS_CLOSEWINDOW
;
333 ie
->ie_Class
= IECLASS_MENUHELP
;
337 ie
->ie_Class
= IECLASS_MENULIST
;
340 case IDCMP_MOUSEBUTTONS
:
341 case IDCMP_MOUSEMOVE
:
343 case IDCMP_VANILLAKEY
:
347 D(bug("ih_fireintuimessage: unexpected IDCMP (%x) for an inputevent-handling-fireintuimessage!\n", Class
));
355 /* ih_fire_intuimessage was called from inside Intuition's defered action handling routines */
357 if ((ie
= AllocInputEvent(iihd
)))
362 ie
->ie_Class
= IECLASS_SIZEWINDOW
;
365 case IDCMP_CHANGEWINDOW
:
366 ie
->ie_Class
= IECLASS_CHANGEWINDOW
;
369 case IDCMP_ACTIVEWINDOW
:
370 ie
->ie_Class
= IECLASS_ACTIVEWINDOW
;
373 case IDCMP_INACTIVEWINDOW
:
374 ie
->ie_Class
= IECLASS_INACTIVEWINDOW
;
377 case IDCMP_CLOSEWINDOW
:
378 ie
->ie_Class
= IECLASS_CLOSEWINDOW
;
382 ie
->ie_Class
= IECLASS_GADGETUP
;
385 case IDCMP_GADGETDOWN
:
386 ie
->ie_Class
= IECLASS_GADGETDOWN
;
389 case IDCMP_REFRESHWINDOW
:
390 ie
->ie_Class
= IECLASS_REFRESHWINDOW
;
394 ie
->ie_Class
= IECLASS_MENUHELP
;
398 ie
->ie_Class
= IECLASS_MENULIST
;
402 D(bug("ih_fireintuimessage: unexpected IDCMP (0x%X) for a deferred-action-fireintuimessage!\n", Class
));
405 } /* switch(Class) */
408 ie
->ie_Qualifier
= iihd
->ActQualifier
;
409 ie
->ie_EventAddress
= IAddress
;
410 CurrentTime(&ie
->ie_TimeStamp
.tv_secs
, &ie
->ie_TimeStamp
.tv_micro
);
412 D(bug("ih_fireintuimessage: generated InputEvent. Class = 0x%X Code = %d EventAddress = 0x%X\n",
415 ie
->ie_EventAddress
));
417 } /* if ((ie = AllocInputEvent(iihd))) */
420 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: result 0x%lx\n",
426 /*********************************************************************/
428 /* This function must never be called with the layer/layerinfo locked,
429 * otherwise a deadlock with ObtainGIRPort can happen.
431 IPTR
Locked_DoMethodA (struct Window
*w
, struct Gadget
*g
, Msg message
, struct IntuitionBase
*IntuitionBase
)
433 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
435 BOOL lock
= w
&& (g
->GadgetType
& GTYP_SYSGADGET
&&
436 ((g
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
||
437 (g
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
));
441 LOCK_REFRESH(w
->WScreen
);
444 LOCKGADGET(IntuitionBase
)
445 rc
= Custom_DoMethodA(IntuitionBase
, g
, message
);
446 UNLOCKGADGET(IntuitionBase
)
450 UNLOCK_REFRESH(w
->WScreen
);
456 /*********************************************************************/
458 IPTR
Custom_DoMethodA (struct IntuitionBase
*IntuitionBase
, struct Gadget
*g
, Msg message
)
460 if (g
->MutualExclude
)
462 return AROS_UFC4(IPTR
, ((struct Hook
*)g
->MutualExclude
)->h_Entry
,
463 AROS_UFCA(struct Hook
*, (struct Hook
*)g
->MutualExclude
, A0
),
464 AROS_UFCA(struct Gadget
*, g
, A2
),
465 AROS_UFCA(APTR
, message
, A1
),
466 AROS_UFCA(struct IntuitionBase
*, IntuitionBase
, A6
));
468 else /* Not needed since gadgetclass sets MutualExclude, but doesn't hurt. */
469 return DoMethodA((Object
*)g
, message
);
472 /****************************************************************************************/
474 void NotifyDepthArrangement(struct Window
*w
, struct IntuitionBase
*IntuitionBase
)
476 if(w
->MoreFlags
& WMFLG_NOTIFYDEPTH
)
478 ih_fire_intuimessage(w
,
487 /****************************************************************************************/
489 void PrepareGadgetInfo(struct GadgetInfo
*gi
, struct Screen
*scr
, struct Window
*win
,
490 struct Requester
*req
)
494 gi
->gi_Requester
= req
;
496 gi
->gi_Pens
.DetailPen
= scr
->DetailPen
;
497 gi
->gi_Pens
.BlockPen
= scr
->BlockPen
;
498 gi
->gi_DrInfo
= (APTR
)&(((struct IntScreen
*)gi
->gi_Screen
)->DInfo
);
501 /****************************************************************************************/
503 void SetGadgetInfoGadget(struct GadgetInfo
*gi
, struct Gadget
*gad
,
504 struct IntuitionBase
*IntuitionBase
)
506 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
507 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
509 SET_GI_RPORT(gi
, gi
->gi_Window
, gi
->gi_Requester
, gad
);
510 InitRastPort(&iihd
->GadgetInfoRastPort
);
512 iihd
->GadgetInfoRastPort
.Layer
= gi
->gi_RastPort
->Layer
;
513 iihd
->GadgetInfoRastPort
.BitMap
= gi
->gi_RastPort
->BitMap
;
515 SetFont(&iihd
->GadgetInfoRastPort
, gi
->gi_DrInfo
->dri_Font
);
517 gi
->gi_Layer
= gi
->gi_RastPort
->Layer
;
518 gi
->gi_RastPort
= &iihd
->GadgetInfoRastPort
;
520 GetGadgetDomain(gad
, gi
->gi_Screen
, gi
->gi_Window
, gi
->gi_Requester
, &gi
->gi_Domain
);
523 /****************************************************************************************/
525 void SetGPIMouseCoords(struct gpInput
*gpi
, struct Gadget
*gad
)
527 struct GadgetInfo
*gi
= gpi
->gpi_GInfo
;
531 if (IS_SCREEN_GADGET(gad
) || !gi
->gi_Window
)
533 mousex
= gi
->gi_Screen
->MouseX
;
534 mousey
= gi
->gi_Screen
->MouseY
;
539 mousex
= gi
->gi_Window
->MouseX
;
540 mousey
= gi
->gi_Window
->MouseY
;
543 gpi
->gpi_Mouse
.X
= mousex
- gi
->gi_Domain
.Left
- GetGadgetLeft(gad
, gi
->gi_Screen
, gi
->gi_Window
, gi
->gi_Requester
);
544 gpi
->gpi_Mouse
.Y
= mousey
- gi
->gi_Domain
.Top
- GetGadgetTop(gad
, gi
->gi_Screen
, gi
->gi_Window
, gi
->gi_Requester
);
548 /****************************************************************************************/
550 void HandleSysGadgetVerify(struct GadgetInfo
*gi
, struct Gadget
*gadget
,
551 struct IntuitionBase
*IntuitionBase
)
553 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
555 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
557 switch(gadget
->GadgetType
& GTYP_SYSTYPEMASK
)
561 if (((struct IntWindow
*)(gi
->gi_Window
))->specialflags
& SPFLAG_IAMDEAD
)
563 CrashedDispose(gi
->gi_Window
,IntuitionBase
);
568 ih_fire_intuimessage(gi
->gi_Window
,
579 if (!IsLayerHiddenBySibling(WLAYER(gi
->gi_Window
), FALSE
)
580 || (iihd
->ActQualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) != 0)
582 /* Send window to back */
583 WindowToBack(gi
->gi_Window
);
587 /* Send window to front */
588 WindowToFront(gi
->gi_Window
);
593 ZipWindow(gi
->gi_Window
);
597 scr
= FindFirstScreen(GetPrivIBase(IntuitionBase
)->ActiveMonitor
, IntuitionBase
);
598 if (gi
->gi_Screen
== scr
599 || (iihd
->ActQualifier
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
)) != 0)
601 ScreenToBack(gi
->gi_Screen
);
605 ScreenToFront(gi
->gi_Screen
);
609 } /* switch(gad->GadgetType & GTYP_SYSTYPEMASK) */
612 /****************************************************************************************/
614 struct Gadget
*HandleCustomGadgetRetVal(IPTR retval
, struct GadgetInfo
*gi
, struct Gadget
*gadget
,
615 ULONG termination
, BOOL
*reuse_event
,
616 struct IntuitionBase
*IntuitionBase
)
618 struct IIHData
*iihdata
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
620 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: retval %ld gi 0x%lx gadget 0x%lx termination %ld reuse %ld\n",
627 if (retval
!= GMR_MEACTIVE
)
629 struct gpGoInactive gpgi
;
631 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: !GMR_MEACTIVE\n"));
633 if (retval
& GMR_REUSE
)
635 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: GMR_REUSE\n"));
639 if (retval
& GMR_VERIFY
)
641 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: GMR_VERIFY\n"));
642 if (IS_SYS_GADGET(gadget
))
644 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: SysGad\n"));
645 HandleSysGadgetVerify(gi
, gadget
, IntuitionBase
);
649 /* Not a system gadget. Send IDCMP_GADGETUP, but not
650 if it is a screen gadget where gi->gi_Window would
653 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: no sysgad\n"));
654 if ((gadget
->Activation
& GACT_RELVERIFY
) &&
657 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: Send IDCMP_GADGETUP\n"));
658 ih_fire_intuimessage(gi
->gi_Window
,
660 termination
& 0x0000FFFF,
665 } /* switch(gad->GadgetType & GTYP_SYSTYPEMASK) */
667 } /* if (retval & GMR_VERIFY) */
669 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: Send GM_GOINACTIVE\n"));
671 gpgi
.MethodID
= GM_GOINACTIVE
;
672 gpgi
.gpgi_GInfo
= gi
;
675 Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpgi
, IntuitionBase
);
677 if (SYSGADGET_ACTIVE
)
679 /* Switch back from Master Drag or Size Gadget to
680 real/original/app Size or Drag Gadget */
682 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: SYSGADGET_ACTIVE\n"));
683 gadget
= iihdata
->ActiveSysGadget
;
684 iihdata
->ActiveSysGadget
= NULL
;
686 if (IS_BOOPSI_GADGET(gadget
))
688 Locked_DoMethodA(gi
->gi_Window
, gadget
, (Msg
)&gpgi
, IntuitionBase
);
692 if ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING2
)
694 ih_fire_intuimessage(gi
->gi_Window
,
705 if (retval
& GMR_VERIFY
&& gi
->gi_Requester
&& gadget
->Activation
& GACT_ENDGADGET
)
707 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: EndRequest\n"));
708 EndRequest(gi
->gi_Requester
, gi
->gi_Window
);
712 gadget
->Activation
&= ~GACT_ACTIVEGADGET
;
714 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle 0x%lx retval 0x%lx\n",
715 (gadget
->Flags
& GFLG_TABCYCLE
),
718 if ((gadget
->Flags
& GFLG_TABCYCLE
) && (retval
& GMR_NEXTACTIVE
))
720 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle+GMR_NEXTACTIVE\n"));
721 gadget
= FindCycleGadget(gi
->gi_Window
, gi
->gi_Requester
, gadget
, GMR_NEXTACTIVE
);
723 else if ((gadget
->Flags
& GFLG_TABCYCLE
) && (retval
& GMR_PREVACTIVE
))
725 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle+GMR_PREVACTIVE\n"));
726 gadget
= FindCycleGadget(gi
->gi_Window
, gi
->gi_Requester
, gadget
, GMR_PREVACTIVE
);
731 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: No gadget\n"));
736 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: activate gadget 0x%lx\n",gadget
));
737 gadget
= DoActivateGadget(gi
->gi_Window
, gi
->gi_Requester
, gadget
, IntuitionBase
);
740 } /* if (retval != GMR_MEACTIVE) */
743 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: set GACT_ACTIVEGADGET\n"));
744 gadget
->Activation
|= GACT_ACTIVEGADGET
;
747 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: return 0x%x\n", gadget
));
751 /****************************************************************************************/
753 /* This function must never be called with the layer/layerinfo locked,
754 * otherwise a deadlock with ObtainGIRPort can happen.
756 struct Gadget
*DoGPInput(struct GadgetInfo
*gi
, struct Gadget
*gadget
,
757 struct InputEvent
*ie
, STACKULONG methodid
,
758 BOOL
*reuse_event
, struct IntuitionBase
*IntuitionBase
)
760 struct IIHData
*iihdata
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
764 ie
->ie_Qualifier
= iihdata
->ActQualifier
;
766 gpi
.MethodID
= methodid
;
769 gpi
.gpi_Termination
= &termination
;
770 gpi
.gpi_TabletData
= NULL
;
772 SetGPIMouseCoords(&gpi
, gadget
);
774 retval
= Locked_DoMethodA (gi
->gi_Window
, gadget
, (Msg
)&gpi
, IntuitionBase
);
776 DEBUG_DOGPINPUT(dprintf("DoGPInput: Locked_DoMethod gadget %p method 0x%lx retval %ld termination 0x%lx\n",
777 gadget
, methodid
, retval
, termination
));
779 return HandleCustomGadgetRetVal(retval
, gi
, gadget
, termination
,
780 reuse_event
, IntuitionBase
);
784 /****************************************************************************************/
786 struct Gadget
* FindGadget (struct Screen
*scr
, struct Window
* window
,
787 struct Requester
* req
, int x
, int y
,
788 struct GadgetInfo
* gi
,BOOL sysonly
,
789 struct IntuitionBase
*IntuitionBase
)
791 struct Gadget
*gadget
, *firstgadget
, *draggadget
= 0;
792 struct gpHitTest gpht
;
795 BOOL sys_only
= sysonly
;
797 DEBUG_CLICK(bug("[Inputhandler] FindGadget(0x%p, 0x%p, 0x%p, %d, %d, %d)\n", scr
, window
, req
, x
, y
, sysonly
));
798 gpht
.MethodID
= GM_HITTEST
;
799 gpht
.gpht_GInfo
= gi
;
801 while (req
|| window
|| scr
)
805 firstgadget
= req
->ReqGadget
;
809 firstgadget
= window
->FirstGadget
;
813 if (draggadget
) return draggadget
;
814 firstgadget
= scr
->FirstGadget
;
817 for (gadget
= firstgadget
; gadget
; gadget
= gadget
->NextGadget
)
819 if (!(gadget
->Flags
& GFLG_DISABLED
) &&
821 (gadget
->GadgetType
& GTYP_SYSGADGET
&&
822 ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SIZING
||
823 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
||
824 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDEPTH
||
825 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_SDEPTH
||
826 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WZOOM
||
827 (gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_CLOSE
))))
829 /* stegerg: domain depends on gadgettype and windowflags! */
830 GetGadgetDomain(gadget
, scr
, window
, req
, &gi
->gi_Domain
);
832 /* Get coords relative to window */
834 GetGadgetIBox(gadget
, gi
, &ibox
);
836 xrel
= x
- gi
->gi_Domain
.Left
;
837 yrel
= y
- gi
->gi_Domain
.Top
;
841 xrel -= req->LeftEdge + window->BorderLeft;
842 yrel -= req->TopEdge + window->BorderTop;
847 xrel
-= window
->LeftEdge
;
848 yrel
-= window
->TopEdge
;
851 if ((xrel
>= ibox
.Left
) &&
852 (yrel
>= ibox
.Top
) &&
853 (xrel
< ibox
.Left
+ ibox
.Width
) &&
854 (yrel
< ibox
.Top
+ ibox
.Height
))
856 if ((gadget
->GadgetType
& GTYP_SYSTYPEMASK
) == GTYP_WDRAGGING
)
858 if (!draggadget
) draggadget
= gadget
;
863 if ((gadget
->GadgetType
& GTYP_GTYPEMASK
) == GTYP_CUSTOMGADGET
)
866 gpht
.gpht_Mouse
.X
= xrel
- ibox
.Left
;
867 gpht
.gpht_Mouse
.Y
= yrel
- ibox
.Top
;
869 /* jDc: don't check for == GMR_GADGETHIT since some reaction classes*/
870 /* (BURN IN HELL!) return TRUE here (related to imageclass HITEST?)*/
871 if (Locked_DoMethodA (window
, gadget
, (Msg
)&gpht
, IntuitionBase
))
881 } /* if (!(gadget->Flags & GFLG_DISABLED)) */
883 } /* for (gadget = window->FirstGadget; gadget; gadget = gadget->NextGadget) */
895 draggadget
= findbordergadget(window
,draggadget
,IntuitionBase
);
908 /****************************************************************************************/
910 struct Gadget
* FindHelpGadget (struct Window
* window
,
911 int x
, int y
, struct IntuitionBase
*IntuitionBase
)
913 struct Gadget
*gadget
, *firstgadget
;
914 struct Requester
*req
= window
->FirstRequest
;
916 while (req
|| window
)
920 firstgadget
= req
->ReqGadget
;
924 firstgadget
= window
->FirstGadget
;
927 for (gadget
= firstgadget
; gadget
; gadget
= gadget
->NextGadget
)
929 if ((gadget
->Flags
& GFLG_EXTENDED
) &&
930 (((struct ExtGadget
*)gadget
)->MoreFlags
& GMORE_GADGETHELP
))
932 if (InsideGadget(window
->WScreen
, window
, req
, gadget
, x
, y
))
941 req
= req
->OlderRequest
;
948 } /* FindHelpGadget */
951 /****************************************************************************************/
953 BOOL
InsideGadget(struct Screen
*scr
, struct Window
*win
, struct Requester
*req
,
954 struct Gadget
*gad
, WORD x
, WORD y
)
959 GetScrGadgetIBox(gad
, scr
, win
, req
, &box
);
961 if ((x
>= box
.Left
) &&
963 (x
< box
.Left
+ box
.Width
) &&
964 (y
< box
.Top
+ box
.Height
))
972 /****************************************************************************************/
974 struct Gadget
*DoActivateGadget(struct Window
*win
, struct Requester
*req
, struct Gadget
*gad
,
975 struct IntuitionBase
*IntuitionBase
)
977 struct IIHData
*iihd
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
978 struct GadgetInfo
*gi
= &iihd
->GadgetInfo
;
979 struct Gadget
*result
= NULL
;
981 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Window 0x%lx Req 0x%lx Gadget 0x%lx\n",
986 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Activation 0x%lx\n",
989 if (gad
->Activation
& GACT_IMMEDIATE
)
991 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Send GADGETDOWN msg\n"));
992 ih_fire_intuimessage(win
,
999 PrepareGadgetInfo(gi
, win
->WScreen
, win
, req
);
1000 SetGadgetInfoGadget(gi
, gad
, IntuitionBase
);
1002 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Type 0x%lx\n",
1003 gad
->GadgetType
& GTYP_GTYPEMASK
));
1005 switch(gad
->GadgetType
& GTYP_GTYPEMASK
)
1007 case GTYP_STRGADGET
:
1009 struct StringInfo
*si
= (struct StringInfo
*)gad
->SpecialInfo
;
1011 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: GTYP_STRGADGET\n"));
1013 gad
->Flags
|= GFLG_SELECTED
;
1014 if (si
&& si
->UndoBuffer
)
1016 strcpy(si
->UndoBuffer
, si
->Buffer
);
1019 gad
->Activation
|= GACT_ACTIVEGADGET
;
1020 UpdateStrGadget(gad
, win
, req
, IntuitionBase
);
1025 case GTYP_CUSTOMGADGET
:
1032 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: GTYP_CUSTOMGADGET\n"));
1034 gpi
.MethodID
= GM_GOACTIVE
;
1036 gpi
.gpi_IEvent
= NULL
;
1037 gpi
.gpi_Termination
= &termination
;
1038 gpi
.gpi_Mouse
.X
= win
->MouseX
- gi
->gi_Domain
.Left
- GetGadgetLeft(gad
, gi
->gi_Screen
, gi
->gi_Window
, NULL
);
1039 gpi
.gpi_Mouse
.Y
= win
->MouseY
- gi
->gi_Domain
.Top
- GetGadgetTop(gad
, gi
->gi_Screen
, gi
->gi_Window
, NULL
);
1040 gpi
.gpi_TabletData
= NULL
;
1042 retval
= Locked_DoMethodA (win
, gad
, (Msg
)&gpi
, IntuitionBase
);
1044 gad
= HandleCustomGadgetRetVal(retval
, gi
, gad
,termination
,
1045 &reuse_event
, IntuitionBase
);
1049 gad
->Activation
|= GACT_ACTIVEGADGET
;
1055 } /* switch(gad->GadgetType & GTYP_GTYPEMASK) */
1057 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: result 0x%lx\n",
1060 if (result
) iihd
->ActiveGadget
= result
;
1066 /****************************************************************************************/
1068 struct Gadget
*FindCycleGadget(struct Window
*win
, struct Requester
*req
,
1069 struct Gadget
*gad
, WORD direction
)
1071 struct Gadget
*g
= NULL
, *gg
, *prev
, *first
;
1073 D(bug("FindCycleGadget: win = %p req %p gad = %p direction = %d\n", win
, req
, gad
, direction
));
1076 first
= req
->ReqGadget
;
1078 first
= win
->FirstGadget
;
1082 case GMR_NEXTACTIVE
:
1083 g
= gad
->NextGadget
;
1090 if (!(gad
->Flags
& GFLG_TABCYCLE
) || (gad
->Flags
& GFLG_DISABLED
))
1092 /* should never happen */
1097 if (!(g
->Flags
& GFLG_DISABLED
) && (g
->Flags
& GFLG_TABCYCLE
)) break;
1104 case GMR_PREVACTIVE
:
1109 /* find a TABCYCLE gadget which is before gad in window's gadgetlist */
1117 if (!(gg
->Flags
& GFLG_DISABLED
) && (gg
->Flags
& GFLG_TABCYCLE
)) prev
= gg
;
1118 gg
= gg
->NextGadget
;
1123 /* There was no TABCYCLE gadget before gad in window's gadgetlist */
1125 gg
= gg
->NextGadget
;
1128 if (!(gad
->Flags
& GFLG_DISABLED
) && (gad
->Flags
& GFLG_TABCYCLE
)) g
= gad
;
1135 if (!(gg
->Flags
& GFLG_DISABLED
) && (gg
->Flags
& GFLG_TABCYCLE
)) prev
= gg
;
1136 gg
= gg
->NextGadget
;
1145 if (!(gad
->Flags
& GFLG_DISABLED
) && (gad
->Flags
& GFLG_TABCYCLE
)) g
= gad
;
1152 default: /* Unused, but well... */
1156 } /* switch(direction) */
1161 /****************************************************************************************/
1163 void FixWindowCoords(struct Window
*win
, LONG
*left
, LONG
*top
, LONG
*width
, LONG
*height
,struct IntuitionBase
*IntuitionBase
)
1165 struct Screen
*scr
= win
->WScreen
;
1167 if (*width
< 1) *width
= 1;
1168 if (*height
< 1) *height
= 1;
1170 if (*width
> scr
->Width
) *width
= scr
->Width
;
1171 if (*height
> scr
->Height
) *height
= scr
->Height
;
1173 if ((GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_OFFSCREENLAYERS
) && (win
->WScreen
->LayerInfo
.Flags
& LIFLG_SUPPORTS_OFFSCREEN_LAYERS
))
1175 if (*left
> scr
->Width
- 1) *left
= scr
->Width
- 1;
1176 if (*top
> scr
->Height
- 1) *top
= scr
->Height
-1;
1181 if ((*left
+ *width
) > scr
->Width
)
1183 *left
= scr
->Width
- *width
;
1190 if ((*top
+ *height
) > scr
->Height
)
1192 *top
= scr
->Height
- *height
;
1201 /****************************************************************************************/
1203 void WindowNeedsRefresh(struct Window
* w
,
1204 struct IntuitionBase
* IntuitionBase
)
1206 /* Supposed to send a message to this window, saying that it needs a
1207 refresh. I will check whether there is no such a message queued in
1208 its messageport, though. It only needs one such message!
1211 /* Refresh the window's gadgetry ...
1212 ... stegerg: and in the actual implementation
1213 call RefreshWindowFrame first, as the border gadgets don't
1214 cover the whole border area.*/
1217 jDc: in actual implementation sizeevent means that we need to send
1218 idcmp, etc and do not clear the flag for smart_refresh window that
1219 has no idcmp_refreshwindow, otherwise we clear the flag!
1222 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: window 0x%lx gzz %d nocarerefresh %d\n",
1223 w
, IS_GZZWINDOW(w
), IS_NOCAREREFRESH(w
)));
1225 //trashregion means that we use delayed refreshing!
1229 (!IW(w
)->trashregion
) ||
1231 (!(w
->Flags
& WFLG_SIMPLE_REFRESH
)) ||
1233 IS_NOCAREREFRESH(w
))
1236 Gad_BeginUpdate(WLAYER(w
), IntuitionBase
);
1238 if (IS_NOCAREREFRESH(w
) || (!((!(w
->Flags
& WFLG_SIMPLE_REFRESH
)) && (!(IW(w
)->specialflags
& SPFLAG_LAYERRESIZED
)))))
1240 if (!IS_GZZWINDOW(w
))
1242 if (w
->Flags
& WFLG_BORDERLESS
)
1244 int_refreshglist(w
->FirstGadget
, w
, NULL
, -1, 0, 0, IntuitionBase
);
1248 int_refreshwindowframe(w
,0,0,IntuitionBase
);
1253 /* refresh all gadgets except border gadgets */
1254 int_refreshglist(w
->FirstGadget
, w
, NULL
, -1, 0, REFRESHGAD_BORDER
, IntuitionBase
);
1256 IW(w
)->specialflags
&= ~SPFLAG_LAYERRESIZED
;
1259 if (IS_NOCAREREFRESH(w
)) WLAYER(w
)->Flags
&= ~LAYERREFRESH
;
1261 Gad_EndUpdate(WLAYER(w
), IS_NOCAREREFRESH(w
) ? TRUE
: FALSE
, IntuitionBase
);
1265 struct Rectangle rect
;
1266 BOOL doclear
= (w
->Flags
& WFLG_BORDERLESS
) ? FALSE
: TRUE
;
1268 rect
.MinX
= w
->BorderLeft
;
1269 rect
.MinY
= w
->BorderTop
;
1270 rect
.MaxX
= w
->Width
- w
->BorderRight
- 1;
1271 rect
.MaxY
= w
->Height
- w
->BorderBottom
- 1;
1274 #ifndef BEGINUPDATEGADGETREFRESH
1275 Gad_BeginUpdate(WLAYER(w
), IntuitionBase
);
1278 LockLayer(0,WLAYER(w
));
1282 #ifndef BEGINUPDATEGADGETREFRESH
1283 if (!IS_GZZWINDOW(w
))
1285 if (w
->Flags
& WFLG_BORDERLESS
)
1287 int_refreshglist(w
->FirstGadget
, w
, NULL
, -1, 0, 0, IntuitionBase
);
1291 int_refreshwindowframe(w
,0,0,IntuitionBase
);
1296 /* refresh all gadgets except border and gadtools gadgets */
1297 int_refreshglist(w
->FirstGadget
, w
, NULL
, -1, 0, REFRESHGAD_BORDER
, IntuitionBase
);
1302 //add rects to trashregion here
1303 OrRegionRegion(WLAYER(w
)->DamageList
,IW(w
)->trashregion
);
1307 ClearRectRegion(IW(w
)->trashregion
,&rect
);
1308 AndRectRegion(WLAYER(w
)->DamageList
,&rect
);
1311 IW(w
)->specialflags
|= SPFLAG_LAYERREFRESH
;
1313 #ifdef BEGINUPDATEGADGETREFRESH
1314 IW(w
)->specialflags
|= SPFLAG_LAYERREFRESH
;
1318 #ifndef BEGINUPDATEGADGETREFRESH
1319 Gad_EndUpdate(WLAYER(w
), FALSE
, IntuitionBase
);
1322 UnlockLayer(WLAYER(w
));
1328 if (IS_DOCAREREFRESH(w
))
1330 if (w
->UserPort
&& (w
->IDCMPFlags
& IDCMP_REFRESHWINDOW
))
1332 struct IntuiMessage
*IM
;
1335 /* Can use Forbid() for this */
1338 IM
= (struct IntuiMessage
*)w
->UserPort
->mp_MsgList
.lh_Head
;
1340 ForeachNode(&w
->UserPort
->mp_MsgList
, IM
)
1342 /* Does the window already have such a message? */
1343 if (IDCMP_REFRESHWINDOW
== IM
->Class
&& IM
->IAddress
== w
)
1345 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: refresh pending\n"));
1346 D(bug("Window %s already has a refresh message pending!!\n",
1347 w
->Title
? w
->Title
: (STRPTR
)"<NONAME>"));
1357 struct InputEvent
*new_ie
;
1358 struct IIHData
*iihdata
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
1360 D(bug("Sending a refresh message to window %s %d %d %d %d!!\n",
1361 w
->Title
? w
->Title
: (STRPTR
)"<NONAME>",
1367 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: sending idcmp message\n"));
1369 if ((new_ie
= AllocInputEvent(iihdata
)))
1371 new_ie
->ie_Class
= IECLASS_EVENT
;
1372 new_ie
->ie_Code
= IECODE_REFRESH
;
1373 new_ie
->ie_EventAddress
= w
;
1374 CurrentTime(&new_ie
->ie_TimeStamp
.tv_secs
, &new_ie
->ie_TimeStamp
.tv_micro
);
1377 fire_intuimessage(w
,
1378 IDCMP_REFRESHWINDOW
,
1384 } /* if (w->UserPort && (w->IDCMPFlags & IDCMP_REFRESHWINDOW)) */
1387 struct IIHData
*iihdata
= (struct IIHData
*)GetPrivIBase(IntuitionBase
)->InputHandler
->is_Data
;
1389 if (FindTask(NULL
) == iihdata
->InputDeviceTask
)
1391 struct InputEvent
*new_ie
;
1393 D(bug("Sending a refresh message to window %s %d %d %d %d!!\n",
1394 w
->Title
? w
->Title
: (STRPTR
)"<NONAME>",
1399 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: sending inputevent\n"));
1401 if ((new_ie
= AllocInputEvent(iihdata
)))
1403 new_ie
->ie_Class
= IECLASS_EVENT
;
1404 new_ie
->ie_Code
= IECODE_REFRESH
;
1405 new_ie
->ie_EventAddress
= w
;
1406 CurrentTime(&new_ie
->ie_TimeStamp
.tv_secs
, &new_ie
->ie_TimeStamp
.tv_micro
);
1409 ih_fire_intuimessage(w
,
1410 IDCMP_REFRESHWINDOW
,
1417 } /* if (!IS_NOCAREREFRESH(w)) */
1421 /****************************************************************************************/
1423 struct Screen
*FindHighestScreen(struct IntuitionBase
*IntuitionBase
)
1425 struct Screen
*scr
, *highest
= IntuitionBase
->FirstScreen
;
1427 for (scr
= highest
; scr
; scr
= scr
->NextScreen
) {
1428 /* We only check screens that are on this monitor */
1429 if (GetPrivScreen(scr
)->IMonitorNode
1430 != GetPrivIBase(IntuitionBase
)->ActiveMonitor
)
1433 /* Check if top of screen is highest so far */
1434 if (scr
->TopEdge
< highest
->TopEdge
)
1440 /****************************************************************************************/
1442 struct Screen
*FindActiveScreen(struct IntuitionBase
*IntuitionBase
)
1445 WORD MinX
, MinY
, MaxX
, MaxY
;
1448 for (scr
= IntuitionBase
->FirstScreen
; scr
; scr
= scr
->NextScreen
) {
1449 /* We check only screens which are on this monitor */
1450 if (GetPrivScreen(scr
)->IMonitorNode
!= GetPrivIBase(IntuitionBase
)->ActiveMonitor
)
1453 compflags
= GetPrivScreen(scr
)->SpecialFlags
>> 8;
1455 /* adjust screen bounds if compositing */
1456 if (compflags
& COMPF_ABOVE
)
1459 MinY
= -(scr
->TopEdge
);
1461 if (compflags
& COMPF_BELOW
)
1464 MaxY
= scr
->MouseY
+ 1;
1466 if (compflags
& COMPF_LEFT
)
1469 MinX
= -(scr
->LeftEdge
);
1471 if (compflags
& COMPF_RIGHT
)
1474 MaxX
= scr
->MouseX
+ 1;
1476 D(bug("[Intuition] Bounds %d,%d->%d,%d\n", MinX
, MinY
, MaxX
, MaxY
));
1477 /* If the mouse is inside screen's bounds, we found it */
1478 if ((scr
->MouseX
>= MinX
) && (scr
->MouseY
>= MinY
) &&
1479 ((scr
->MouseX
< MaxX
) && scr
->MouseY
< MaxY
))
1485 /****************************************************************************************/
1487 struct Window
*FindActiveWindow(struct InputEvent
*ie
, struct Screen
*scr
, ULONG
*stitlebarhit
,
1488 struct IntuitionBase
*IntuitionBase
)
1490 /* The caller has checked that the input event is a IECLASS_RAWMOUSE, SELECTDOWN event */
1491 /* NOTE: may be called with NULL ie ptr! */
1492 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
1494 struct Window
*new_w
;
1497 lock
= LockIBase(0UL);
1499 new_w
= IntuitionBase
->ActiveWindow
;
1503 D(bug("FindActiveWindow: scr %p win %p\n",scr
,new_w
));
1505 if (stitlebarhit
) *stitlebarhit
= FALSE
;
1509 D(bug("FindActiveWindow: Click at (%d,%d)\n",scr
->MouseX
,scr
->MouseY
));
1512 LockLayerInfo(&scr
->LayerInfo
);
1514 l
= WhichLayer(&scr
->LayerInfo
, scr
->MouseX
, scr
->MouseY
);
1516 UnlockLayerInfo(&scr
->LayerInfo
);
1521 D(bug("FindActiveWindow: Click not inside layer\n"));
1523 else if (l
== scr
->BarLayer
)
1525 D(bug("FindActiveWindow: Click on screen bar layer -> active window stays the same\n"));
1526 if (stitlebarhit
) *stitlebarhit
= TRUE
;
1530 new_w
= (struct Window
*)l
->Window
;
1533 D(bug("FindActiveWindow: Selected layer is not a window\n"));
1536 D(bug("FindActiveWindow: Found layer %p\n", l
));
1540 D(bug("FindActiveWindow: New window %p\n", new_w
));
1544 /****************************************************************************************/
1546 struct Window
*FindDesktopWindow(struct Screen
*screen
,struct IntuitionBase
*IntuitionBase
)
1550 for (win
= screen
->FirstWindow
; win
; win
= win
->NextWindow
)
1552 if (win
->Flags
& WFLG_BACKDROP
&&
1553 win
->Width
== screen
->Width
&&
1554 win
->Height
>= screen
->Height
- (screen
->BarHeight
+ 2))
1564 /****************************************************************************************/
1566 struct InputEvent
*AllocInputEvent(struct IIHData
*iihdata
)
1568 struct GeneratedInputEvent
*gie
;
1569 struct InputEvent
*ie
;
1571 /* There might be an inputevent from someone else that our handler discarded.
1572 * We may as well use it. This can only happen inside our main loop.
1574 ie
= iihdata
->FreeInputEvents
;
1577 iihdata
->FreeInputEvents
= ie
->ie_NextEvent
;
1578 DEBUG_INPUTEVENT(dprintf("AllocInputEvent: reuse 0x%lx event\n", ie
));
1582 gie
= AllocPooled(iihdata
->InputEventMemPool
, sizeof(struct GeneratedInputEvent
));
1585 /* Allocated events are put in the list of events that have not yet been
1588 AddTail((struct List
*)&iihdata
->NewAllocatedInputEventList
, (struct Node
*)gie
);
1591 DEBUG_INPUTEVENT(dprintf("AllocInputEvent: allocated 0x%lx (0x%lx)\n", ie
, gie
));
1596 *iihdata
->EndInputEventChain
= ie
;
1597 iihdata
->EndInputEventChain
= &ie
->ie_NextEvent
;
1603 /****************************************************************************************/
1605 void FreeGeneratedInputEvents(struct IIHData
*iihdata
)
1607 struct Node
*node
, *succ
;
1609 /* Free the list of allocated events that have already been propagated. */
1610 ForeachNodeSafe(&iihdata
->AllocatedInputEventList
, node
, succ
)
1612 DEBUG_INPUTEVENT(dprintf("FreeGeneratedInputEvent: free 0x%lx\n", node
));
1613 FreePooled(iihdata
->InputEventMemPool
, node
, sizeof(struct GeneratedInputEvent
));
1616 /* The list is not in a valid state at this point, and NewList() should
1617 * be called, but since we won't use it until the list of not-yet-propagated
1618 * events is copied in it, we won't bother.
1620 //NEWLIST(&iihdata->AllocatedInputEventList);
1623 /****************************************************************************************/
1625 BOOL
FireMenuMessage(WORD code
, struct Window
*win
,
1626 struct InputEvent
*ie
, struct IntuitionBase
*IntuitionBase
)
1628 struct MenuMessage
*msg
;
1629 BOOL result
= FALSE
;
1631 if ((msg
= AllocMenuMessage(IntuitionBase
)))
1635 if (ie
) msg
->ie
= *ie
;
1636 SendMenuMessage(msg
, IntuitionBase
);
1644 /****************************************************************************************/
1646 LONG
Gad_BeginUpdate(struct Layer
*layer
, struct IntuitionBase
*IntuitionBase
)
1648 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
1650 /* Must lock GadgetLock to avoid deadlocks with ObtainGirPort
1651 from other tasks, because ObtainGirPort first obtains
1652 GadgetLock and then layer lock through LockLayer!!!! */
1653 LOCKGADGET(IntuitionBase
)
1654 return BeginUpdate(layer
);
1657 /****************************************************************************************/
1659 void Gad_EndUpdate(struct Layer
*layer
, UWORD flag
, struct IntuitionBase
*IntuitionBase
)
1661 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
1663 EndUpdate(layer
, flag
);
1664 UNLOCKGADGET(IntuitionBase
)
1667 /****************************************************************************************/