fix properties
[AROS.git] / rom / intuition / inputhandler_support.c
bloba5a655a8cf3035c7d3f6a2d8d461b4f76d76c28e
1 /*
2 Copyright 1995-2010, 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) ;
55 #define DEBUG_CLICK(x)
57 #include <stddef.h>
59 /****************************************************************************************/
62 All screens and windows on active monitor will be updated with the current position of
63 the mouse pointer. Windows will receive relative mouse coordinates.
66 /****************************************************************************************/
68 void notify_mousemove_screensandwindows(struct IntuitionBase * IntuitionBase)
70 LONG lock = LockIBase(0);
71 struct Screen *scr = IntuitionBase->FirstScreen;
73 for (scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen)
75 struct Window *win;
77 /* Ignore screens which are not on our current monitor */
78 if (GetPrivScreen(scr)->MonitorObject != GetPrivIBase(IntuitionBase)->ActiveMonitor)
79 continue;
81 scr->MouseX = IntuitionBase->MouseX - scr->LeftEdge;
82 scr->MouseY = IntuitionBase->MouseY - scr->TopEdge;
85 ** Visit all windows of this screen
87 win = scr->FirstWindow;
89 while (NULL != win)
91 UpdateMouseCoords(win);
93 win = win -> NextWindow;
97 UnlockIBase(lock);
100 /****************************************************************************************/
102 void send_intuimessage(struct IntuiMessage *imsg, struct Window *w,
103 struct IntuitionBase *IntuitionBase)
105 SendIntuiMessage(w, imsg);
108 /****************************************************************************************/
110 void free_intuimessage(struct IntuiMessage *imsg,
111 struct IntuitionBase *IntuitionBase)
113 FreeIntuiMessage(imsg);
116 /****************************************************************************************/
118 struct IntuiMessage *alloc_intuimessage(struct Window *w,
119 struct IntuitionBase *IntuitionBase)
121 struct IntuiMessage *imsg;
123 imsg = AllocIntuiMessage(w);
124 if (imsg)
126 if (w)
128 if (w->IDCMPFlags & IDCMP_DELTAMOVE)
130 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
132 imsg->MouseX = iihd->DeltaMouseX;
133 imsg->MouseY = iihd->DeltaMouseY;
135 else
137 imsg->MouseX = w->MouseX;
138 imsg->MouseY = w->MouseY;
141 CurrentTime(&imsg->Seconds, &imsg->Micros);
144 return imsg;
147 /****************************************************************************************/
149 BOOL fire_intuimessage(struct Window *w,
150 ULONG Class,
151 UWORD Code,
152 APTR IAddress,
153 struct IntuitionBase *IntuitionBase)
155 struct IntuiMessage *imsg;
156 BOOL result = FALSE;
158 if ((w->IDCMPFlags & Class) && (w->UserPort))
160 if ((imsg = alloc_intuimessage(w, IntuitionBase)))
162 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
164 imsg->Class = Class;
165 imsg->Code = Code;
166 imsg->Qualifier = iihd->ActQualifier;
167 if (Class == IDCMP_RAWKEY)
169 INT_INTUIMESSAGE(imsg)->prevCodeQuals = IAddress;
170 imsg->IAddress = &INT_INTUIMESSAGE(imsg)->prevCodeQuals;
172 else
174 imsg->IAddress = IAddress;
177 send_intuimessage(imsg, w, IntuitionBase);
179 result = TRUE;
181 else
183 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: can't alloc imsg\n"));
186 else
188 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: no Userport or masked out idcmpflags\n"));
191 return result;
194 BOOL fire_message(struct Window *w,ULONG Class, UWORD Code, APTR IAddress, struct IntuitionBase *IntuitionBase)
196 struct ExtIntuiMessage *imsg;
197 BOOL result = FALSE;
199 if ((w->IDCMPFlags & Class) && (w->UserPort))
201 if ((imsg = (struct ExtIntuiMessage *)alloc_intuimessage(w, IntuitionBase)))
203 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
205 imsg->eim_IntuiMessage.Class = Class;
206 imsg->eim_IntuiMessage.Code = Code;
207 imsg->eim_IntuiMessage.Qualifier = iihdata->ActQualifier;
208 if (Class == IDCMP_RAWKEY)
210 INT_INTUIMESSAGE(imsg)->prevCodeQuals = IAddress;
211 imsg->eim_IntuiMessage.IAddress = &INT_INTUIMESSAGE(imsg)->prevCodeQuals;
213 else
215 imsg->eim_IntuiMessage.IAddress = IAddress;
218 if (iihdata->ActEventTablet && (w->MoreFlags & WMFLG_TABLETMESSAGES))
220 if ((imsg->eim_TabletData = AllocPooled(GetPrivIBase(IntuitionBase)->IDCMPPool,sizeof (struct TabletData))))
222 memclr(imsg->eim_TabletData,sizeof (struct TabletData));
223 imsg->eim_TabletData->td_XFraction = iihdata->ActEventTablet->ient_ScaledXFraction;
224 imsg->eim_TabletData->td_YFraction = iihdata->ActEventTablet->ient_ScaledYFraction;
225 imsg->eim_TabletData->td_TabletX = iihdata->ActEventTablet->ient_TabletX;
226 imsg->eim_TabletData->td_TabletY = iihdata->ActEventTablet->ient_TabletY;
227 imsg->eim_TabletData->td_RangeX = iihdata->ActEventTablet->ient_RangeX;
228 imsg->eim_TabletData->td_RangeY = iihdata->ActEventTablet->ient_RangeY;
229 imsg->eim_TabletData->td_TagList = CloneTagItems(iihdata->ActEventTablet->ient_TagList);
233 send_intuimessage(imsg, w, IntuitionBase);
235 result = TRUE;
237 else
239 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: can't alloc imsg\n"));
242 else
244 DEBUG_FIREINTUIMSG(dprintf("fire_intuimessage: no Userport or masked out idcmpflags\n"));
247 return result;
250 /****************************************************************************************/
253 use ih_fire_intuimessage if A) the inputevent because of which
254 you call this function might have to be eaten or modified
255 by Intuition or B) an inputevent might have to be created
256 by Intuition because of a deferred action.
258 In any case this function may be called only from inside Intuition's
259 InputHandler!!!!!!
262 /****************************************************************************************/
264 BOOL ih_fire_intuimessage(struct Window * w,
265 ULONG Class,
266 UWORD Code,
267 APTR IAddress,
268 struct IntuitionBase *IntuitionBase)
270 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
271 struct InputEvent *ie/* = iihd->ActInputEvent*/;
273 BOOL result;
275 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: win 0x%lx class 0x%lx code 0x%lx IAddress 0x%lx\n",
277 Class,
278 Code,
279 IAddress));
281 result = fire_message(w, Class, Code, IAddress, IntuitionBase);
283 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: fire_intuimessage result 0x%lx\n",
284 result));
286 if (result /*&& ie*/)
288 /* was sent as IDCMP to window so eat inputevent */
290 //ie->ie_Class = IECLASS_NULL;
294 #if 0
295 else if (ie/* && (ie->ie_Class != IECLASS_NULL) && !iihd->ActInputEventUsed*/)
298 /* ih_fire_intuimessage was called from inside Intuition's event handling loop */
300 //iihd->ActInputEventUsed = TRUE;
302 ie->ie_SubClass = 0;
303 ie->ie_Code = Code;
304 //ie->ie_Qualifier = iihd->ActQualifier;
305 ie->ie_EventAddress = IAddress;
307 switch(Class)
309 case IDCMP_GADGETUP:
310 /* Note: on the Amiga if a boopsi Gadget which is GA_Immediate
311 and GA_RelVerify immediately in GM_GOACTIVE returns GMR_VERIFY,
312 then this sends IDCMP_GADGETDOWN + IDCMP_GADGETUP. AROS does
313 the same. But for changed inputevents (if window does not have this
314 IDCMP Flags set) there will be only one IECLASS_GADGETDOWN
317 ie->ie_Class = IECLASS_GADGETUP;
318 break;
320 case IDCMP_GADGETDOWN:
321 ie->ie_Class = IECLASS_GADGETDOWN;
322 break;
324 case IDCMP_ACTIVEWINDOW:
325 ie->ie_Class = IECLASS_ACTIVEWINDOW;
326 break;
328 case IDCMP_INACTIVEWINDOW:
329 ie->ie_Class = IECLASS_INACTIVEWINDOW;
330 break;
332 case IDCMP_CLOSEWINDOW:
333 ie->ie_Class = IECLASS_CLOSEWINDOW;
334 break;
336 case IDCMP_MENUHELP:
337 ie->ie_Class = IECLASS_MENUHELP;
338 break;
340 case IDCMP_MENUPICK:
341 ie->ie_Class = IECLASS_MENULIST;
342 break;
344 case IDCMP_MOUSEBUTTONS:
345 case IDCMP_MOUSEMOVE:
346 case IDCMP_RAWKEY:
347 case IDCMP_VANILLAKEY:
348 break;
350 default:
351 D(bug("ih_fireintuimessage: unexpected IDCMP (%x) for an inputevent-handling-fireintuimessage!\n", Class));
352 break;
356 #endif
357 else //if (!ie)
359 /* ih_fire_intuimessage was called from inside Intuition's defered action handling routines */
361 if ((ie = AllocInputEvent(iihd)))
363 switch(Class)
365 case IDCMP_NEWSIZE:
366 ie->ie_Class = IECLASS_SIZEWINDOW;
367 break;
369 case IDCMP_CHANGEWINDOW:
370 ie->ie_Class = IECLASS_CHANGEWINDOW;
371 break;
373 case IDCMP_ACTIVEWINDOW:
374 ie->ie_Class = IECLASS_ACTIVEWINDOW;
375 break;
377 case IDCMP_INACTIVEWINDOW:
378 ie->ie_Class = IECLASS_INACTIVEWINDOW;
379 break;
381 case IDCMP_CLOSEWINDOW:
382 ie->ie_Class = IECLASS_CLOSEWINDOW;
383 break;
385 case IDCMP_GADGETUP:
386 ie->ie_Class = IECLASS_GADGETUP;
387 break;
389 case IDCMP_GADGETDOWN:
390 ie->ie_Class = IECLASS_GADGETDOWN;
391 break;
393 case IDCMP_REFRESHWINDOW:
394 ie->ie_Class = IECLASS_REFRESHWINDOW;
395 break;
397 case IDCMP_MENUHELP:
398 ie->ie_Class = IECLASS_MENUHELP;
399 break;
401 case IDCMP_MENUPICK:
402 ie->ie_Class = IECLASS_MENULIST;
403 break;
405 default:
406 D(bug("ih_fireintuimessage: unexpected IDCMP (0x%X) for a deferred-action-fireintuimessage!\n", Class));
407 break;
409 } /* switch(Class) */
411 ie->ie_Code = Code;
412 ie->ie_Qualifier = iihd->ActQualifier;
413 ie->ie_EventAddress = IAddress;
414 CurrentTime(&ie->ie_TimeStamp.tv_secs, &ie->ie_TimeStamp.tv_micro);
416 D(bug("ih_fireintuimessage: generated InputEvent. Class = 0x%X Code = %d EventAddress = 0x%X\n",
417 ie->ie_Class,
418 ie->ie_Code,
419 ie->ie_EventAddress));
421 } /* if ((ie = AllocInputEvent(iihd))) */
424 DEBUG_FIREINTUIMSG(dprintf("ih_fire_intuimessage: result 0x%lx\n",
425 result));
427 return result;
430 /*********************************************************************/
432 /* This function must never be called with the layer/layerinfo locked,
433 * otherwise a deadlock with ObtainGIRPort can happen.
435 IPTR Locked_DoMethodA (struct Window *w, struct Gadget *g, Msg message, struct IntuitionBase *IntuitionBase)
437 IPTR rc;
438 BOOL lock = w && (g->GadgetType & GTYP_SYSGADGET &&
439 ((g->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDRAGGING ||
440 (g->GadgetType & GTYP_SYSTYPEMASK) == GTYP_SIZING));
442 if (lock)
444 LOCK_REFRESH(w->WScreen);
447 LOCKGADGET
448 rc = Custom_DoMethodA(g, message);
449 UNLOCKGADGET
451 if (lock)
453 UNLOCK_REFRESH(w->WScreen);
456 return rc;
459 /*********************************************************************/
461 #undef Custom_DoMethodA
462 IPTR Custom_DoMethodA (struct IntuitionBase *IntuitionBase, struct Gadget *g, Msg message)
464 if (g->MutualExclude)
466 return AROS_UFC4(IPTR, ((struct Hook *)g->MutualExclude)->h_Entry,
467 AROS_UFCA(struct Hook *, (struct Hook *)g->MutualExclude, A0),
468 AROS_UFCA(struct Gadget *, g, A2),
469 AROS_UFCA(APTR, message, A1),
470 AROS_UFCA(struct IntuitionBase *, IntuitionBase, A6));
472 else /* Not needed since gadgetclass sets MutualExclude, but doesn't hurt. */
473 return DoMethodA((Object *)g, message);
476 /****************************************************************************************/
478 void NotifyDepthArrangement(struct Window *w, struct IntuitionBase *IntuitionBase)
480 if(w->MoreFlags & WMFLG_NOTIFYDEPTH)
482 ih_fire_intuimessage(w,
483 IDCMP_CHANGEWINDOW,
484 CWCODE_DEPTH,
486 IntuitionBase);
491 /****************************************************************************************/
493 void PrepareGadgetInfo(struct GadgetInfo *gi, struct Screen *scr, struct Window *win,
494 struct Requester *req)
496 gi->gi_Screen = scr;
497 gi->gi_Window = win;
498 gi->gi_Requester = req;
499 gi->gi_RastPort = 0;
500 gi->gi_Pens.DetailPen = scr->DetailPen;
501 gi->gi_Pens.BlockPen = scr->BlockPen;
502 gi->gi_DrInfo = (APTR)&(((struct IntScreen *)gi->gi_Screen)->DInfo);
505 /****************************************************************************************/
507 void SetGadgetInfoGadget(struct GadgetInfo *gi, struct Gadget *gad,
508 struct IntuitionBase *IntuitionBase)
510 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
512 SET_GI_RPORT(gi, gi->gi_Window, gi->gi_Requester, gad);
513 InitRastPort(&iihd->GadgetInfoRastPort);
515 iihd->GadgetInfoRastPort.Layer = gi->gi_RastPort->Layer;
516 iihd->GadgetInfoRastPort.BitMap = gi->gi_RastPort->BitMap;
518 SetFont(&iihd->GadgetInfoRastPort, gi->gi_DrInfo->dri_Font);
520 gi->gi_Layer = gi->gi_RastPort->Layer;
521 gi->gi_RastPort = &iihd->GadgetInfoRastPort;
523 GetGadgetDomain(gad, gi->gi_Screen, gi->gi_Window, gi->gi_Requester, &gi->gi_Domain);
526 /****************************************************************************************/
528 void SetGPIMouseCoords(struct gpInput *gpi, struct Gadget *gad)
530 struct GadgetInfo *gi = gpi->gpi_GInfo;
532 WORD mousex, mousey;
534 if (IS_SCREEN_GADGET(gad) || !gi->gi_Window)
536 mousex = gi->gi_Screen->MouseX;
537 mousey = gi->gi_Screen->MouseY;
539 else
542 mousex = gi->gi_Window->MouseX;
543 mousey = gi->gi_Window->MouseY;
546 gpi->gpi_Mouse.X = mousex - gi->gi_Domain.Left - GetGadgetLeft(gad, gi->gi_Screen, gi->gi_Window, gi->gi_Requester);
547 gpi->gpi_Mouse.Y = mousey - gi->gi_Domain.Top - GetGadgetTop(gad, gi->gi_Screen, gi->gi_Window, gi->gi_Requester);
551 /****************************************************************************************/
553 void HandleSysGadgetVerify(struct GadgetInfo *gi, struct Gadget *gadget,
554 struct IntuitionBase *IntuitionBase)
556 struct Screen *scr;
558 switch(gadget->GadgetType & GTYP_SYSTYPEMASK)
560 case GTYP_CLOSE:
561 #ifdef __MORPHOS__
562 if (((struct IntWindow *)(gi->gi_Window))->specialflags & SPFLAG_IAMDEAD)
564 CrashedDispose(gi->gi_Window,IntuitionBase);
566 else
568 #endif
569 ih_fire_intuimessage(gi->gi_Window,
570 IDCMP_CLOSEWINDOW,
572 gi->gi_Window,
573 IntuitionBase);
574 #ifdef __MORPHOS__
576 #endif
577 break;
579 case GTYP_WDEPTH:
580 if (!IsLayerHiddenBySibling(WLAYER(gi->gi_Window), FALSE))
582 /* Send window to back */
583 WindowToBack(gi->gi_Window);
585 else
587 /* Send window to front */
588 WindowToFront(gi->gi_Window);
590 break;
592 case GTYP_WZOOM:
593 ZipWindow(gi->gi_Window);
594 break;
596 case GTYP_SDEPTH:
597 scr = FindFirstScreen(GetPrivIBase(IntuitionBase)->ActiveMonitor, IntuitionBase);
598 if (gi->gi_Screen == scr)
600 ScreenToBack(gi->gi_Screen);
602 else
604 ScreenToFront(gi->gi_Screen);
606 break;
608 } /* switch(gad->GadgetType & GTYP_SYSTYPEMASK) */
611 /****************************************************************************************/
613 struct Gadget *HandleCustomGadgetRetVal(IPTR retval, struct GadgetInfo *gi, struct Gadget *gadget,
614 ULONG termination, BOOL *reuse_event,
615 struct IntuitionBase *IntuitionBase)
617 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
619 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: retval %ld gi 0x%lx gadget 0x%lx termination %ld reuse %ld\n",
620 retval,
622 gadget,
623 termination,
624 *reuse_event));
626 if (retval != GMR_MEACTIVE)
628 struct gpGoInactive gpgi;
630 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: !GMR_MEACTIVE\n"));
632 if (retval & GMR_REUSE)
634 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: GMR_REUSE\n"));
635 *reuse_event = TRUE;
638 if (retval & GMR_VERIFY)
640 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: GMR_VERIFY\n"));
641 if (IS_SYS_GADGET(gadget))
643 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: SysGad\n"));
644 HandleSysGadgetVerify(gi, gadget, IntuitionBase);
646 else
648 /* Not a system gadget. Send IDCMP_GADGETUP, but not
649 if it is a screen gadget where gi->gi_Window would
650 be NULL */
652 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: no sysgad\n"));
653 if ((gadget->Activation & GACT_RELVERIFY) &&
654 (gi->gi_Window))
656 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: Send IDCMP_GADGETUP\n"));
657 ih_fire_intuimessage(gi->gi_Window,
658 IDCMP_GADGETUP,
659 termination & 0x0000FFFF,
660 gadget,
661 IntuitionBase);
664 } /* switch(gad->GadgetType & GTYP_SYSTYPEMASK) */
666 } /* if (retval & GMR_VERIFY) */
668 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: Send GM_GOINACTIVE\n"));
670 gpgi.MethodID = GM_GOINACTIVE;
671 gpgi.gpgi_GInfo = gi;
672 gpgi.gpgi_Abort = 0;
674 Locked_DoMethodA(gi->gi_Window, gadget, (Msg)&gpgi, IntuitionBase);
676 if (SYSGADGET_ACTIVE)
678 /* Switch back from Master Drag or Size Gadget to
679 real/original/app Size or Drag Gadget */
681 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: SYSGADGET_ACTIVE\n"));
682 gadget = iihdata->ActiveSysGadget;
683 iihdata->ActiveSysGadget = NULL;
685 if (IS_BOOPSI_GADGET(gadget))
687 Locked_DoMethodA(gi->gi_Window, gadget, (Msg)&gpgi, IntuitionBase);
690 #ifdef __MORPHOS__
691 if ((gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDRAGGING2)
693 ih_fire_intuimessage(gi->gi_Window,
694 IDCMP_GADGETUP,
696 gadget,
697 IntuitionBase);
699 #endif
701 retval = 0;
704 if (retval & GMR_VERIFY && gi->gi_Requester && gadget->Activation & GACT_ENDGADGET)
706 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: EndRequest\n"));
707 EndRequest(gi->gi_Requester, gi->gi_Window);
708 retval = 0;
711 gadget->Activation &= ~GACT_ACTIVEGADGET;
713 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle 0x%lx retval 0x%lx\n",
714 (gadget->Flags & GFLG_TABCYCLE),
715 retval));
717 if ((gadget->Flags & GFLG_TABCYCLE) && (retval & GMR_NEXTACTIVE))
719 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle+GMR_NEXTACTIVE\n"));
720 gadget = FindCycleGadget(gi->gi_Window, gi->gi_Requester, gadget, GMR_NEXTACTIVE);
722 else if ((gadget->Flags & GFLG_TABCYCLE) && (retval & GMR_PREVACTIVE))
724 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: TabCycle+GMR_PREVACTIVE\n"));
725 gadget = FindCycleGadget(gi->gi_Window, gi->gi_Requester, gadget, GMR_PREVACTIVE);
727 else
729 gadget = NULL;
730 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: No gadget\n"));
733 if (gadget)
735 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: activate gadget 0x%lx\n",gadget));
736 gadget = DoActivateGadget(gi->gi_Window, gi->gi_Requester, gadget, IntuitionBase);
739 } /* if (retval != GMR_MEACTIVE) */
740 else
742 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: set GACT_ACTIVEGADGET\n"));
743 gadget->Activation |= GACT_ACTIVEGADGET;
746 DEBUG_HANDLECUSTOMRETVAL(dprintf("HandleCustomGadgetRetVal: return 0x%x\n", gadget));
747 return gadget;
750 /****************************************************************************************/
752 /* This function must never be called with the layer/layerinfo locked,
753 * otherwise a deadlock with ObtainGIRPort can happen.
755 struct Gadget *DoGPInput(struct GadgetInfo *gi, struct Gadget *gadget,
756 struct InputEvent *ie, STACKULONG methodid,
757 BOOL *reuse_event, struct IntuitionBase *IntuitionBase)
759 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
760 struct gpInput gpi;
761 IPTR retval;
762 ULONG termination;
763 ie->ie_Qualifier = iihdata->ActQualifier;
765 gpi.MethodID = methodid;
766 gpi.gpi_GInfo = gi;
767 gpi.gpi_IEvent = ie;
768 gpi.gpi_Termination = &termination;
769 gpi.gpi_TabletData = NULL;
771 SetGPIMouseCoords(&gpi, gadget);
773 retval = Locked_DoMethodA (gi->gi_Window, gadget, (Msg)&gpi, IntuitionBase);
775 DEBUG_DOGPINPUT(dprintf("DoGPInput: Locked_DoMethod gadget %p method 0x%lx retval %ld termination 0x%lx\n",
776 gadget, methodid, retval, termination));
778 return HandleCustomGadgetRetVal(retval, gi, gadget, termination,
779 reuse_event, IntuitionBase);
783 /****************************************************************************************/
785 struct Gadget * FindGadget (struct Screen *scr, struct Window * window,
786 struct Requester * req, int x, int y,
787 struct GadgetInfo * gi,BOOL sysonly,
788 struct IntuitionBase *IntuitionBase)
790 struct Gadget *gadget, *firstgadget, *draggadget = 0;
791 struct gpHitTest gpht;
792 struct IBox ibox;
793 WORD xrel, yrel;
794 BOOL sys_only = sysonly;
796 DEBUG_CLICK(bug("[Inputhandler] FindGadget(0x%p, 0x%p, 0x%p, %d, %d, %d)\n", scr, window, req, x, y, sysonly));
797 gpht.MethodID = GM_HITTEST;
798 gpht.gpht_GInfo = gi;
800 while (req || window || scr)
802 if (req)
804 firstgadget = req->ReqGadget;
806 else if (window)
808 firstgadget = window->FirstGadget;
810 else
812 if (draggadget) return draggadget;
813 firstgadget = scr->FirstGadget;
816 for (gadget = firstgadget; gadget; gadget = gadget->NextGadget)
818 if (!(gadget->Flags & GFLG_DISABLED) &&
819 (!sys_only ||
820 (gadget->GadgetType & GTYP_SYSGADGET &&
821 ((gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_SIZING ||
822 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDRAGGING ||
823 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDEPTH ||
824 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_SDEPTH ||
825 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WZOOM ||
826 (gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_CLOSE))))
828 /* stegerg: domain depends on gadgettype and windowflags! */
829 GetGadgetDomain(gadget, scr, window, req, &gi->gi_Domain);
831 /* Get coords relative to window */
833 GetGadgetIBox(gadget, gi, &ibox);
835 xrel = x - gi->gi_Domain.Left;
836 yrel = y - gi->gi_Domain.Top;
838 /*if (req)
840 xrel -= req->LeftEdge + window->BorderLeft;
841 yrel -= req->TopEdge + window->BorderTop;
844 if (window)
846 xrel -= window->LeftEdge;
847 yrel -= window->TopEdge;
850 if ((xrel >= ibox.Left) &&
851 (yrel >= ibox.Top) &&
852 (xrel < ibox.Left + ibox.Width) &&
853 (yrel < ibox.Top + ibox.Height))
855 if ((gadget->GadgetType & GTYP_SYSTYPEMASK) == GTYP_WDRAGGING)
857 if (!draggadget) draggadget = gadget;
859 else
862 if ((gadget->GadgetType & GTYP_GTYPEMASK) == GTYP_CUSTOMGADGET)
865 gpht.gpht_Mouse.X = xrel - ibox.Left;
866 gpht.gpht_Mouse.Y = yrel - ibox.Top;
868 /* jDc: don't check for == GMR_GADGETHIT since some reaction classes*/
869 /* (BURN IN HELL!) return TRUE here (related to imageclass HITEST?)*/
870 if (Locked_DoMethodA (window, gadget, (Msg)&gpht, IntuitionBase))
871 return (gadget);
873 else
875 return (gadget);
880 } /* if (!(gadget->Flags & GFLG_DISABLED)) */
882 } /* for (gadget = window->FirstGadget; gadget; gadget = gadget->NextGadget) */
884 sys_only = sysonly;
886 if (req)
888 req = NULL;
889 sys_only = TRUE;
891 else if (window)
893 #ifdef SKINS
894 draggadget = findbordergadget(window,draggadget,IntuitionBase);
895 #endif
896 window = NULL;
898 else
899 scr = NULL;
902 return (draggadget);
904 } /* FindGadget */
907 /****************************************************************************************/
909 struct Gadget * FindHelpGadget (struct Window * window,
910 int x, int y, struct IntuitionBase *IntuitionBase)
912 struct Gadget *gadget, *firstgadget;
913 struct Requester *req = window->FirstRequest;
915 while (req || window)
917 if (req)
919 firstgadget = req->ReqGadget;
921 else
923 firstgadget = window->FirstGadget;
926 for (gadget = firstgadget; gadget; gadget = gadget->NextGadget)
928 if ((gadget->Flags & GFLG_EXTENDED) &&
929 (((struct ExtGadget *)gadget)->MoreFlags & GMORE_GADGETHELP))
931 if (InsideGadget(window->WScreen, window, req, gadget, x, y))
933 return (gadget);
939 if (req)
940 req = req->OlderRequest;
941 else
942 window = NULL;
945 return (NULL);
947 } /* FindGadget */
950 /****************************************************************************************/
952 BOOL InsideGadget(struct Screen *scr, struct Window *win, struct Requester *req,
953 struct Gadget *gad, WORD x, WORD y)
955 struct IBox box;
956 BOOL rc = FALSE;
958 GetScrGadgetIBox(gad, scr, win, req, &box);
960 if ((x >= box.Left) &&
961 (y >= box.Top) &&
962 (x < box.Left + box.Width) &&
963 (y < box.Top + box.Height))
965 rc = TRUE;
968 return rc;
971 /****************************************************************************************/
973 struct Gadget *DoActivateGadget(struct Window *win, struct Requester *req, struct Gadget *gad,
974 struct IntuitionBase *IntuitionBase)
976 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
977 struct GadgetInfo *gi = &iihd->GadgetInfo;
978 struct Gadget *result = NULL;
980 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Window 0x%lx Req 0x%lx Gadget 0x%lx\n",
981 win,
982 req,
983 gad));
985 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Activation 0x%lx\n",
986 gad->Activation));
988 if (gad->Activation & GACT_IMMEDIATE)
990 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Send GADGETDOWN msg\n"));
991 ih_fire_intuimessage(win,
992 IDCMP_GADGETDOWN,
994 gad,
995 IntuitionBase);
998 PrepareGadgetInfo(gi, win->WScreen, win, req);
999 SetGadgetInfoGadget(gi, gad, IntuitionBase);
1001 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: Type 0x%lx\n",
1002 gad->GadgetType & GTYP_GTYPEMASK));
1004 switch(gad->GadgetType & GTYP_GTYPEMASK)
1006 case GTYP_STRGADGET:
1008 struct StringInfo *si = (struct StringInfo *)gad->SpecialInfo;
1010 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: GTYP_STRGADGET\n"));
1012 gad->Flags |= GFLG_SELECTED;
1013 if (si && si->UndoBuffer)
1015 strcpy(si->UndoBuffer, si->Buffer);
1018 gad->Activation |= GACT_ACTIVEGADGET;
1019 UpdateStrGadget(gad, win, req, IntuitionBase);
1020 result = gad;
1021 break;
1024 case GTYP_CUSTOMGADGET:
1026 struct gpInput gpi;
1027 ULONG termination;
1028 IPTR retval;
1029 BOOL reuse_event;
1031 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: GTYP_CUSTOMGADGET\n"));
1033 gpi.MethodID = GM_GOACTIVE;
1034 gpi.gpi_GInfo = gi;
1035 gpi.gpi_IEvent = NULL;
1036 gpi.gpi_Termination = &termination;
1037 gpi.gpi_Mouse.X = win->MouseX - gi->gi_Domain.Left - GetGadgetLeft(gad, gi->gi_Screen, gi->gi_Window, NULL);
1038 gpi.gpi_Mouse.Y = win->MouseY - gi->gi_Domain.Top - GetGadgetTop(gad, gi->gi_Screen, gi->gi_Window, NULL);
1039 gpi.gpi_TabletData = NULL;
1041 retval = Locked_DoMethodA (win, gad, (Msg)&gpi, IntuitionBase);
1043 gad = HandleCustomGadgetRetVal(retval, gi, gad,termination,
1044 &reuse_event, IntuitionBase);
1046 if (gad)
1048 gad->Activation |= GACT_ACTIVEGADGET;
1049 result = gad;
1051 break;
1054 } /* switch(gad->GadgetType & GTYP_GTYPEMASK) */
1056 DEBUG_ACTIVATEGADGET(dprintf("DoActivateGadget: result 0x%lx\n",
1057 result));
1059 if (result) iihd->ActiveGadget = result;
1061 return result;
1065 /****************************************************************************************/
1067 struct Gadget *FindCycleGadget(struct Window *win, struct Requester *req,
1068 struct Gadget *gad, WORD direction)
1070 struct Gadget *g = NULL, *gg, *prev, *first;
1072 D(bug("FindCycleGadget: win = %p req %p gad = %p direction = %d\n", win, req, gad, direction));
1074 if (req)
1075 first = req->ReqGadget;
1076 else
1077 first = win->FirstGadget;
1079 switch(direction)
1081 case GMR_NEXTACTIVE:
1082 g = gad->NextGadget;
1083 if (!g) g = first;
1085 while(g)
1087 if (g == gad)
1089 if (!(gad->Flags & GFLG_TABCYCLE) || (gad->Flags & GFLG_DISABLED))
1091 /* should never happen */
1092 g = NULL;
1094 break;
1096 if (!(g->Flags & GFLG_DISABLED) && (g->Flags & GFLG_TABCYCLE)) break;
1098 g = g->NextGadget;
1099 if (!g) g = first;
1101 break;
1103 case GMR_PREVACTIVE:
1104 prev = 0;
1105 g = 0;
1106 gg = first;
1108 /* find a TABCYCLE gadget which is before gad in window's gadgetlist */
1109 while (gg)
1111 if (gg == gad)
1113 if (prev) g = prev;
1114 break;
1116 if (!(gg->Flags & GFLG_DISABLED) && (gg->Flags & GFLG_TABCYCLE)) prev = gg;
1117 gg = gg->NextGadget;
1120 if (gg && !g)
1122 /* There was no TABCYCLE gadget before gad in window's gadgetlist */
1124 gg = gg->NextGadget;
1125 if (!gg)
1127 if (!(gad->Flags & GFLG_DISABLED) && (gad->Flags & GFLG_TABCYCLE)) g = gad;
1128 break;
1130 prev = 0;
1132 while(gg)
1134 if (!(gg->Flags & GFLG_DISABLED) && (gg->Flags & GFLG_TABCYCLE)) prev = gg;
1135 gg = gg->NextGadget;
1138 if (prev)
1140 g = prev;
1142 else
1144 if (!(gad->Flags & GFLG_DISABLED) && (gad->Flags & GFLG_TABCYCLE)) g = gad;
1149 break;
1151 default: /* Unused, but well... */
1152 g = first;
1153 break;
1155 } /* switch(direction) */
1157 return g;
1160 /****************************************************************************************/
1162 void FixWindowCoords(struct Window *win, LONG *left, LONG *top, LONG *width, LONG *height,struct IntuitionBase *IntuitionBase)
1164 struct Screen *scr = win->WScreen;
1166 if (*width < 1) *width = 1;
1167 if (*height < 1) *height = 1;
1169 if (*width > scr->Width) *width = scr->Width;
1170 if (*height > scr->Height) *height = scr->Height;
1172 if ((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (win->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS))
1174 if (*left > scr->Width - 1) *left = scr->Width - 1;
1175 if (*top > scr->Height - 1) *top = scr->Height -1;
1177 else
1180 if ((*left + *width) > scr->Width)
1182 *left = scr->Width - *width;
1184 else if (*left < 0)
1186 *left = 0;
1189 if ((*top + *height) > scr->Height)
1191 *top = scr->Height - *height;
1193 else if (*top < 0)
1195 *top = 0;
1200 /****************************************************************************************/
1202 void WindowNeedsRefresh(struct Window * w,
1203 struct IntuitionBase * IntuitionBase )
1205 /* Supposed to send a message to this window, saying that it needs a
1206 refresh. I will check whether there is no such a message queued in
1207 its messageport, though. It only needs one such message!
1210 /* Refresh the window's gadgetry ...
1211 ... stegerg: and in the actual implementation
1212 call RefershWindowFrame first, as the border gadgets dont
1213 cover the whole border area.*/
1216 jDc: in actual implementation sizeevent means that we need to send
1217 idcmp, etc and do not clear the flag for smart_refresh window that
1218 has no idcmp_refreshwindow, otherwise we clear the flag!
1221 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: window 0x%lx gzz %d nocarerefresh %d\n",
1222 w, IS_GZZWINDOW(w), IS_NOCAREREFRESH(w)));
1224 //trashregion means that we use delayed refreshing!
1226 if (
1227 #ifdef DAMAGECACHE
1228 (!IW(w)->trashregion) ||
1229 #else
1230 (!(w->Flags & WFLG_SIMPLE_REFRESH)) ||
1231 #endif
1232 IS_NOCAREREFRESH(w))
1235 Gad_BeginUpdate(WLAYER(w), IntuitionBase);
1237 if (IS_NOCAREREFRESH(w) || (!((!(w->Flags & WFLG_SIMPLE_REFRESH)) && (!(IW(w)->specialflags & SPFLAG_LAYERRESIZED)))))
1239 if (!IS_GZZWINDOW(w))
1241 if (w->Flags & WFLG_BORDERLESS)
1243 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, 0, IntuitionBase);
1245 else
1247 int_refreshwindowframe(w,0,0,IntuitionBase);
1250 else
1252 /* refresh all gadgets except border gadgets */
1253 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, REFRESHGAD_BORDER, IntuitionBase);
1255 IW(w)->specialflags &= ~SPFLAG_LAYERRESIZED;
1258 if (IS_NOCAREREFRESH(w)) WLAYER(w)->Flags &= ~LAYERREFRESH;
1260 Gad_EndUpdate(WLAYER(w), IS_NOCAREREFRESH(w) ? TRUE : FALSE, IntuitionBase);
1262 } else {
1263 #ifdef DAMAGECACHE
1264 struct Rectangle rect;
1265 BOOL doclear = (w->Flags & WFLG_BORDERLESS) ? FALSE : TRUE;
1267 rect.MinX = w->BorderLeft;
1268 rect.MinY = w->BorderTop;
1269 rect.MaxX = w->Width - w->BorderRight - 1;
1270 rect.MaxY = w->Height - w->BorderBottom - 1;
1271 #endif
1273 #ifndef BEGINUPDATEGADGETREFRESH
1274 Gad_BeginUpdate(WLAYER(w), IntuitionBase);
1275 #else
1276 #ifdef DAMAGECACHE
1277 LockLayer(0,WLAYER(w));
1278 #endif
1279 #endif
1281 #ifndef BEGINUPDATEGADGETREFRESH
1282 if (!IS_GZZWINDOW(w))
1284 if (w->Flags & WFLG_BORDERLESS)
1286 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, 0, IntuitionBase);
1288 else
1290 int_refreshwindowframe(w,0,0,IntuitionBase);
1293 else
1295 /* refresh all gadgets except border and gadtools gadgets */
1296 int_refreshglist(w->FirstGadget, w, NULL, -1, 0, REFRESHGAD_BORDER , IntuitionBase);
1298 #endif
1300 #ifdef DAMAGECACHE
1301 //add rects to trashregion here
1302 OrRegionRegion(WLAYER(w)->DamageList,IW(w)->trashregion);
1304 if (doclear)
1306 ClearRectRegion(IW(w)->trashregion,&rect);
1307 AndRectRegion(WLAYER(w)->DamageList,&rect);
1310 IW(w)->specialflags |= SPFLAG_LAYERREFRESH;
1311 #else
1312 #ifdef BEGINUPDATEGADGETREFRESH
1313 IW(w)->specialflags |= SPFLAG_LAYERREFRESH;
1314 #endif
1315 #endif
1317 #ifndef BEGINUPDATEGADGETREFRESH
1318 Gad_EndUpdate(WLAYER(w), FALSE, IntuitionBase);
1319 #else
1320 #ifdef DAMAGECACHE
1321 UnlockLayer(WLAYER(w));
1322 #endif
1323 #endif
1327 if (IS_DOCAREREFRESH(w))
1329 if (w->UserPort && (w->IDCMPFlags & IDCMP_REFRESHWINDOW))
1331 struct IntuiMessage *IM;
1332 BOOL found = FALSE;
1334 /* Can use Forbid() for this */
1335 Forbid();
1337 IM = (struct IntuiMessage *)w->UserPort->mp_MsgList.lh_Head;
1339 ForeachNode(&w->UserPort->mp_MsgList, IM)
1341 /* Does the window already have such a message? */
1342 if (IDCMP_REFRESHWINDOW == IM->Class && IM->IAddress == w)
1344 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: refresh pending\n"));
1345 D(bug("Window %s already has a refresh message pending!!\n",
1346 w->Title ? w->Title : (STRPTR)"<NONAME>"));
1347 found = TRUE;
1348 break;
1352 Permit();
1354 if (!found)
1356 struct InputEvent *new_ie;
1357 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
1359 D(bug("Sending a refresh message to window %s %d %d %d %d!!\n",
1360 w->Title ? w->Title : (STRPTR)"<NONAME>",
1361 w->LeftEdge,
1362 w->TopEdge,
1363 w->Width,
1364 w->Height));
1366 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: sending idcmp message\n"));
1368 if ((new_ie = AllocInputEvent(iihdata)))
1370 new_ie->ie_Class = IECLASS_EVENT;
1371 new_ie->ie_Code = IECODE_REFRESH;
1372 new_ie->ie_EventAddress = w;
1373 CurrentTime(&new_ie->ie_TimeStamp.tv_secs, &new_ie->ie_TimeStamp.tv_micro);
1376 fire_intuimessage(w,
1377 IDCMP_REFRESHWINDOW,
1380 IntuitionBase);
1381 } /* if (!found) */
1383 } /* if (w->UserPort && (w->IDCMPFlags & IDCMP_REFRESHWINDOW)) */
1384 else
1386 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
1388 if (FindTask(NULL) == iihdata->InputDeviceTask)
1390 struct InputEvent *new_ie;
1392 DEBUG_WINDOWNEEDSREFRESH(dprintf("WindowNeedsRefresh: sending inputevent\n"));
1394 if ((new_ie = AllocInputEvent(iihdata)))
1396 new_ie->ie_Class = IECLASS_EVENT;
1397 new_ie->ie_Code = IECODE_REFRESH;
1398 new_ie->ie_EventAddress = w;
1399 CurrentTime(&new_ie->ie_TimeStamp.tv_secs, &new_ie->ie_TimeStamp.tv_micro);
1402 ih_fire_intuimessage(w,
1403 IDCMP_REFRESHWINDOW,
1406 IntuitionBase);
1410 } /* if (!IS_NOCAREREFRESH(w)) */
1414 /****************************************************************************************/
1416 struct Screen *FindActiveScreen(struct IntuitionBase *IntuitionBase)
1418 struct Screen *scr;
1420 for (scr = IntuitionBase->FirstScreen; scr; scr = scr->NextScreen) {
1421 /* We check only screens which are on this monitor */
1422 if (GetPrivScreen(scr)->MonitorObject != GetPrivIBase(IntuitionBase)->ActiveMonitor)
1423 continue;
1425 /* If the mouse is inside screen's bitmap, we found it */
1426 if ((scr->MouseX >= 0) && (scr->MouseY >= 0) &&
1427 ((scr->MouseX < scr->Width) && scr->MouseY < scr->Height))
1428 break;
1430 return scr;
1433 /****************************************************************************************/
1435 struct Window *FindActiveWindow(struct InputEvent *ie, struct Screen *scr, ULONG *stitlebarhit,
1436 struct IntuitionBase *IntuitionBase)
1438 /* The caller has checked that the input event is a IECLASS_RAWMOUSE, SELECTDOWN event */
1439 /* NOTE: may be called with NULL ie ptr! */
1440 struct Layer *l;
1441 struct Window *new_w;
1442 ULONG lock;
1444 lock = LockIBase(0UL);
1446 new_w = IntuitionBase->ActiveWindow;
1448 UnlockIBase(lock);
1450 D(bug("FindActiveWindow: scr %p win %p\n",scr,new_w));
1452 if (stitlebarhit) *stitlebarhit = FALSE;
1454 if (scr)
1456 D(bug("FindActiveWindow: Click at (%d,%d)\n",scr->MouseX,scr->MouseY));
1458 /* What layer ? */
1459 LockLayerInfo(&scr->LayerInfo);
1461 l = WhichLayer(&scr->LayerInfo, scr->MouseX, scr->MouseY);
1463 UnlockLayerInfo(&scr->LayerInfo);
1465 if (NULL == l)
1467 new_w = NULL;
1468 D(bug("FindActiveWindow: Click not inside layer\n"));
1470 else if (l == scr->BarLayer)
1472 D(bug("FindActiveWindow: Click on screen bar layer -> active window stays the same\n"));
1473 if (stitlebarhit) *stitlebarhit = TRUE;
1475 else
1477 new_w = (struct Window *)l->Window;
1478 if (!new_w)
1480 D(bug("FindActiveWindow: Selected layer is not a window\n"));
1483 D(bug("FindActiveWindow: Found layer %p\n", l));
1487 D(bug("FindActiveWindow: New window %p\n", new_w));
1488 return new_w;
1491 /****************************************************************************************/
1493 struct Window *FindDesktopWindow(struct Screen *screen,struct IntuitionBase *IntuitionBase)
1495 struct Window *win;
1497 for (win = screen->FirstWindow; win; win = win->NextWindow)
1499 if (win->Flags & WFLG_BACKDROP &&
1500 win->Width == screen->Width &&
1501 win->Height >= screen->Height - (screen->BarHeight + 2))
1503 return win;
1507 return NULL;
1511 /****************************************************************************************/
1513 struct InputEvent *AllocInputEvent(struct IIHData *iihdata)
1515 struct IntuitionBase *IntuitionBase = iihdata->IntuitionBase;
1516 struct GeneratedInputEvent *gie;
1517 struct InputEvent *ie;
1519 /* There might be an inputevent from someone else that our handler discarded.
1520 * We may as well use it. This can only happen inside our main loop.
1522 ie = iihdata->FreeInputEvents;
1523 if (ie)
1525 iihdata->FreeInputEvents = ie->ie_NextEvent;
1526 DEBUG_INPUTEVENT(dprintf("AllocInputEvent: reuse 0x%lx event\n", ie));
1528 else
1530 gie = AllocPooled(iihdata->InputEventMemPool, sizeof(struct GeneratedInputEvent));
1531 if (gie)
1533 /* Allocated events are put in the list of events that have not yet been
1534 * propagated.
1536 AddTail((struct List *)&iihdata->NewAllocatedInputEventList, (struct Node *)gie);
1537 ie = &gie->ie;
1539 DEBUG_INPUTEVENT(dprintf("AllocInputEvent: allocated 0x%lx (0x%lx)\n", ie, gie));
1542 if (ie)
1544 *iihdata->EndInputEventChain = ie;
1545 iihdata->EndInputEventChain = &ie->ie_NextEvent;
1548 return ie;
1551 /****************************************************************************************/
1553 void FreeGeneratedInputEvents(struct IIHData *iihdata)
1555 struct IntuitionBase *IntuitionBase = iihdata->IntuitionBase;
1556 struct Node *node, *succ;
1558 /* Free the list of allocated events that have already been propagated. */
1559 ForeachNodeSafe(&iihdata->AllocatedInputEventList, node, succ)
1561 DEBUG_INPUTEVENT(dprintf("FreeGeneratedInputEvent: free 0x%lx\n", node));
1562 FreePooled(iihdata->InputEventMemPool, node, sizeof(struct GeneratedInputEvent));
1565 /* The list is not in a valid state at this point, and NewList() should
1566 * be called, but since we won't use it until the list of not-yet-propagated
1567 * events is copied in it, we won't bother.
1569 //NEWLIST(&iihdata->AllocatedInputEventList);
1572 /****************************************************************************************/
1574 BOOL FireMenuMessage(WORD code, struct Window *win,
1575 struct InputEvent *ie, struct IntuitionBase *IntuitionBase)
1577 struct MenuMessage *msg;
1578 BOOL result = FALSE;
1580 if ((msg = AllocMenuMessage(IntuitionBase)))
1582 msg->code = code;
1583 msg->win = win;
1584 if (ie) msg->ie = *ie;
1585 SendMenuMessage(msg, IntuitionBase);
1587 result = TRUE;
1590 return result;
1593 /****************************************************************************************/
1595 LONG Gad_BeginUpdate(struct Layer *layer, struct IntuitionBase *IntuitionBase)
1597 /* Must lock GadgetLock to avoid deadlocks with ObtainGirPort
1598 from other tasks, because ObtainGirPort first obtains
1599 GadgetLock and then layer lock through LockLayer!!!! */
1600 LOCKGADGET
1601 return BeginUpdate(layer);
1604 /****************************************************************************************/
1606 void Gad_EndUpdate(struct Layer *layer, UWORD flag, struct IntuitionBase *IntuitionBase)
1608 EndUpdate(layer, flag);
1609 UNLOCKGADGET
1612 /****************************************************************************************/