New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / rom / intuition / inputhandler_support.c
blob99ffb73283343c5b8f4389563d059e94af30a562
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
6 Support functions for InputHandler.
7 */
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>
28 #include <string.h>
30 #include "inputhandler.h"
32 #include "boopsigadgets.h"
33 #include "boolgadgets.h"
34 #include "propgadgets.h"
35 #include "strgadgets.h"
36 #include "gadgets.h"
37 #include "intuition_intern.h" /* EWFLG_xxx */
38 #include "inputhandler_actions.h"
39 #include "inputhandler_support.h"
40 #include "menus.h"
42 #ifdef SKINS
43 # include "mosmisc.h"
44 #endif
46 #undef DEBUG
47 #define DEBUG 0
48 #include <aros/debug.h>
50 #define DEBUG_WINDOWNEEDSREFRESH(x) ;
51 #define DEBUG_DOGPINPUT(x) ;
52 #define DEBUG_HANDLECUSTOMRETVAL(x) ;
53 #define DEBUG_ACTIVATEGADGET(x) ;
54 #define DEBUG_FIREINTUIMSG(x) ;
56 #include <stddef.h>
58 /****************************************************************************************/
61 All screens and windows will be updated with the current position of
62 the mouse pointer. The windows will receive relative mouse coordinates.
65 /****************************************************************************************/
67 void notify_mousemove_screensandwindows(WORD x,
68 WORD y,
69 struct IntuitionBase * IntuitionBase)
71 LONG lock = LockIBase(0);
72 struct Screen *scr = IntuitionBase->FirstScreen;
74 while (NULL != scr)
76 struct Window * win = scr->FirstWindow;
78 scr->MouseX = x;// - scr->LeftEdge;
79 scr->MouseY = y;// - scr->TopEdge;
82 ** Visit all windows of this screen
85 while (NULL != win)
87 UpdateMouseCoords(win);
89 win = win -> NextWindow;
92 scr = scr->NextScreen;
95 UnlockIBase(lock);
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);
122 if (imsg)
124 if (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;
133 else
135 imsg->MouseX = w->MouseX;
136 imsg->MouseY = w->MouseY;
139 CurrentTime(&imsg->Seconds, &imsg->Micros);
142 return imsg;
145 /****************************************************************************************/
147 BOOL fire_intuimessage(struct Window *w,
148 ULONG Class,
149 UWORD Code,
150 APTR IAddress,
151 struct IntuitionBase *IntuitionBase)
153 struct IntuiMessage *imsg;
154 BOOL result = FALSE;
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;
162 imsg->Class = Class;
163 imsg->Code = Code;
164 imsg->Qualifier = iihd->ActQualifier;
165 if (Class == IDCMP_RAWKEY)
167 INT_INTUIMESSAGE(imsg)->prevCodeQuals = IAddress;
168 imsg->IAddress = &INT_INTUIMESSAGE(imsg)->prevCodeQuals;
170 else
172 imsg->IAddress = IAddress;
175 send_intuimessage(imsg, w, IntuitionBase);
177 result = TRUE;
179 else
181 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: can't alloc imsg\n"));
184 else
186 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: no Userport or masked out idcmpflags\n"));
189 return result;
192 BOOL fire_message(struct Window *w,ULONG Class, UWORD Code, APTR IAddress, struct IntuitionBase *IntuitionBase)
194 struct ExtIntuiMessage *imsg;
195 BOOL result = FALSE;
197 if ((w->IDCMPFlags & Class) && (w->UserPort))
199 if ((imsg = (struct ExtIntuiMessage *)alloc_intuimessage(w, IntuitionBase)))
201 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
203 imsg->eim_IntuiMessage.Class = Class;
204 imsg->eim_IntuiMessage.Code = Code;
205 imsg->eim_IntuiMessage.Qualifier = iihdata->ActQualifier;
206 if (Class == IDCMP_RAWKEY)
208 INT_INTUIMESSAGE(imsg)->prevCodeQuals = IAddress;
209 imsg->eim_IntuiMessage.IAddress = &INT_INTUIMESSAGE(imsg)->prevCodeQuals;
211 else
213 imsg->eim_IntuiMessage.IAddress = IAddress;
216 if (iihdata->ActEventTablet && (w->MoreFlags & WMFLG_TABLETMESSAGES))
218 if ((imsg->eim_TabletData = AllocPooled(GetPrivIBase(IntuitionBase)->IDCMPPool,sizeof (struct TabletData))))
220 memclr(imsg->eim_TabletData,sizeof (struct TabletData));
221 imsg->eim_TabletData->td_XFraction = iihdata->ActEventTablet->ient_ScaledXFraction;
222 imsg->eim_TabletData->td_YFraction = iihdata->ActEventTablet->ient_ScaledYFraction;
223 imsg->eim_TabletData->td_TabletX = iihdata->ActEventTablet->ient_TabletX;
224 imsg->eim_TabletData->td_TabletY = iihdata->ActEventTablet->ient_TabletY;
225 imsg->eim_TabletData->td_RangeX = iihdata->ActEventTablet->ient_RangeX;
226 imsg->eim_TabletData->td_RangeY = iihdata->ActEventTablet->ient_RangeY;
227 imsg->eim_TabletData->td_TagList = CloneTagItems(iihdata->ActEventTablet->ient_TagList);
231 send_intuimessage(imsg, w, IntuitionBase);
233 result = TRUE;
235 else
237 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: can't alloc imsg\n"));
240 else
242 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: no Userport or masked out idcmpflags\n"));
245 return result;
248 /****************************************************************************************/
251 use ih_fire_intuimessage if A) the inputevent because of which
252 you call this function might have to be eaten or modified
253 by Intuition or B) an inputevent might have to be created
254 by Intuition because of a deferred action.
256 In any case this function may be called only from inside Intuition's
257 InputHandler!!!!!!
260 /****************************************************************************************/
262 BOOL ih_fire_intuimessage(struct Window * w,
263 ULONG Class,
264 UWORD Code,
265 APTR IAddress,
266 struct IntuitionBase *IntuitionBase)
268 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
269 struct InputEvent *ie/* = iihd->ActInputEvent*/;
271 BOOL result;
273 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: win 0x%lx class 0x%lx code 0x%lx IAddress 0x%lx\n",
275 Class,
276 Code,
277 IAddress));
279 result = fire_message(w, Class, Code, IAddress, IntuitionBase);
281 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: fire_intuimessage result 0x%lx\n",
282 result));
284 if (result /*&& ie*/)
286 /* was sent as IDCMP to window so eat inputevent */
288 //ie->ie_Class = IECLASS_NULL;
292 #if 0
293 else if (ie/* && (ie->ie_Class != IECLASS_NULL) && !iihd->ActInputEventUsed*/)
296 /* ih_fire_intuimessage was called from inside Intuition's event handling loop */
298 //iihd->ActInputEventUsed = TRUE;
300 ie->ie_SubClass = 0;
301 ie->ie_Code = Code;
302 //ie->ie_Qualifier = iihd->ActQualifier;
303 ie->ie_EventAddress = IAddress;
305 switch(Class)
307 case IDCMP_GADGETUP:
308 /* Note: on the Amiga if a boopsi Gadget which is GA_Immediate
309 and GA_RelVerify immediately in GM_GOACTIVE returns GMR_VERIFY,
310 then this sends IDCMP_GADGETDOWN + IDCMP_GADGETUP. AROS does
311 the same. But for changed inputevents (if window does not have this
312 IDCMP Flags set) there will be only one IECLASS_GADGETDOWN
315 ie->ie_Class = IECLASS_GADGETUP;
316 break;
318 case IDCMP_GADGETDOWN:
319 ie->ie_Class = IECLASS_GADGETDOWN;
320 break;
322 case IDCMP_ACTIVEWINDOW:
323 ie->ie_Class = IECLASS_ACTIVEWINDOW;
324 break;
326 case IDCMP_INACTIVEWINDOW:
327 ie->ie_Class = IECLASS_INACTIVEWINDOW;
328 break;
330 case IDCMP_CLOSEWINDOW:
331 ie->ie_Class = IECLASS_CLOSEWINDOW;
332 break;
334 case IDCMP_MENUHELP:
335 ie->ie_Class = IECLASS_MENUHELP;
336 break;
338 case IDCMP_MENUPICK:
339 ie->ie_Class = IECLASS_MENULIST;
340 break;
342 case IDCMP_MOUSEBUTTONS:
343 case IDCMP_MOUSEMOVE:
344 case IDCMP_RAWKEY:
345 case IDCMP_VANILLAKEY:
346 break;
348 default:
349 D(bug("ih_fireintuimessage: unexpected IDCMP (%x) for an inputevent-handling-fireintuimessage!\n", Class));
350 break;
354 #endif
355 else //if (!ie)
357 /* ih_fire_intuimessage was called from inside Intuition's defered action handling routines */
359 if ((ie = AllocInputEvent(iihd)))
361 switch(Class)
363 case IDCMP_NEWSIZE:
364 ie->ie_Class = IECLASS_SIZEWINDOW;
365 break;
367 case IDCMP_CHANGEWINDOW:
368 ie->ie_Class = IECLASS_CHANGEWINDOW;
369 break;
371 case IDCMP_ACTIVEWINDOW:
372 ie->ie_Class = IECLASS_ACTIVEWINDOW;
373 break;
375 case IDCMP_INACTIVEWINDOW:
376 ie->ie_Class = IECLASS_INACTIVEWINDOW;
377 break;
379 case IDCMP_CLOSEWINDOW:
380 ie->ie_Class = IECLASS_CLOSEWINDOW;
381 break;
383 case IDCMP_GADGETUP:
384 ie->ie_Class = IECLASS_GADGETUP;
385 break;
387 case IDCMP_GADGETDOWN:
388 ie->ie_Class = IECLASS_GADGETDOWN;
389 break;
391 case IDCMP_REFRESHWINDOW:
392 ie->ie_Class = IECLASS_REFRESHWINDOW;
393 break;
395 case IDCMP_MENUHELP:
396 ie->ie_Class = IECLASS_MENUHELP;
397 break;
399 case IDCMP_MENUPICK:
400 ie->ie_Class = IECLASS_MENULIST;
401 break;
403 default:
404 D(bug("ih_fireintuimessage: unexpected IDCMP (0x%X) for a deferred-action-fireintuimessage!\n", Class));
405 break;
407 } /* switch(Class) */
409 ie->ie_Code = Code;
410 ie->ie_Qualifier = iihd->ActQualifier;
411 ie->ie_EventAddress = IAddress;
412 CurrentTime(&ie->ie_TimeStamp.tv_secs, &ie->ie_TimeStamp.tv_micro);
414 D(bug("ih_fireintuimessage: generated InputEvent. Class = 0x%X Code = %d EventAddress = 0x%X\n",
415 ie->ie_Class,
416 ie->ie_Code,
417 ie->ie_EventAddress));
419 } /* if ((ie = AllocInputEvent(iihd))) */
422 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: result 0x%lx\n",
423 result));
425 return result;
428 /*********************************************************************/
430 /* This function must never be called with the layer/layerinfo locked,
431 * otherwise a deadlock with ObtainGIRPort can happen.
433 IPTR Locked_DoMethodA (struct Window *w, struct Gadget *g, Msg message, struct IntuitionBase *IntuitionBase)
435 IPTR rc;
436 BOOL lock = w && (g->GadgetType & GTYP_SYSGADGET &&
437 ((g->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDRAGGING ||
438 (g->GadgetType & GTYP_SYSTYPEMASK) == GTYP_SIZING));
440 if (lock)
442 LOCK_REFRESH(w->WScreen);
445 LOCKGADGET
446 rc = Custom_DoMethodA(g, message);
447 UNLOCKGADGET
449 if (lock)
451 UNLOCK_REFRESH(w->WScreen);
454 return rc;
457 /*********************************************************************/
459 #undef Custom_DoMethodA
460 IPTR Custom_DoMethodA (struct IntuitionBase *IntuitionBase, struct Gadget *g, Msg message)
462 if (g->MutualExclude)
464 return AROS_UFC4(IPTR, ((struct Hook *)g->MutualExclude)->h_Entry,
465 AROS_UFCA(struct Hook *, (struct Hook *)g->MutualExclude, A0),
466 AROS_UFCA(struct Gadget *, g, A2),
467 AROS_UFCA(APTR, message, A1),
468 AROS_UFCA(struct IntuitionBase *, IntuitionBase, A6));
470 else /* Not needed since gadgetclass sets MutualExclude, but doesn't hurt. */
471 return DoMethodA((Object *)g, message);
474 /****************************************************************************************/
476 void NotifyDepthArrangement(struct Window *w, struct IntuitionBase *IntuitionBase)
478 if(w->MoreFlags & WMFLG_NOTIFYDEPTH)
480 ih_fire_intuimessage(w,
481 IDCMP_CHANGEWINDOW,
482 CWCODE_DEPTH,
484 IntuitionBase);
489 /****************************************************************************************/
491 void PrepareGadgetInfo(struct GadgetInfo *gi, struct Screen *scr, struct Window *win,
492 struct Requester *req)
494 gi->gi_Screen = scr;
495 gi->gi_Window = win;
496 gi->gi_Requester = req;
497 gi->gi_RastPort = 0;
498 gi->gi_Pens.DetailPen = scr->DetailPen;
499 gi->gi_Pens.BlockPen = scr->BlockPen;
500 gi->gi_DrInfo = (APTR)&(((struct IntScreen *)gi->gi_Screen)->DInfo);
503 /****************************************************************************************/
505 void SetGadgetInfoGadget(struct GadgetInfo *gi, struct Gadget *gad,
506 struct IntuitionBase *IntuitionBase)
508 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
510 SET_GI_RPORT(gi, gi->gi_Window, gi->gi_Requester, gad);
511 InitRastPort(&iihd->GadgetInfoRastPort);
513 iihd->GadgetInfoRastPort.Layer = gi->gi_RastPort->Layer;
514 iihd->GadgetInfoRastPort.BitMap = gi->gi_RastPort->BitMap;
516 SetFont(&iihd->GadgetInfoRastPort, gi->gi_DrInfo->dri_Font);
518 gi->gi_Layer = gi->gi_RastPort->Layer;
519 gi->gi_RastPort = &iihd->GadgetInfoRastPort;
521 GetGadgetDomain(gad, gi->gi_Screen, gi->gi_Window, gi->gi_Requester, &gi->gi_Domain);
524 /****************************************************************************************/
526 void SetGPIMouseCoords(struct gpInput *gpi, struct Gadget *gad)
528 struct GadgetInfo *gi = gpi->gpi_GInfo;
530 WORD mousex, mousey;
532 if (IS_SCREEN_GADGET(gad) || !gi->gi_Window)
534 mousex = gi->gi_Screen->MouseX;
535 mousey = gi->gi_Screen->MouseY;
537 else
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);
547 /****************************************************************************************/
549 void HandleSysGadgetVerify(struct GadgetInfo *gi, struct Gadget *gadget,
550 struct IntuitionBase *IntuitionBase)
552 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
554 case GTYP_CLOSE:
555 #ifdef __MORPHOS__
556 if (((struct IntWindow *)(gi->gi_Window))->specialflags & SPFLAG_IAMDEAD)
558 CrashedDispose(gi->gi_Window,IntuitionBase);
560 else
562 #endif
563 ih_fire_intuimessage(gi->gi_Window,
564 IDCMP_CLOSEWINDOW,
566 gi->gi_Window,
567 IntuitionBase);
568 #ifdef __MORPHOS__
570 #endif
571 break;
573 case GTYP_WDEPTH:
574 if (FALSE == IsLayerHiddenBySibling(WLAYER(gi->gi_Window),FALSE))
576 /* Send window to back */
577 WindowToBack(gi->gi_Window);
579 else
581 /* Send window to front */
582 WindowToFront(gi->gi_Window);
584 break;
586 case GTYP_WZOOM:
587 ZipWindow(gi->gi_Window);
588 break;
590 case GTYP_SDEPTH:
591 if (gi->gi_Screen == IntuitionBase->FirstScreen)
593 ScreenToBack(gi->gi_Screen);
595 else
597 ScreenToFront(gi->gi_Screen);
599 break;
601 } /* switch(gad->GadgetType & GTYP_SYSTYPEMASK) */
604 /****************************************************************************************/
606 struct Gadget *HandleCustomGadgetRetVal(IPTR retval, struct GadgetInfo *gi, struct Gadget *gadget,
607 ULONG termination, BOOL *reuse_event,
608 struct IntuitionBase *IntuitionBase)
610 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
612 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: retval %ld gi 0x%lx gadget 0x%lx termination %ld reuse %ld\n",
613 retval,
615 gadget,
616 termination,
617 *reuse_event));
619 if (retval != GMR_MEACTIVE)
621 struct gpGoInactive gpgi;
623 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: !GMR_MEACTIVE\n"));
625 if (retval & GMR_REUSE)
627 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: GMR_REUSE\n"));
628 *reuse_event = TRUE;
631 if (retval & GMR_VERIFY)
633 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: GMR_VERIFY\n"));
634 if (IS_SYS_GADGET(gadget))
636 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: SysGad\n"));
637 HandleSysGadgetVerify(gi, gadget, IntuitionBase);
639 else
641 /* Not a system gadget. Send IDCMP_GADGETUP, but not
642 if it is a screen gadget where gi->gi_Window would
643 be NULL */
645 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: no sysgad\n"));
646 if ((gadget->Activation & GACT_RELVERIFY) &&
647 (gi->gi_Window))
649 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: Send IDCMP_GADGETUP\n"));
650 ih_fire_intuimessage(gi->gi_Window,
651 IDCMP_GADGETUP,
652 termination & 0x0000FFFF,
653 gadget,
654 IntuitionBase);
657 } /* switch(gad->GadgetType & GTYP_SYSTYPEMASK) */
659 } /* if (retval & GMR_VERIFY) */
661 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: Send GM_GOINACTIVE\n"));
663 gpgi.MethodID = GM_GOINACTIVE;
664 gpgi.gpgi_GInfo = gi;
665 gpgi.gpgi_Abort = 0;
667 Locked_DoMethodA(gi->gi_Window, gadget, (Msg)&gpgi, IntuitionBase);
669 if (SYSGADGET_ACTIVE)
671 /* Switch back from Master Drag or Size Gadget to
672 real/original/app Size or Drag Gadget */
674 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: SYSGADGET_ACTIVE\n"));
675 gadget = iihdata->ActiveSysGadget;
676 iihdata->ActiveSysGadget = NULL;
678 if (IS_BOOPSI_GADGET(gadget))
680 Locked_DoMethodA(gi->gi_Window, gadget, (Msg)&gpgi, IntuitionBase);
683 #ifdef __MORPHOS__
684 if ((gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDRAGGING2)
686 ih_fire_intuimessage(gi->gi_Window,
687 IDCMP_GADGETUP,
689 gadget,
690 IntuitionBase);
692 #endif
694 retval = 0;
697 if (retval & GMR_VERIFY && gi->gi_Requester && gadget->Activation & GACT_ENDGADGET)
699 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: EndRequest\n"));
700 EndRequest(gi->gi_Requester, gi->gi_Window);
701 retval = 0;
704 gadget->Activation &= ~GACT_ACTIVEGADGET;
706 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle 0x%lx retval 0x%lx\n",
707 (gadget->Flags & GFLG_TABCYCLE),
708 retval));
710 if ((gadget->Flags & GFLG_TABCYCLE) && (retval & GMR_NEXTACTIVE))
712 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle+GMR_NEXTACTIVE\n"));
713 gadget = FindCycleGadget(gi->gi_Window, gi->gi_Requester, gadget, GMR_NEXTACTIVE);
715 else if ((gadget->Flags & GFLG_TABCYCLE) && (retval & GMR_PREVACTIVE))
717 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle+GMR_PREVACTIVE\n"));
718 gadget = FindCycleGadget(gi->gi_Window, gi->gi_Requester, gadget, GMR_PREVACTIVE);
720 else
722 gadget = NULL;
723 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: No gadget\n"));
726 if (gadget)
728 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: activate gadget 0x%lx\n",gadget));
729 gadget = DoActivateGadget(gi->gi_Window, gi->gi_Requester, gadget, IntuitionBase);
732 } /* if (retval != GMR_MEACTIVE) */
733 else
735 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: set GACT_ACTIVEGADGET\n"));
736 gadget->Activation |= GACT_ACTIVEGADGET;
739 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: return 0x%x\n", gadget));
740 return gadget;
743 /****************************************************************************************/
745 /* This function must never be called with the layer/layerinfo locked,
746 * otherwise a deadlock with ObtainGIRPort can happen.
748 struct Gadget *DoGPInput(struct GadgetInfo *gi, struct Gadget *gadget,
749 struct InputEvent *ie, STACKULONG methodid,
750 BOOL *reuse_event, struct IntuitionBase *IntuitionBase)
752 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
753 struct gpInput gpi;
754 IPTR retval;
755 ULONG termination;
757 ie->ie_Qualifier = iihdata->ActQualifier;
759 gpi.MethodID = methodid;
760 gpi.gpi_GInfo = gi;
761 gpi.gpi_IEvent = ie;
762 gpi.gpi_Termination = &termination;
763 gpi.gpi_TabletData = NULL;
765 SetGPIMouseCoords(&gpi, gadget);
767 retval = Locked_DoMethodA (gi->gi_Window, gadget, (Msg)&gpi, IntuitionBase);
769 DEBUG_DOGPINPUT(dprintf("DoGPInput: Locked_DoMethod gadget %p method 0x%lx retval %ld termination 0x%lx\n",
770 gadget, methodid, retval, termination));
772 return HandleCustomGadgetRetVal(retval, gi, gadget, termination,
773 reuse_event, IntuitionBase);
777 /****************************************************************************************/
779 struct Gadget * FindGadget (struct Screen *scr, struct Window * window,
780 struct Requester * req, int x, int y,
781 struct GadgetInfo * gi,BOOL sysonly,
782 struct IntuitionBase *IntuitionBase)
784 struct Gadget *gadget, *firstgadget, *draggadget = 0;
785 struct gpHitTest gpht;
786 struct IBox ibox;
787 WORD xrel, yrel;
788 BOOL sys_only = sysonly;
790 gpht.MethodID = GM_HITTEST;
791 gpht.gpht_GInfo = gi;
793 while (req || window || scr)
795 if (req)
797 firstgadget = req->ReqGadget;
799 else if (window)
801 firstgadget = window->FirstGadget;
803 else
805 if (draggadget) return draggadget;
806 firstgadget = scr->FirstGadget;
809 for (gadget = firstgadget; gadget; gadget = gadget->NextGadget)
811 if (!(gadget->Flags & GFLG_DISABLED) &&
812 (!sys_only ||
813 (gadget->GadgetType & GTYP_SYSGADGET &&
814 ((gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_SIZING ||
815 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDRAGGING ||
816 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDEPTH ||
817 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_SDEPTH ||
818 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WZOOM ||
819 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_CLOSE))))
821 /* stegerg: domain depends on gadgettype and windowflags! */
822 GetGadgetDomain(gadget, scr, window, req, &gi->gi_Domain);
824 /* Get coords relative to window */
826 GetGadgetIBox(gadget, gi, &ibox);
828 xrel = x - gi->gi_Domain.Left;
829 yrel = y - gi->gi_Domain.Top;
831 /*if (req)
833 xrel -= req->LeftEdge + window->BorderLeft;
834 yrel -= req->TopEdge + window->BorderTop;
837 if (window)
839 xrel -= window->LeftEdge;
840 yrel -= window->TopEdge;
843 if ((xrel >= ibox.Left) &&
844 (yrel >= ibox.Top) &&
845 (xrel < ibox.Left + ibox.Width) &&
846 (yrel < ibox.Top + ibox.Height))
848 if ((gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDRAGGING)
850 if (!draggadget) draggadget = gadget;
852 else
855 if ((gadget->GadgetType & GTYP_GTYPEMASK) == GTYP_CUSTOMGADGET)
858 gpht.gpht_Mouse.X = xrel - ibox.Left;
859 gpht.gpht_Mouse.Y = yrel - ibox.Top;
861 /* jDc: don't check for == GMR_GADGETHIT since some reaction classes*/
862 /* (BURN IN HELL!) return TRUE here (related to imageclass HITEST?)*/
863 if (Locked_DoMethodA (window, gadget, (Msg)&gpht, IntuitionBase))
864 return (gadget);
866 else
868 return (gadget);
873 } /* if (!(gadget->Flags & GFLG_DISABLED)) */
875 } /* for (gadget = window->FirstGadget; gadget; gadget = gadget->NextGadget) */
877 sys_only = sysonly;
879 if (req)
881 req = NULL;
882 sys_only = TRUE;
884 else if (window)
886 #ifdef SKINS
887 draggadget = findbordergadget(window,draggadget,IntuitionBase);
888 #endif
889 window = NULL;
891 else
892 scr = NULL;
895 return (draggadget);
897 } /* FindGadget */
900 /****************************************************************************************/
902 struct Gadget * FindHelpGadget (struct Window * window,
903 int x, int y, struct IntuitionBase *IntuitionBase)
905 struct Gadget *gadget, *firstgadget;
906 struct Requester *req = window->FirstRequest;
908 while (req || window)
910 if (req)
912 firstgadget = req->ReqGadget;
914 else
916 firstgadget = window->FirstGadget;
919 for (gadget = firstgadget; gadget; gadget = gadget->NextGadget)
921 if ((gadget->Flags & GFLG_EXTENDED) &&
922 (((struct ExtGadget *)gadget)->MoreFlags & GMORE_GADGETHELP))
924 if (InsideGadget(window->WScreen, window, req, gadget, x, y))
926 return (gadget);
932 if (req)
933 req = req->OlderRequest;
934 else
935 window = NULL;
938 return (NULL);
940 } /* FindGadget */
943 /****************************************************************************************/
945 BOOL InsideGadget(struct Screen *scr, struct Window *win, struct Requester *req,
946 struct Gadget *gad, WORD x, WORD y)
948 struct IBox box;
949 BOOL rc = FALSE;
951 GetScrGadgetIBox(gad, scr, win, req, &box);
953 if ((x >= box.Left) &&
954 (y >= box.Top) &&
955 (x < box.Left + box.Width) &&
956 (y < box.Top + box.Height))
958 rc = TRUE;
961 return rc;
964 /****************************************************************************************/
966 struct Gadget *DoActivateGadget(struct Window *win, struct Requester *req, struct Gadget *gad,
967 struct IntuitionBase *IntuitionBase)
969 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
970 struct GadgetInfo *gi = &iihd->GadgetInfo;
971 struct Gadget *result = NULL;
973 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Window 0x%lx Req 0x%lx Gadget 0x%lx\n",
974 win,
975 req,
976 gad));
978 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Activation 0x%lx\n",
979 gad->Activation));
981 if (gad->Activation & GACT_IMMEDIATE)
983 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Send GADGETDOWN msg\n"));
984 ih_fire_intuimessage(win,
985 IDCMP_GADGETDOWN,
987 gad,
988 IntuitionBase);
991 PrepareGadgetInfo(gi, win->WScreen, win, req);
992 SetGadgetInfoGadget(gi, gad, IntuitionBase);
994 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Type 0x%lx\n",
995 gad->GadgetType & GTYP_GTYPEMASK));
997 switch(gad->GadgetType & GTYP_GTYPEMASK)
999 case GTYP_STRGADGET:
1000 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: GTYP_STRGADGET\n"));
1001 gad->Activation |= GACT_ACTIVEGADGET;
1002 UpdateStrGadget(gad, win, req, IntuitionBase);
1003 result = gad;
1004 break;
1006 case GTYP_CUSTOMGADGET:
1008 struct gpInput gpi;
1009 ULONG termination;
1010 IPTR retval;
1011 BOOL reuse_event;
1013 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: GTYP_CUSTOMGADGET\n"));
1015 gpi.MethodID = GM_GOACTIVE;
1016 gpi.gpi_GInfo = gi;
1017 gpi.gpi_IEvent = NULL;
1018 gpi.gpi_Termination = &termination;
1019 gpi.gpi_Mouse.X = win->MouseX - gi->gi_Domain.Left - GetGadgetLeft(gad, gi->gi_Screen, gi->gi_Window, NULL);
1020 gpi.gpi_Mouse.Y = win->MouseY - gi->gi_Domain.Top - GetGadgetTop(gad, gi->gi_Screen, gi->gi_Window, NULL);
1021 gpi.gpi_TabletData = NULL;
1023 retval = Locked_DoMethodA (win, gad, (Msg)&gpi, IntuitionBase);
1025 gad = HandleCustomGadgetRetVal(retval, gi, gad,termination,
1026 &reuse_event, IntuitionBase);
1028 if (gad)
1030 gad->Activation |= GACT_ACTIVEGADGET;
1031 result = gad;
1033 break;
1036 } /* switch(gad->GadgetType & GTYP_GTYPEMASK) */
1038 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: result 0x%lx\n",
1039 result));
1041 if (result) iihd->ActiveGadget = result;
1043 return result;
1047 /****************************************************************************************/
1049 struct Gadget *FindCycleGadget(struct Window *win, struct Requester *req,
1050 struct Gadget *gad, WORD direction)
1052 struct Gadget *g = NULL, *gg, *prev, *first;
1054 D(bug("FindCycleGadget: win = %p req %p gad = %p direction = %d\n", win, req, gad, direction));
1056 if (req)
1057 first = req->ReqGadget;
1058 else
1059 first = win->FirstGadget;
1061 switch(direction)
1063 case GMR_NEXTACTIVE:
1064 g = gad->NextGadget;
1065 if (!g) g = first;
1067 while(g)
1069 if (g == gad)
1071 if (!(gad->Flags & GFLG_TABCYCLE) || (gad->Flags & GFLG_DISABLED))
1073 /* should never happen */
1074 g = NULL;
1076 break;
1078 if (!(g->Flags & GFLG_DISABLED) && (g->Flags & GFLG_TABCYCLE)) break;
1080 g = g->NextGadget;
1081 if (!g) g = first;
1083 break;
1085 case GMR_PREVACTIVE:
1086 prev = 0;
1087 g = 0;
1088 gg = first;
1090 /* find a TABCYCLE gadget which is before gad in window's gadgetlist */
1091 while (gg)
1093 if (gg == gad)
1095 if (prev) g = prev;
1096 break;
1098 if (!(gg->Flags & GFLG_DISABLED) && (gg->Flags & GFLG_TABCYCLE)) prev = gg;
1099 gg = gg->NextGadget;
1102 if (gg && !g)
1104 /* There was no TABCYCLE gadget before gad in window's gadgetlist */
1106 gg = gg->NextGadget;
1107 if (!gg)
1109 if (!(gad->Flags & GFLG_DISABLED) && (gad->Flags & GFLG_TABCYCLE)) g = gad;
1110 break;
1112 prev = 0;
1114 while(gg)
1116 if (!(gg->Flags & GFLG_DISABLED) && (gg->Flags & GFLG_TABCYCLE)) prev = gg;
1117 gg = gg->NextGadget;
1120 if (prev)
1122 g = prev;
1124 else
1126 if (!(gad->Flags & GFLG_DISABLED) && (gad->Flags & GFLG_TABCYCLE)) g = gad;
1131 break;
1133 default: /* Unused, but well... */
1134 g = first;
1135 break;
1137 } /* switch(direction) */
1139 return g;
1142 /****************************************************************************************/
1144 void FixWindowCoords(struct Window *win, LONG *left, LONG *top, LONG *width, LONG *height,struct IntuitionBase *IntuitionBase)
1146 struct Screen *scr = win->WScreen;
1148 if (*width < 1) *width = 1;
1149 if (*height < 1) *height = 1;
1151 if (*width > scr->Width) *width = scr->Width;
1152 if (*height > scr->Height) *height = scr->Height;
1154 if ((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (win->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS))
1156 if (*left > scr->Width - 1) *left = scr->Width - 1;
1157 if (*top > scr->Height - 1) *top = scr->Height -1;
1159 else
1162 if ((*left + *width) > scr->Width)
1164 *left = scr->Width - *width;
1166 else if (*left < 0)
1168 *left = 0;
1171 if ((*top + *height) > scr->Height)
1173 *top = scr->Height - *height;
1175 else if (*top < 0)
1177 *top = 0;
1182 /****************************************************************************************/
1184 void WindowNeedsRefresh(struct Window * w,
1185 struct IntuitionBase * IntuitionBase )
1187 /* Supposed to send a message to this window, saying that it needs a
1188 refresh. I will check whether there is no such a message queued in
1189 its messageport, though. It only needs one such message!
1192 /* Refresh the window's gadgetry ...
1193 ... stegerg: and in the actual implementation
1194 call RefershWindowFrame first, as the border gadgets don´t
1195 cover the whole border area.*/
1198 jDc: in actual implementation sizeevent means that we need to send
1199 idcmp, etc and do not clear the flag for smart_refresh window that
1200 has no idcmp_refreshwindow, otherwise we clear the flag!
1203 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: window 0x%lx gzz %d nocarerefresh %d\n",
1204 w, IS_GZZWINDOW(w), IS_NOCAREREFRESH(w)));
1206 //trashregion means that we use delayed refreshing!
1208 if (
1209 #ifdef DAMAGECACHE
1210 (!IW(w)->trashregion) ||
1211 #else
1212 (!(w->Flags & WFLG_SIMPLE_REFRESH)) ||
1213 #endif
1214 IS_NOCAREREFRESH(w))
1217 Gad_BeginUpdate(WLAYER(w), IntuitionBase);
1219 if (IS_NOCAREREFRESH(w) || (!((!(w->Flags & WFLG_SIMPLE_REFRESH)) && (!(IW(w)->specialflags & SPFLAG_LAYERRESIZED)))))
1221 if (!IS_GZZWINDOW(w))
1223 if (w->Flags & WFLG_BORDERLESS)
1225 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, 0, IntuitionBase);
1227 else
1229 int_refreshwindowframe(w,0,0,IntuitionBase);
1232 else
1234 /* refresh all gadgets except border gadgets */
1235 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, REFRESHGAD_BORDER, IntuitionBase);
1237 IW(w)->specialflags &= ~SPFLAG_LAYERRESIZED;
1240 if (IS_NOCAREREFRESH(w)) WLAYER(w)->Flags &= ~LAYERREFRESH;
1242 Gad_EndUpdate(WLAYER(w), IS_NOCAREREFRESH(w) ? TRUE : FALSE, IntuitionBase);
1244 } else {
1245 #ifdef DAMAGECACHE
1246 struct Rectangle rect;
1247 BOOL doclear = (w->Flags & WFLG_BORDERLESS) ? FALSE : TRUE;
1249 rect.MinX = w->BorderLeft;
1250 rect.MinY = w->BorderTop;
1251 rect.MaxX = w->Width - w->BorderRight - 1;
1252 rect.MaxY = w->Height - w->BorderBottom - 1;
1253 #endif
1255 #ifndef BEGINUPDATEGADGETREFRESH
1256 Gad_BeginUpdate(WLAYER(w), IntuitionBase);
1257 #else
1258 #ifdef DAMAGECACHE
1259 LockLayer(0,WLAYER(w));
1260 #endif
1261 #endif
1263 #ifndef BEGINUPDATEGADGETREFRESH
1264 if (!IS_GZZWINDOW(w))
1266 if (w->Flags & WFLG_BORDERLESS)
1268 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, 0, IntuitionBase);
1270 else
1272 int_refreshwindowframe(w,0,0,IntuitionBase);
1275 else
1277 /* refresh all gadgets except border and gadtools gadgets */
1278 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, REFRESHGAD_BORDER , IntuitionBase);
1280 #endif
1282 #ifdef DAMAGECACHE
1283 //add rects to trashregion here
1284 OrRegionRegion(WLAYER(w)->DamageList,IW(w)->trashregion);
1286 if (doclear)
1288 ClearRectRegion(IW(w)->trashregion,&rect);
1289 AndRectRegion(WLAYER(w)->DamageList,&rect);
1292 IW(w)->specialflags |= SPFLAG_LAYERREFRESH;
1293 #else
1294 #ifdef BEGINUPDATEGADGETREFRESH
1295 IW(w)->specialflags |= SPFLAG_LAYERREFRESH;
1296 #endif
1297 #endif
1299 #ifndef BEGINUPDATEGADGETREFRESH
1300 Gad_EndUpdate(WLAYER(w), FALSE, IntuitionBase);
1301 #else
1302 #ifdef DAMAGECACHE
1303 UnlockLayer(WLAYER(w));
1304 #endif
1305 #endif
1309 if (IS_DOCAREREFRESH(w))
1311 if (w->UserPort && (w->IDCMPFlags & IDCMP_REFRESHWINDOW))
1313 struct IntuiMessage *IM;
1314 BOOL found = FALSE;
1316 /* Can use Forbid() for this */
1317 Forbid();
1319 IM = (struct IntuiMessage *)w->UserPort->mp_MsgList.lh_Head;
1321 ForeachNode(&w->UserPort->mp_MsgList, IM)
1323 /* Does the window already have such a message? */
1324 if (IDCMP_REFRESHWINDOW == IM->Class && IM->IAddress == w)
1326 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: refresh pending\n"));
1327 D(bug("Window %s already has a refresh message pending!!\n",
1328 w->Title ? w->Title : (STRPTR)"<NONAME>"));
1329 found = TRUE;
1330 break;
1334 Permit();
1336 if (!found)
1338 struct InputEvent *new_ie;
1339 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
1341 D(bug("Sending a refresh message to window %s %d %d %d %d!!\n",
1342 w->Title ? w->Title : (STRPTR)"<NONAME>",
1343 w->LeftEdge,
1344 w->TopEdge,
1345 w->Width,
1346 w->Height));
1348 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: sending idcmp message\n"));
1350 if ((new_ie = AllocInputEvent(iihdata)))
1352 new_ie->ie_Class = IECLASS_EVENT;
1353 new_ie->ie_Code = IECODE_REFRESH;
1354 new_ie->ie_EventAddress = w;
1355 CurrentTime(&new_ie->ie_TimeStamp.tv_secs, &new_ie->ie_TimeStamp.tv_micro);
1358 fire_intuimessage(w,
1359 IDCMP_REFRESHWINDOW,
1362 IntuitionBase);
1363 } /* if (!found) */
1365 } /* if (w->UserPort && (w->IDCMPFlags & IDCMP_REFRESHWINDOW)) */
1366 else
1368 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
1370 if (FindTask(NULL) == iihdata->InputDeviceTask)
1372 struct InputEvent *new_ie;
1374 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: sending inputevent\n"));
1376 if ((new_ie = AllocInputEvent(iihdata)))
1378 new_ie->ie_Class = IECLASS_EVENT;
1379 new_ie->ie_Code = IECODE_REFRESH;
1380 new_ie->ie_EventAddress = w;
1381 CurrentTime(&new_ie->ie_TimeStamp.tv_secs, &new_ie->ie_TimeStamp.tv_micro);
1384 ih_fire_intuimessage(w,
1385 IDCMP_REFRESHWINDOW,
1388 IntuitionBase);
1392 } /* if (!IS_NOCAREREFRESH(w)) */
1396 /****************************************************************************************/
1398 struct Window *FindActiveWindow(struct InputEvent *ie,ULONG *stitlebarhit,
1399 struct IntuitionBase *IntuitionBase)
1401 /* The caller has checked that the input event is a IECLASS_RAWMOUSE, SELECTDOWN event */
1402 /* NOTE: may be called with NULL ie ptr! */
1403 struct Screen *scr;
1404 struct Layer *l;
1405 struct Window *new_w;
1406 ULONG lock;
1408 lock = LockIBase(0UL);
1410 new_w = IntuitionBase->ActiveWindow;
1411 scr = IntuitionBase->FirstScreen;
1413 UnlockIBase(lock);
1415 D(bug("FindActiveWindow: scr %p win %p\n",scr,new_w));
1417 if (stitlebarhit) *stitlebarhit = FALSE;
1419 if (scr)
1421 D(bug("FindActiveWindow: Click at (%d,%d)\n",scr->MouseX,scr->MouseY));
1423 /* What layer ? */
1424 LockLayerInfo(&scr->LayerInfo);
1426 l = WhichLayer(&scr->LayerInfo, scr->MouseX, scr->MouseY);
1428 UnlockLayerInfo(&scr->LayerInfo);
1430 if (NULL == l)
1432 new_w = NULL;
1433 D(bug("FindActiveWindow: Click not inside layer\n"));
1435 else if (l == scr->BarLayer)
1437 D(bug("FindActiveWindow: Click on screen bar layer -> active window stays the same\n"));
1438 if (stitlebarhit) *stitlebarhit = TRUE;
1440 else
1442 new_w = (struct Window *)l->Window;
1443 if (!new_w)
1445 D(bug("FindActiveWindow: Selected layer is not a window\n"));
1448 D(bug("FindActiveWindow: Found layer %p\n", l));
1452 D(bug("FindActiveWindow: New window %p\n", new_w));
1453 return new_w;
1456 /****************************************************************************************/
1458 struct Window *FindDesktopWindow(struct Screen *screen,struct IntuitionBase *IntuitionBase)
1460 struct Window *win;
1462 for (win = screen->FirstWindow; win; win = win->NextWindow)
1464 if (win->Flags & WFLG_BACKDROP &&
1465 win->Width == screen->Width &&
1466 win->Height >= screen->Height - (screen->BarHeight + 2))
1468 return win;
1472 return NULL;
1476 /****************************************************************************************/
1478 struct InputEvent *AllocInputEvent(struct IIHData *iihdata)
1480 struct IntuitionBase *IntuitionBase = iihdata->IntuitionBase;
1481 struct GeneratedInputEvent *gie;
1482 struct InputEvent *ie;
1484 /* There might be an inputevent from someone else that our handler discarded.
1485 * We may as well use it. This can only happen inside our main loop.
1487 ie = iihdata->FreeInputEvents;
1488 if (ie)
1490 iihdata->FreeInputEvents = ie->ie_NextEvent;
1491 DEBUG_INPUTEVENT(dprintf("AllocInputEvent: reuse 0x%lx event\n", ie));
1493 else
1495 gie = AllocPooled(iihdata->InputEventMemPool, sizeof(struct GeneratedInputEvent));
1496 if (gie)
1498 /* Allocated events are put in the list of events that have not yet been
1499 * propagated.
1501 AddTail((struct List *)&iihdata->NewAllocatedInputEventList, (struct Node *)gie);
1502 ie = &gie->ie;
1504 DEBUG_INPUTEVENT(dprintf("AllocInputEvent: allocated 0x%lx (0x%lx)\n", ie, gie));
1507 if (ie)
1509 *iihdata->EndInputEventChain = ie;
1510 iihdata->EndInputEventChain = &ie->ie_NextEvent;
1513 return ie;
1516 /****************************************************************************************/
1518 void FreeGeneratedInputEvents(struct IIHData *iihdata)
1520 struct IntuitionBase *IntuitionBase = iihdata->IntuitionBase;
1521 struct Node *node, *succ;
1523 /* Free the list of allocated events that have already been propagated. */
1524 ForeachNodeSafe(&iihdata->AllocatedInputEventList, node, succ)
1526 DEBUG_INPUTEVENT(dprintf("FreeGeneratedInputEvent: free 0x%lx\n", node));
1527 FreePooled(iihdata->InputEventMemPool, node, sizeof(struct GeneratedInputEvent));
1530 /* The list is not in a valid state at this point, and NewList() should
1531 * be called, but since we won't use it until the list of not-yet-propagated
1532 * events is copied in it, we won't bother.
1534 //NEWLIST(&iihdata->AllocatedInputEventList);
1537 /****************************************************************************************/
1539 BOOL FireMenuMessage(WORD code, struct Window *win,
1540 struct InputEvent *ie, struct IntuitionBase *IntuitionBase)
1542 struct MenuMessage *msg;
1543 BOOL result = FALSE;
1545 if ((msg = AllocMenuMessage(IntuitionBase)))
1547 msg->code = code;
1548 msg->win = win;
1549 if (ie) msg->ie = *ie;
1550 SendMenuMessage(msg, IntuitionBase);
1552 result = TRUE;
1555 return result;
1558 /****************************************************************************************/
1560 LONG Gad_BeginUpdate(struct Layer *layer, struct IntuitionBase *IntuitionBase)
1562 /* Must lock GadgetLock to avoid deadlocks with ObtainGirPort
1563 from other tasks, because ObtainGirPort first obtains
1564 GadgetLock and then layer lock through LockLayer!!!! */
1565 LOCKGADGET
1566 return BeginUpdate(layer);
1569 /****************************************************************************************/
1571 void Gad_EndUpdate(struct Layer *layer, UWORD flag, struct IntuitionBase *IntuitionBase)
1573 EndUpdate(layer, flag);
1574 UNLOCKGADGET
1577 /****************************************************************************************/