some fixes to accented characters
[tangerine.git] / rom / intuition / inputhandler_support.c
blob86d6b94f6d37e793a1e9626abaa2ea36044fd504
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
540 mousex = gi->gi_Window->MouseX;
541 mousey = gi->gi_Window->MouseY;
544 gpi->gpi_Mouse.X = mousex - gi->gi_Domain.Left - GetGadgetLeft(gad, gi->gi_Screen, gi->gi_Window, gi->gi_Requester);
545 gpi->gpi_Mouse.Y = mousey - gi->gi_Domain.Top - GetGadgetTop(gad, gi->gi_Screen, gi->gi_Window, gi->gi_Requester);
549 /****************************************************************************************/
551 void HandleSysGadgetVerify(struct GadgetInfo *gi, struct Gadget *gadget,
552 struct IntuitionBase *IntuitionBase)
554 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
556 case GTYP_CLOSE:
557 #ifdef __MORPHOS__
558 if (((struct IntWindow *)(gi->gi_Window))->specialflags & SPFLAG_IAMDEAD)
560 CrashedDispose(gi->gi_Window,IntuitionBase);
562 else
564 #endif
565 ih_fire_intuimessage(gi->gi_Window,
566 IDCMP_CLOSEWINDOW,
568 gi->gi_Window,
569 IntuitionBase);
570 #ifdef __MORPHOS__
572 #endif
573 break;
575 case GTYP_WDEPTH:
576 if (!IsLayerHiddenBySibling(WLAYER(gi->gi_Window), FALSE))
578 /* Send window to back */
579 WindowToBack(gi->gi_Window);
581 else
583 /* Send window to front */
584 WindowToFront(gi->gi_Window);
586 break;
588 case GTYP_WZOOM:
589 ZipWindow(gi->gi_Window);
590 break;
592 case GTYP_SDEPTH:
593 if (gi->gi_Screen == IntuitionBase->FirstScreen)
595 ScreenToBack(gi->gi_Screen);
597 else
599 ScreenToFront(gi->gi_Screen);
601 break;
603 } /* switch(gad->GadgetType & GTYP_SYSTYPEMASK) */
606 /****************************************************************************************/
608 struct Gadget *HandleCustomGadgetRetVal(IPTR retval, struct GadgetInfo *gi, struct Gadget *gadget,
609 ULONG termination, BOOL *reuse_event,
610 struct IntuitionBase *IntuitionBase)
612 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
614 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: retval %ld gi 0x%lx gadget 0x%lx termination %ld reuse %ld\n",
615 retval,
617 gadget,
618 termination,
619 *reuse_event));
621 if (retval != GMR_MEACTIVE)
623 struct gpGoInactive gpgi;
625 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: !GMR_MEACTIVE\n"));
627 if (retval & GMR_REUSE)
629 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: GMR_REUSE\n"));
630 *reuse_event = TRUE;
633 if (retval & GMR_VERIFY)
635 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: GMR_VERIFY\n"));
636 if (IS_SYS_GADGET(gadget))
638 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: SysGad\n"));
639 HandleSysGadgetVerify(gi, gadget, IntuitionBase);
641 else
643 /* Not a system gadget. Send IDCMP_GADGETUP, but not
644 if it is a screen gadget where gi->gi_Window would
645 be NULL */
647 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: no sysgad\n"));
648 if ((gadget->Activation & GACT_RELVERIFY) &&
649 (gi->gi_Window))
651 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: Send IDCMP_GADGETUP\n"));
652 ih_fire_intuimessage(gi->gi_Window,
653 IDCMP_GADGETUP,
654 termination & 0x0000FFFF,
655 gadget,
656 IntuitionBase);
659 } /* switch(gad->GadgetType & GTYP_SYSTYPEMASK) */
661 } /* if (retval & GMR_VERIFY) */
663 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: Send GM_GOINACTIVE\n"));
665 gpgi.MethodID = GM_GOINACTIVE;
666 gpgi.gpgi_GInfo = gi;
667 gpgi.gpgi_Abort = 0;
669 Locked_DoMethodA(gi->gi_Window, gadget, (Msg)&gpgi, IntuitionBase);
671 if (SYSGADGET_ACTIVE)
673 /* Switch back from Master Drag or Size Gadget to
674 real/original/app Size or Drag Gadget */
676 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: SYSGADGET_ACTIVE\n"));
677 gadget = iihdata->ActiveSysGadget;
678 iihdata->ActiveSysGadget = NULL;
680 if (IS_BOOPSI_GADGET(gadget))
682 Locked_DoMethodA(gi->gi_Window, gadget, (Msg)&gpgi, IntuitionBase);
685 #ifdef __MORPHOS__
686 if ((gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDRAGGING2)
688 ih_fire_intuimessage(gi->gi_Window,
689 IDCMP_GADGETUP,
691 gadget,
692 IntuitionBase);
694 #endif
696 retval = 0;
699 if (retval & GMR_VERIFY && gi->gi_Requester && gadget->Activation & GACT_ENDGADGET)
701 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: EndRequest\n"));
702 EndRequest(gi->gi_Requester, gi->gi_Window);
703 retval = 0;
706 gadget->Activation &= ~GACT_ACTIVEGADGET;
708 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle 0x%lx retval 0x%lx\n",
709 (gadget->Flags & GFLG_TABCYCLE),
710 retval));
712 if ((gadget->Flags & GFLG_TABCYCLE) && (retval & GMR_NEXTACTIVE))
714 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle+GMR_NEXTACTIVE\n"));
715 gadget = FindCycleGadget(gi->gi_Window, gi->gi_Requester, gadget, GMR_NEXTACTIVE);
717 else if ((gadget->Flags & GFLG_TABCYCLE) && (retval & GMR_PREVACTIVE))
719 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle+GMR_PREVACTIVE\n"));
720 gadget = FindCycleGadget(gi->gi_Window, gi->gi_Requester, gadget, GMR_PREVACTIVE);
722 else
724 gadget = NULL;
725 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: No gadget\n"));
728 if (gadget)
730 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: activate gadget 0x%lx\n",gadget));
731 gadget = DoActivateGadget(gi->gi_Window, gi->gi_Requester, gadget, IntuitionBase);
734 } /* if (retval != GMR_MEACTIVE) */
735 else
737 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: set GACT_ACTIVEGADGET\n"));
738 gadget->Activation |= GACT_ACTIVEGADGET;
741 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: return 0x%x\n", gadget));
742 return gadget;
745 /****************************************************************************************/
747 /* This function must never be called with the layer/layerinfo locked,
748 * otherwise a deadlock with ObtainGIRPort can happen.
750 struct Gadget *DoGPInput(struct GadgetInfo *gi, struct Gadget *gadget,
751 struct InputEvent *ie, STACKULONG methodid,
752 BOOL *reuse_event, struct IntuitionBase *IntuitionBase)
754 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
755 struct gpInput gpi;
756 IPTR retval;
757 ULONG termination;
758 ie->ie_Qualifier = iihdata->ActQualifier;
760 gpi.MethodID = methodid;
761 gpi.gpi_GInfo = gi;
762 gpi.gpi_IEvent = ie;
763 gpi.gpi_Termination = &termination;
764 gpi.gpi_TabletData = NULL;
766 SetGPIMouseCoords(&gpi, gadget);
768 retval = Locked_DoMethodA (gi->gi_Window, gadget, (Msg)&gpi, IntuitionBase);
770 DEBUG_DOGPINPUT(dprintf("DoGPInput: Locked_DoMethod gadget %p method 0x%lx retval %ld termination 0x%lx\n",
771 gadget, methodid, retval, termination));
773 return HandleCustomGadgetRetVal(retval, gi, gadget, termination,
774 reuse_event, IntuitionBase);
778 /****************************************************************************************/
780 struct Gadget * FindGadget (struct Screen *scr, struct Window * window,
781 struct Requester * req, int x, int y,
782 struct GadgetInfo * gi,BOOL sysonly,
783 struct IntuitionBase *IntuitionBase)
785 struct Gadget *gadget, *firstgadget, *draggadget = 0;
786 struct gpHitTest gpht;
787 struct IBox ibox;
788 WORD xrel, yrel;
789 BOOL sys_only = sysonly;
791 gpht.MethodID = GM_HITTEST;
792 gpht.gpht_GInfo = gi;
794 while (req || window || scr)
796 if (req)
798 firstgadget = req->ReqGadget;
800 else if (window)
802 firstgadget = window->FirstGadget;
804 else
806 if (draggadget) return draggadget;
807 firstgadget = scr->FirstGadget;
810 for (gadget = firstgadget; gadget; gadget = gadget->NextGadget)
812 if (!(gadget->Flags & GFLG_DISABLED) &&
813 (!sys_only ||
814 (gadget->GadgetType & GTYP_SYSGADGET &&
815 ((gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_SIZING ||
816 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDRAGGING ||
817 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDEPTH ||
818 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_SDEPTH ||
819 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WZOOM ||
820 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_CLOSE))))
822 /* stegerg: domain depends on gadgettype and windowflags! */
823 GetGadgetDomain(gadget, scr, window, req, &gi->gi_Domain);
825 /* Get coords relative to window */
827 GetGadgetIBox(gadget, gi, &ibox);
829 xrel = x - gi->gi_Domain.Left;
830 yrel = y - gi->gi_Domain.Top;
832 /*if (req)
834 xrel -= req->LeftEdge + window->BorderLeft;
835 yrel -= req->TopEdge + window->BorderTop;
838 if (window)
840 xrel -= window->LeftEdge;
841 yrel -= window->TopEdge;
844 if ((xrel >= ibox.Left) &&
845 (yrel >= ibox.Top) &&
846 (xrel < ibox.Left + ibox.Width) &&
847 (yrel < ibox.Top + ibox.Height))
849 if ((gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDRAGGING)
851 if (!draggadget) draggadget = gadget;
853 else
856 if ((gadget->GadgetType & GTYP_GTYPEMASK) == GTYP_CUSTOMGADGET)
859 gpht.gpht_Mouse.X = xrel - ibox.Left;
860 gpht.gpht_Mouse.Y = yrel - ibox.Top;
862 /* jDc: don't check for == GMR_GADGETHIT since some reaction classes*/
863 /* (BURN IN HELL!) return TRUE here (related to imageclass HITEST?)*/
864 if (Locked_DoMethodA (window, gadget, (Msg)&gpht, IntuitionBase))
865 return (gadget);
867 else
869 return (gadget);
874 } /* if (!(gadget->Flags & GFLG_DISABLED)) */
876 } /* for (gadget = window->FirstGadget; gadget; gadget = gadget->NextGadget) */
878 sys_only = sysonly;
880 if (req)
882 req = NULL;
883 sys_only = TRUE;
885 else if (window)
887 #ifdef SKINS
888 draggadget = findbordergadget(window,draggadget,IntuitionBase);
889 #endif
890 window = NULL;
892 else
893 scr = NULL;
896 return (draggadget);
898 } /* FindGadget */
901 /****************************************************************************************/
903 struct Gadget * FindHelpGadget (struct Window * window,
904 int x, int y, struct IntuitionBase *IntuitionBase)
906 struct Gadget *gadget, *firstgadget;
907 struct Requester *req = window->FirstRequest;
909 while (req || window)
911 if (req)
913 firstgadget = req->ReqGadget;
915 else
917 firstgadget = window->FirstGadget;
920 for (gadget = firstgadget; gadget; gadget = gadget->NextGadget)
922 if ((gadget->Flags & GFLG_EXTENDED) &&
923 (((struct ExtGadget *)gadget)->MoreFlags & GMORE_GADGETHELP))
925 if (InsideGadget(window->WScreen, window, req, gadget, x, y))
927 return (gadget);
933 if (req)
934 req = req->OlderRequest;
935 else
936 window = NULL;
939 return (NULL);
941 } /* FindGadget */
944 /****************************************************************************************/
946 BOOL InsideGadget(struct Screen *scr, struct Window *win, struct Requester *req,
947 struct Gadget *gad, WORD x, WORD y)
949 struct IBox box;
950 BOOL rc = FALSE;
952 GetScrGadgetIBox(gad, scr, win, req, &box);
954 if ((x >= box.Left) &&
955 (y >= box.Top) &&
956 (x < box.Left + box.Width) &&
957 (y < box.Top + box.Height))
959 rc = TRUE;
962 return rc;
965 /****************************************************************************************/
967 struct Gadget *DoActivateGadget(struct Window *win, struct Requester *req, struct Gadget *gad,
968 struct IntuitionBase *IntuitionBase)
970 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
971 struct GadgetInfo *gi = &iihd->GadgetInfo;
972 struct Gadget *result = NULL;
974 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Window 0x%lx Req 0x%lx Gadget 0x%lx\n",
975 win,
976 req,
977 gad));
979 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Activation 0x%lx\n",
980 gad->Activation));
982 if (gad->Activation & GACT_IMMEDIATE)
984 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Send GADGETDOWN msg\n"));
985 ih_fire_intuimessage(win,
986 IDCMP_GADGETDOWN,
988 gad,
989 IntuitionBase);
992 PrepareGadgetInfo(gi, win->WScreen, win, req);
993 SetGadgetInfoGadget(gi, gad, IntuitionBase);
995 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Type 0x%lx\n",
996 gad->GadgetType & GTYP_GTYPEMASK));
998 switch(gad->GadgetType & GTYP_GTYPEMASK)
1000 case GTYP_STRGADGET:
1002 struct StringInfo *si = (struct StringInfo *)gad->SpecialInfo;
1004 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: GTYP_STRGADGET\n"));
1006 gad->Flags |= GFLG_SELECTED;
1007 if (si && si->UndoBuffer)
1009 strcpy(si->UndoBuffer, si->Buffer);
1012 gad->Activation |= GACT_ACTIVEGADGET;
1013 UpdateStrGadget(gad, win, req, IntuitionBase);
1014 result = gad;
1015 break;
1018 case GTYP_CUSTOMGADGET:
1020 struct gpInput gpi;
1021 ULONG termination;
1022 IPTR retval;
1023 BOOL reuse_event;
1025 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: GTYP_CUSTOMGADGET\n"));
1027 gpi.MethodID = GM_GOACTIVE;
1028 gpi.gpi_GInfo = gi;
1029 gpi.gpi_IEvent = NULL;
1030 gpi.gpi_Termination = &termination;
1031 gpi.gpi_Mouse.X = win->MouseX - gi->gi_Domain.Left - GetGadgetLeft(gad, gi->gi_Screen, gi->gi_Window, NULL);
1032 gpi.gpi_Mouse.Y = win->MouseY - gi->gi_Domain.Top - GetGadgetTop(gad, gi->gi_Screen, gi->gi_Window, NULL);
1033 gpi.gpi_TabletData = NULL;
1035 retval = Locked_DoMethodA (win, gad, (Msg)&gpi, IntuitionBase);
1037 gad = HandleCustomGadgetRetVal(retval, gi, gad,termination,
1038 &reuse_event, IntuitionBase);
1040 if (gad)
1042 gad->Activation |= GACT_ACTIVEGADGET;
1043 result = gad;
1045 break;
1048 } /* switch(gad->GadgetType & GTYP_GTYPEMASK) */
1050 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: result 0x%lx\n",
1051 result));
1053 if (result) iihd->ActiveGadget = result;
1055 return result;
1059 /****************************************************************************************/
1061 struct Gadget *FindCycleGadget(struct Window *win, struct Requester *req,
1062 struct Gadget *gad, WORD direction)
1064 struct Gadget *g = NULL, *gg, *prev, *first;
1066 D(bug("FindCycleGadget: win = %p req %p gad = %p direction = %d\n", win, req, gad, direction));
1068 if (req)
1069 first = req->ReqGadget;
1070 else
1071 first = win->FirstGadget;
1073 switch(direction)
1075 case GMR_NEXTACTIVE:
1076 g = gad->NextGadget;
1077 if (!g) g = first;
1079 while(g)
1081 if (g == gad)
1083 if (!(gad->Flags & GFLG_TABCYCLE) || (gad->Flags & GFLG_DISABLED))
1085 /* should never happen */
1086 g = NULL;
1088 break;
1090 if (!(g->Flags & GFLG_DISABLED) && (g->Flags & GFLG_TABCYCLE)) break;
1092 g = g->NextGadget;
1093 if (!g) g = first;
1095 break;
1097 case GMR_PREVACTIVE:
1098 prev = 0;
1099 g = 0;
1100 gg = first;
1102 /* find a TABCYCLE gadget which is before gad in window's gadgetlist */
1103 while (gg)
1105 if (gg == gad)
1107 if (prev) g = prev;
1108 break;
1110 if (!(gg->Flags & GFLG_DISABLED) && (gg->Flags & GFLG_TABCYCLE)) prev = gg;
1111 gg = gg->NextGadget;
1114 if (gg && !g)
1116 /* There was no TABCYCLE gadget before gad in window's gadgetlist */
1118 gg = gg->NextGadget;
1119 if (!gg)
1121 if (!(gad->Flags & GFLG_DISABLED) && (gad->Flags & GFLG_TABCYCLE)) g = gad;
1122 break;
1124 prev = 0;
1126 while(gg)
1128 if (!(gg->Flags & GFLG_DISABLED) && (gg->Flags & GFLG_TABCYCLE)) prev = gg;
1129 gg = gg->NextGadget;
1132 if (prev)
1134 g = prev;
1136 else
1138 if (!(gad->Flags & GFLG_DISABLED) && (gad->Flags & GFLG_TABCYCLE)) g = gad;
1143 break;
1145 default: /* Unused, but well... */
1146 g = first;
1147 break;
1149 } /* switch(direction) */
1151 return g;
1154 /****************************************************************************************/
1156 void FixWindowCoords(struct Window *win, LONG *left, LONG *top, LONG *width, LONG *height,struct IntuitionBase *IntuitionBase)
1158 struct Screen *scr = win->WScreen;
1160 if (*width < 1) *width = 1;
1161 if (*height < 1) *height = 1;
1163 if (*width > scr->Width) *width = scr->Width;
1164 if (*height > scr->Height) *height = scr->Height;
1166 if ((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (win->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS))
1168 if (*left > scr->Width - 1) *left = scr->Width - 1;
1169 if (*top > scr->Height - 1) *top = scr->Height -1;
1171 else
1174 if ((*left + *width) > scr->Width)
1176 *left = scr->Width - *width;
1178 else if (*left < 0)
1180 *left = 0;
1183 if ((*top + *height) > scr->Height)
1185 *top = scr->Height - *height;
1187 else if (*top < 0)
1189 *top = 0;
1194 /****************************************************************************************/
1196 void WindowNeedsRefresh(struct Window * w,
1197 struct IntuitionBase * IntuitionBase )
1199 /* Supposed to send a message to this window, saying that it needs a
1200 refresh. I will check whether there is no such a message queued in
1201 its messageport, though. It only needs one such message!
1204 /* Refresh the window's gadgetry ...
1205 ... stegerg: and in the actual implementation
1206 call RefershWindowFrame first, as the border gadgets dont
1207 cover the whole border area.*/
1210 jDc: in actual implementation sizeevent means that we need to send
1211 idcmp, etc and do not clear the flag for smart_refresh window that
1212 has no idcmp_refreshwindow, otherwise we clear the flag!
1215 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: window 0x%lx gzz %d nocarerefresh %d\n",
1216 w, IS_GZZWINDOW(w), IS_NOCAREREFRESH(w)));
1218 //trashregion means that we use delayed refreshing!
1220 if (
1221 #ifdef DAMAGECACHE
1222 (!IW(w)->trashregion) ||
1223 #else
1224 (!(w->Flags & WFLG_SIMPLE_REFRESH)) ||
1225 #endif
1226 IS_NOCAREREFRESH(w))
1229 Gad_BeginUpdate(WLAYER(w), IntuitionBase);
1231 if (IS_NOCAREREFRESH(w) || (!((!(w->Flags & WFLG_SIMPLE_REFRESH)) && (!(IW(w)->specialflags & SPFLAG_LAYERRESIZED)))))
1233 if (!IS_GZZWINDOW(w))
1235 if (w->Flags & WFLG_BORDERLESS)
1237 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, 0, IntuitionBase);
1239 else
1241 int_refreshwindowframe(w,0,0,IntuitionBase);
1244 else
1246 /* refresh all gadgets except border gadgets */
1247 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, REFRESHGAD_BORDER, IntuitionBase);
1249 IW(w)->specialflags &= ~SPFLAG_LAYERRESIZED;
1252 if (IS_NOCAREREFRESH(w)) WLAYER(w)->Flags &= ~LAYERREFRESH;
1254 Gad_EndUpdate(WLAYER(w), IS_NOCAREREFRESH(w) ? TRUE : FALSE, IntuitionBase);
1256 } else {
1257 #ifdef DAMAGECACHE
1258 struct Rectangle rect;
1259 BOOL doclear = (w->Flags & WFLG_BORDERLESS) ? FALSE : TRUE;
1261 rect.MinX = w->BorderLeft;
1262 rect.MinY = w->BorderTop;
1263 rect.MaxX = w->Width - w->BorderRight - 1;
1264 rect.MaxY = w->Height - w->BorderBottom - 1;
1265 #endif
1267 #ifndef BEGINUPDATEGADGETREFRESH
1268 Gad_BeginUpdate(WLAYER(w), IntuitionBase);
1269 #else
1270 #ifdef DAMAGECACHE
1271 LockLayer(0,WLAYER(w));
1272 #endif
1273 #endif
1275 #ifndef BEGINUPDATEGADGETREFRESH
1276 if (!IS_GZZWINDOW(w))
1278 if (w->Flags & WFLG_BORDERLESS)
1280 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, 0, IntuitionBase);
1282 else
1284 int_refreshwindowframe(w,0,0,IntuitionBase);
1287 else
1289 /* refresh all gadgets except border and gadtools gadgets */
1290 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, REFRESHGAD_BORDER , IntuitionBase);
1292 #endif
1294 #ifdef DAMAGECACHE
1295 //add rects to trashregion here
1296 OrRegionRegion(WLAYER(w)->DamageList,IW(w)->trashregion);
1298 if (doclear)
1300 ClearRectRegion(IW(w)->trashregion,&rect);
1301 AndRectRegion(WLAYER(w)->DamageList,&rect);
1304 IW(w)->specialflags |= SPFLAG_LAYERREFRESH;
1305 #else
1306 #ifdef BEGINUPDATEGADGETREFRESH
1307 IW(w)->specialflags |= SPFLAG_LAYERREFRESH;
1308 #endif
1309 #endif
1311 #ifndef BEGINUPDATEGADGETREFRESH
1312 Gad_EndUpdate(WLAYER(w), FALSE, IntuitionBase);
1313 #else
1314 #ifdef DAMAGECACHE
1315 UnlockLayer(WLAYER(w));
1316 #endif
1317 #endif
1321 if (IS_DOCAREREFRESH(w))
1323 if (w->UserPort && (w->IDCMPFlags & IDCMP_REFRESHWINDOW))
1325 struct IntuiMessage *IM;
1326 BOOL found = FALSE;
1328 /* Can use Forbid() for this */
1329 Forbid();
1331 IM = (struct IntuiMessage *)w->UserPort->mp_MsgList.lh_Head;
1333 ForeachNode(&w->UserPort->mp_MsgList, IM)
1335 /* Does the window already have such a message? */
1336 if (IDCMP_REFRESHWINDOW == IM->Class && IM->IAddress == w)
1338 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: refresh pending\n"));
1339 D(bug("Window %s already has a refresh message pending!!\n",
1340 w->Title ? w->Title : (STRPTR)"<NONAME>"));
1341 found = TRUE;
1342 break;
1346 Permit();
1348 if (!found)
1350 struct InputEvent *new_ie;
1351 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
1353 D(bug("Sending a refresh message to window %s %d %d %d %d!!\n",
1354 w->Title ? w->Title : (STRPTR)"<NONAME>",
1355 w->LeftEdge,
1356 w->TopEdge,
1357 w->Width,
1358 w->Height));
1360 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: sending idcmp message\n"));
1362 if ((new_ie = AllocInputEvent(iihdata)))
1364 new_ie->ie_Class = IECLASS_EVENT;
1365 new_ie->ie_Code = IECODE_REFRESH;
1366 new_ie->ie_EventAddress = w;
1367 CurrentTime(&new_ie->ie_TimeStamp.tv_secs, &new_ie->ie_TimeStamp.tv_micro);
1370 fire_intuimessage(w,
1371 IDCMP_REFRESHWINDOW,
1374 IntuitionBase);
1375 } /* if (!found) */
1377 } /* if (w->UserPort && (w->IDCMPFlags & IDCMP_REFRESHWINDOW)) */
1378 else
1380 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
1382 if (FindTask(NULL) == iihdata->InputDeviceTask)
1384 struct InputEvent *new_ie;
1386 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: sending inputevent\n"));
1388 if ((new_ie = AllocInputEvent(iihdata)))
1390 new_ie->ie_Class = IECLASS_EVENT;
1391 new_ie->ie_Code = IECODE_REFRESH;
1392 new_ie->ie_EventAddress = w;
1393 CurrentTime(&new_ie->ie_TimeStamp.tv_secs, &new_ie->ie_TimeStamp.tv_micro);
1396 ih_fire_intuimessage(w,
1397 IDCMP_REFRESHWINDOW,
1400 IntuitionBase);
1404 } /* if (!IS_NOCAREREFRESH(w)) */
1408 /****************************************************************************************/
1410 struct Window *FindActiveWindow(struct InputEvent *ie,ULONG *stitlebarhit,
1411 struct IntuitionBase *IntuitionBase)
1413 /* The caller has checked that the input event is a IECLASS_RAWMOUSE, SELECTDOWN event */
1414 /* NOTE: may be called with NULL ie ptr! */
1415 struct Screen *scr;
1416 struct Layer *l;
1417 struct Window *new_w;
1418 ULONG lock;
1420 lock = LockIBase(0UL);
1422 new_w = IntuitionBase->ActiveWindow;
1423 scr = IntuitionBase->FirstScreen;
1425 UnlockIBase(lock);
1427 D(bug("FindActiveWindow: scr %p win %p\n",scr,new_w));
1429 if (stitlebarhit) *stitlebarhit = FALSE;
1431 if (scr)
1433 D(bug("FindActiveWindow: Click at (%d,%d)\n",scr->MouseX,scr->MouseY));
1435 /* What layer ? */
1436 LockLayerInfo(&scr->LayerInfo);
1438 l = WhichLayer(&scr->LayerInfo, scr->MouseX, scr->MouseY);
1440 UnlockLayerInfo(&scr->LayerInfo);
1442 if (NULL == l)
1444 new_w = NULL;
1445 D(bug("FindActiveWindow: Click not inside layer\n"));
1447 else if (l == scr->BarLayer)
1449 D(bug("FindActiveWindow: Click on screen bar layer -> active window stays the same\n"));
1450 if (stitlebarhit) *stitlebarhit = TRUE;
1452 else
1454 new_w = (struct Window *)l->Window;
1455 if (!new_w)
1457 D(bug("FindActiveWindow: Selected layer is not a window\n"));
1460 D(bug("FindActiveWindow: Found layer %p\n", l));
1464 D(bug("FindActiveWindow: New window %p\n", new_w));
1465 return new_w;
1468 /****************************************************************************************/
1470 struct Window *FindDesktopWindow(struct Screen *screen,struct IntuitionBase *IntuitionBase)
1472 struct Window *win;
1474 for (win = screen->FirstWindow; win; win = win->NextWindow)
1476 if (win->Flags & WFLG_BACKDROP &&
1477 win->Width == screen->Width &&
1478 win->Height >= screen->Height - (screen->BarHeight + 2))
1480 return win;
1484 return NULL;
1488 /****************************************************************************************/
1490 struct InputEvent *AllocInputEvent(struct IIHData *iihdata)
1492 struct IntuitionBase *IntuitionBase = iihdata->IntuitionBase;
1493 struct GeneratedInputEvent *gie;
1494 struct InputEvent *ie;
1496 /* There might be an inputevent from someone else that our handler discarded.
1497 * We may as well use it. This can only happen inside our main loop.
1499 ie = iihdata->FreeInputEvents;
1500 if (ie)
1502 iihdata->FreeInputEvents = ie->ie_NextEvent;
1503 DEBUG_INPUTEVENT(dprintf("AllocInputEvent: reuse 0x%lx event\n", ie));
1505 else
1507 gie = AllocPooled(iihdata->InputEventMemPool, sizeof(struct GeneratedInputEvent));
1508 if (gie)
1510 /* Allocated events are put in the list of events that have not yet been
1511 * propagated.
1513 AddTail((struct List *)&iihdata->NewAllocatedInputEventList, (struct Node *)gie);
1514 ie = &gie->ie;
1516 DEBUG_INPUTEVENT(dprintf("AllocInputEvent: allocated 0x%lx (0x%lx)\n", ie, gie));
1519 if (ie)
1521 *iihdata->EndInputEventChain = ie;
1522 iihdata->EndInputEventChain = &ie->ie_NextEvent;
1525 return ie;
1528 /****************************************************************************************/
1530 void FreeGeneratedInputEvents(struct IIHData *iihdata)
1532 struct IntuitionBase *IntuitionBase = iihdata->IntuitionBase;
1533 struct Node *node, *succ;
1535 /* Free the list of allocated events that have already been propagated. */
1536 ForeachNodeSafe(&iihdata->AllocatedInputEventList, node, succ)
1538 DEBUG_INPUTEVENT(dprintf("FreeGeneratedInputEvent: free 0x%lx\n", node));
1539 FreePooled(iihdata->InputEventMemPool, node, sizeof(struct GeneratedInputEvent));
1542 /* The list is not in a valid state at this point, and NewList() should
1543 * be called, but since we won't use it until the list of not-yet-propagated
1544 * events is copied in it, we won't bother.
1546 //NEWLIST(&iihdata->AllocatedInputEventList);
1549 /****************************************************************************************/
1551 BOOL FireMenuMessage(WORD code, struct Window *win,
1552 struct InputEvent *ie, struct IntuitionBase *IntuitionBase)
1554 struct MenuMessage *msg;
1555 BOOL result = FALSE;
1557 if ((msg = AllocMenuMessage(IntuitionBase)))
1559 msg->code = code;
1560 msg->win = win;
1561 if (ie) msg->ie = *ie;
1562 SendMenuMessage(msg, IntuitionBase);
1564 result = TRUE;
1567 return result;
1570 /****************************************************************************************/
1572 LONG Gad_BeginUpdate(struct Layer *layer, struct IntuitionBase *IntuitionBase)
1574 /* Must lock GadgetLock to avoid deadlocks with ObtainGirPort
1575 from other tasks, because ObtainGirPort first obtains
1576 GadgetLock and then layer lock through LockLayer!!!! */
1577 LOCKGADGET
1578 return BeginUpdate(layer);
1581 /****************************************************************************************/
1583 void Gad_EndUpdate(struct Layer *layer, UWORD flag, struct IntuitionBase *IntuitionBase)
1585 EndUpdate(layer, flag);
1586 UNLOCKGADGET
1589 /****************************************************************************************/