revert between 56095 -> 55830 in arch
[AROS.git] / rom / intuition / inputhandler_actions.c
blob0ba457653dc62f64e4c2e35a60fc025784670421
1 /*
2 Copyright 1995-2017, The AROS Development Team. All rights reserved.
3 Copyright 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
6 Responsible for executing deferred Intuition actions like MoveWindow,
7 SizeWindow, ActivateWindow, etc.
8 */
10 #include <proto/exec.h>
11 #include <proto/intuition.h>
12 #include <proto/alib.h>
13 #include <proto/layers.h>
14 #include <proto/graphics.h>
15 #include <proto/keymap.h>
16 #include <proto/input.h>
17 #include <exec/memory.h>
18 #include <exec/alerts.h>
19 #include <exec/interrupts.h>
20 #include <exec/ports.h>
21 #include <intuition/intuition.h>
22 #include <intuition/intuitionbase.h>
23 #include <intuition/gadgetclass.h>
24 #include <intuition/cghooks.h>
25 #include <intuition/sghooks.h>
26 #include <devices/input.h>
27 #include <devices/inputevent.h>
28 #include "inputhandler.h"
30 #include "boopsigadgets.h"
31 #include "boolgadgets.h"
32 #include "propgadgets.h"
33 #include "strgadgets.h"
34 #include "gadgets.h"
35 #include "intuition_intern.h" /* EWFLG_xxx */
36 #include "inputhandler_support.h"
37 #include "inputhandler_actions.h"
38 #include "menus.h"
40 #undef DEBUG
41 #define DEBUG 0
42 #include <aros/debug.h>
44 #define LOCK_ACTIONS() ObtainSemaphore(&GetPrivIBase(IntuitionBase)->IntuiActionLock);
45 #define UNLOCK_ACTIONS() ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->IntuiActionLock);
47 #ifndef __MORPHOS__
48 static void move_family(struct Window *, int , int);
49 #endif
51 /*******************************************************************************************************/
53 static void CheckLayerRefresh(struct Layer *lay, struct Screen *targetscreen,
54 struct IntuitionBase *IntuitionBase)
56 //if (lay->Flags & LAYERREFRESH)
58 struct Window *win = (struct Window *)lay->Window;
60 if (lay == targetscreen->BarLayer)
62 RenderScreenBar(targetscreen, TRUE, IntuitionBase);
64 else if (win)
66 /* Does it belong to a GZZ window and is it
67 the outer window of that GZZ window? */
68 if (IS_GZZWINDOW(win) && (lay == BLAYER(win)))
70 /* simply refresh that window's frame */
71 Gad_BeginUpdate(lay, IntuitionBase);
72 int_refreshwindowframe(win,REFRESHGAD_BORDER,0,IntuitionBase);
73 lay->Flags &= ~LAYERREFRESH;
74 Gad_EndUpdate(lay, TRUE, IntuitionBase);
76 /* Is it the window layer ? */
77 else if (lay == WLAYER(win))
79 WindowNeedsRefresh(win, IntuitionBase);
81 /* Otherwise, it's a requester. */
82 else
84 struct Requester *req;
86 for (req = win->FirstRequest; req && req->ReqLayer != lay; req = req->OlderRequest);
88 if (req)
90 /* FIXME: should send an IDCMP refresh message too. */
91 Gad_BeginUpdate(lay, IntuitionBase);
92 render_requester(req, IntuitionBase);
93 lay->Flags &= ~LAYERREFRESH;
94 Gad_EndUpdate(lay, TRUE, IntuitionBase);
99 } /* if (lay->Flags & LAYERREFRESH) */
102 /*******************************************************************************************************/
104 void CheckLayers(struct Screen *screen, struct IntuitionBase *IntuitionBase)
106 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
107 struct Layer *L;
109 LOCK_REFRESH(screen);
111 for (L = screen->LayerInfo.top_layer; L; L = L->back)
113 if (L->Flags & LAYERREFRESH)
115 CheckLayerRefresh(L, screen, IntuitionBase);
119 UNLOCK_REFRESH(screen);
122 void WindowSizeWillChange(struct Window *targetwindow, WORD dx, WORD dy,
123 struct IntuitionBase *IntuitionBase)
125 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
126 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
127 struct Rectangle *clipto = NULL;
128 struct Rectangle final_innerrect;
130 /* Erase the old frame on the right/lower side if
131 new size is bigger than old size
134 D(bug("********* WindowSizeWillChange ******** dx = %d dy = %d\n", dx, dy));
136 if (AVOID_WINBORDERERASE(IntuitionBase))
138 final_innerrect.MinX = targetwindow->BorderLeft;
139 final_innerrect.MinY = targetwindow->BorderTop;
140 final_innerrect.MaxX = targetwindow->Width + dx - 1 - targetwindow->BorderRight;
141 final_innerrect.MaxY = targetwindow->Height + dy - 1 - targetwindow->BorderBottom;
142 clipto = &final_innerrect;
145 if ( ((dx > 0) && (targetwindow->BorderRight > 0)) ||
146 ((dy > 0) && (targetwindow->BorderBottom > 0)) )
148 struct RastPort *rp = targetwindow->BorderRPort;
149 struct Layer *L = (BLAYER(targetwindow)) ? BLAYER(targetwindow) : WLAYER(targetwindow);
150 struct Rectangle rect;
151 struct Region *oldclipregion;
152 WORD ScrollX;
153 WORD ScrollY;
156 ** In case a clip region is installed then I have to
157 ** install the regular cliprects of the layer
158 ** first. Otherwise the frame might not get cleared correctly.
161 LockLayer(0, L);
163 oldclipregion = InstallClipRegion(L, NULL);
165 ScrollX = L->Scroll_X;
166 ScrollY = L->Scroll_Y;
168 L->Scroll_X = 0;
169 L->Scroll_Y = 0;
171 if ((dx > 0) && (targetwindow->BorderRight > 0))
173 rect.MinX = targetwindow->Width - targetwindow->BorderRight;
174 rect.MinY = 0;
175 rect.MaxX = targetwindow->Width - 1;
176 rect.MaxY = targetwindow->Height - 1;
178 OrRectRegion(L->DamageList, &rect);
179 L->Flags |= LAYERREFRESH;
181 if (!AVOID_WINBORDERERASE(IntuitionBase) || AndRectRect(&rect, &final_innerrect, &rect))
183 EraseRect(rp, rect.MinX, rect.MinY, rect.MaxX, rect.MaxY);
188 if ((dy > 0) && (targetwindow->BorderBottom > 0))
191 rect.MinX = 0;
192 rect.MinY = targetwindow->Height - targetwindow->BorderBottom;
193 rect.MaxX = targetwindow->Width - 1;
194 rect.MaxY = targetwindow->Height - 1;
196 OrRectRegion(L->DamageList, &rect);
197 L->Flags |= LAYERREFRESH;
199 if (!AVOID_WINBORDERERASE(IntuitionBase) || AndRectRect(&rect, &final_innerrect, &rect))
201 EraseRect(rp, rect.MinX, rect.MinY, rect.MaxX, rect.MaxY);
207 ** Reinstall the clipregions rectangles if there are any.
209 if (NULL != oldclipregion)
211 InstallClipRegion(L, oldclipregion);
214 L->Scroll_X = ScrollX;
215 L->Scroll_Y = ScrollY;
217 UnlockLayer(L);
219 } /* if ( ((dx > 0) && (targetwindow->BorderRight > 0)) || ((dy > 0) && (targetwindow->BorderBottom > 0)) ) */
221 /* Before resizing the layers eraserect the area of all
222 GFLG_REL??? gadgets and add the area to the damagelist */
224 EraseRelGadgetArea(targetwindow, clipto, FALSE, IntuitionBase);
228 /*******************************************************************************************************/
230 void WindowSizeHasChanged(struct Window *targetwindow, WORD dx, WORD dy,
231 BOOL is_sizewindow, struct IntuitionBase *IntuitionBase)
233 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
234 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
235 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
236 struct Layer *lay;
238 D(bug("********* WindowSizeHasChanged ********\n"));
240 lay = (BLAYER(targetwindow)) ? BLAYER(targetwindow) : WLAYER(targetwindow);
242 /* Fix GadgetInfo domain if there is an active gadget in window
243 which was resized */
245 if ((iihdata->ActiveGadget) && (targetwindow == iihdata->GadgetInfo.gi_Window))
247 /* In case of active window drag/size gadget the master drag/size gadget never
248 has GZZ flag set, so pass in real gadget (ActiveSysGadget) */
250 GetGadgetDomain(iihdata->ActiveSysGadget ? iihdata->ActiveSysGadget : iihdata->ActiveGadget,
251 iihdata->GadgetInfo.gi_Screen,
252 iihdata->GadgetInfo.gi_Window,
253 NULL,
254 &iihdata->GadgetInfo.gi_Domain);
257 /* Relayout GFLG_REL??? gadgets */
258 DoGMLayout(targetwindow->FirstGadget, targetwindow, NULL, -1, FALSE, IntuitionBase);
260 /* Add the new area of all GFLG_REL??? gadgets to the damagelist, but
261 don't EraseRect() as the gadgets will be re-rendered at their new
262 position anyway */
265 struct Rectangle innerrect;
267 innerrect.MinX = targetwindow->BorderLeft;
268 innerrect.MinY = targetwindow->BorderTop;
269 innerrect.MaxX = targetwindow->Width - 1 - targetwindow->BorderRight;
270 innerrect.MaxY = targetwindow->Height - 1 - targetwindow->BorderBottom;
272 EraseRelGadgetArea(
273 targetwindow,
274 AVOID_WINBORDERERASE(IntuitionBase) ? &innerrect : NULL,
275 TRUE, IntuitionBase
279 /* If new size is smaller than old size add right/bottom
280 frame to damagelist */
281 if ( ((dx < 0) && (targetwindow->BorderRight > 0)) ||
282 ((dx > 0) && (targetwindow->BorderTop > 0)) ||
283 ((dy < 0) && (targetwindow->BorderBottom > 0)) )
285 struct Rectangle rect;
287 LockLayer(0, lay);
289 if ((dx < 0) && (targetwindow->BorderRight > 0))
291 rect.MinX = targetwindow->Width - targetwindow->BorderRight;
292 rect.MinY = 0;
293 rect.MaxX = targetwindow->Width - 1;
294 rect.MaxY = targetwindow->Height - 1;
296 OrRectRegion(lay->DamageList, &rect);
297 lay->Flags |= LAYERREFRESH;
300 if ((dx > 0) && (targetwindow->BorderTop > 0))
302 rect.MinX = 0;
303 rect.MinY = 0;
304 rect.MaxX = targetwindow->Width - 1;
305 rect.MaxY = targetwindow->BorderTop - 1;
307 OrRectRegion(lay->DamageList, &rect);
308 lay->Flags |= LAYERREFRESH;
311 if ((dy < 0) && (targetwindow->BorderBottom > 0))
313 rect.MinX = 0;
314 rect.MinY = targetwindow->Height - targetwindow->BorderBottom;
315 rect.MaxX = targetwindow->Width - 1;
316 rect.MaxY = targetwindow->Height - 1;
318 OrRectRegion(lay->DamageList, &rect);
319 lay->Flags |= LAYERREFRESH;
322 UnlockLayer(lay);
324 } /* if ( ((dx < 0) && (targetwindow->BorderRight > 0)) || ((dy < 0) && (targetwindow->BorderBottom > 0)) ) */
326 ((struct IntWindow *)(targetwindow))->specialflags |= SPFLAG_LAYERRESIZED;
328 #if 0
329 if (IS_GZZWINDOW(targetwindow))
331 lay = targetwindow->BorderRPort->Layer;
333 if (lay->Flags & LAYERREFRESH)
335 Gad_BeginUpdate(lay, IntuitionBase);
336 RefreshWindowFrame(targetwindow);
337 lay->Flags &= ~LAYERREFRESH;
338 Gad_EndUpdate(lay, TRUE, IntuitionBase);
341 lay = targetwindow->WLayer;
343 if (lay->Flags & LAYERREFRESH)
345 Gad_BeginUpdate(lay, IntuitionBase);
346 int_refreshglist(targetwindow->FirstGadget, targetwindow, NULL, -1, 0, REFRESHGAD_BORDER, IntuitionBase);
347 Gad_EndUpdate(lay, IS_NOCAREREFRESH(targetwindow), IntuitionBase);
351 else
353 lay = targetwindow->WLayer;
355 if (lay->Flags & LAYERREFRESH)
357 Gad_BeginUpdate(lay, IntuitionBase);
358 RefreshWindowFrame(targetwindow);
359 int_refreshglist(targetwindow->FirstGadget, targetwindow, NULL, -1, 0, REFRESHGAD_BORDER, IntuitionBase);
360 Gad_EndUpdate(lay, IS_NOCAREREFRESH(targetwindow), IntuitionBase);
364 lay = targetwindow->WLayer;
366 if (IS_NOCAREREFRESH(targetwindow))
368 LockLayer(0, lay);
369 lay->Flags &= ~LAYERREFRESH;
370 UnlockLayer(lay);
372 #endif
374 #if 0
375 //if (is_sizewindow)
377 /* Send IDCMP_NEWSIZE to resized window */
379 ih_fire_intuimessage(targetwindow,
380 IDCMP_NEWSIZE,
382 targetwindow,
383 IntuitionBase);
386 if (ie = AllocInputEvent(iihdata))
388 ie->ie_Class = IECLASS_EVENT;
389 ie->ie_Code = IECODE_NEWSIZE;
390 ie->ie_EventAddress = targetwindow;
391 CurrentTime(&ie->ie_TimeStamp.tv_secs, &ie->ie_TimeStamp.tv_micro);
394 /* Send IDCMP_CHANGEWINDOW to resized window */
396 ih_fire_intuimessage(targetwindow,
397 IDCMP_CHANGEWINDOW,
398 CWCODE_MOVESIZE,
399 targetwindow,
400 IntuitionBase);
401 #endif
405 /*******************************************************************************************************/
407 void DoMoveSizeWindow(struct Window *targetwindow, LONG NewLeftEdge, LONG NewTopEdge,
408 LONG NewWidth, LONG NewHeight, BOOL send_newsize, struct IntuitionBase *IntuitionBase)
410 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
411 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
412 //struct IntWindow *w = (struct IntWindow *)targetwindow;
413 struct Layer *targetlayer = WLAYER(targetwindow)/*, *L*/;
414 struct Requester *req;
415 struct InputEvent *ie;
416 LONG OldLeftEdge = targetwindow->LeftEdge;
417 LONG OldTopEdge = targetwindow->TopEdge;
418 LONG OldWidth = targetwindow->Width;
419 LONG OldHeight = targetwindow->Height;
420 LONG pos_dx, pos_dy, size_dx, size_dy;
422 /* correct new window coords if necessary */
424 FixWindowCoords(targetwindow, &NewLeftEdge, &NewTopEdge, &NewWidth, &NewHeight,IntuitionBase);
426 D(bug("DoMoveSizeWindow to %d,%d %d x %d\n", NewLeftEdge, NewTopEdge, NewWidth, NewHeight));
428 pos_dx = NewLeftEdge - OldLeftEdge;
429 pos_dy = NewTopEdge - OldTopEdge;
430 size_dx = NewWidth - OldWidth;
431 size_dy = NewHeight - OldHeight;
433 LOCK_REFRESH(targetwindow->WScreen);
435 /* jDc: intuition 68k doesn't care about that */
436 // if (pos_dx || pos_dy || size_dx || size_dy)
437 // {
439 if (size_dx || size_dy)
441 WindowSizeWillChange(targetwindow, size_dx, size_dy, IntuitionBase);
444 targetwindow->LeftEdge += pos_dx;
445 targetwindow->TopEdge += pos_dy;
446 #ifndef __MORPHOS__
447 targetwindow->RelLeftEdge += pos_dx;
448 targetwindow->RelTopEdge += pos_dy;
449 #endif
451 targetwindow->Width = NewWidth;
452 targetwindow->Height = NewHeight;
453 targetwindow->GZZWidth = targetwindow->Width - targetwindow->BorderLeft - targetwindow->BorderRight;
454 targetwindow->GZZHeight = targetwindow->Height - targetwindow->BorderTop - targetwindow->BorderBottom;
456 /* check for GZZ window */
457 if (BLAYER(targetwindow))
459 /* move outer window first */
460 MoveSizeLayer(BLAYER(targetwindow), pos_dx, pos_dy, size_dx, size_dy);
463 MoveSizeLayer(targetlayer, pos_dx, pos_dy, size_dx, size_dy);
465 for (req = targetwindow->FirstRequest; req; req = req->OlderRequest)
467 struct Layer *layer = req->ReqLayer;
469 if (layer)
471 int dx, dy, dw, dh;
472 int left, top, right, bottom;
474 left = NewLeftEdge + req->LeftEdge;
475 top = NewTopEdge + req->TopEdge;
476 right = left + req->Width - 1;
477 bottom = top + req->Height - 1;
479 if (left > NewLeftEdge + NewWidth - 1)
480 left = NewLeftEdge + NewWidth - 1;
482 if (top > NewTopEdge + NewHeight - 1)
483 top = NewTopEdge + NewHeight - 1;
485 if (right > NewLeftEdge + NewWidth - 1)
486 right = NewLeftEdge + NewWidth - 1;
488 if (bottom > NewTopEdge + NewHeight - 1)
489 bottom = NewTopEdge + NewHeight - 1;
491 dx = left - layer->bounds.MinX;
492 dy = top - layer->bounds.MinY;
493 dw = right - left - layer->bounds.MaxX + layer->bounds.MinX;
494 dh = bottom - top - layer->bounds.MaxY + layer->bounds.MinY;
496 MoveSizeLayer(layer, dx, dy, dw, dh);
500 #if 0
501 if (w->ZipLeftEdge != ~0) w->ZipLeftEdge = OldLeftEdge;
502 if (w->ZipTopEdge != ~0) w->ZipTopEdge = OldTopEdge;
503 if (w->ZipWidth != ~0) w->ZipWidth = OldWidth;
504 if (w->ZipHeight != ~0) w->ZipHeight = OldHeight;
505 #endif
507 if (pos_dx || pos_dy)
509 UpdateMouseCoords(targetwindow);
510 #ifndef __MORPHOS__
511 if (HAS_CHILDREN(targetwindow))
512 move_family(targetwindow, pos_dx, pos_dy);
513 #endif
516 // } /* if (pos_dx || pos_dy || size_dx || size_dy) */
518 if (size_dx || size_dy)
520 WindowSizeHasChanged(targetwindow, size_dx, size_dy, FALSE, IntuitionBase);
523 ih_fire_intuimessage(targetwindow,
524 IDCMP_CHANGEWINDOW,
525 CWCODE_MOVESIZE,
526 targetwindow,
527 IntuitionBase);
529 if (send_newsize)
531 /* Send IDCMP_NEWSIZE and IDCMP_CHANGEWINDOW to resized window, even
532 if there was no resizing/position change at all. BGUI for example
533 relies on this! */
535 ih_fire_intuimessage(targetwindow,
536 IDCMP_NEWSIZE,
538 targetwindow,
539 IntuitionBase);
541 if ((ie = AllocInputEvent(iihdata)))
543 ie->ie_Class = IECLASS_EVENT;
544 ie->ie_Code = IECODE_NEWSIZE;
545 ie->ie_EventAddress = targetwindow;
546 CurrentTime(&ie->ie_TimeStamp.tv_secs, &ie->ie_TimeStamp.tv_micro);
550 // jDc: CheckLayers calls LOCK_REFRESH, so there's no reason to UNLOCK here!
551 // UNLOCK_REFRESH(targetwindow->WScreen);
553 CheckLayers(targetwindow->WScreen, IntuitionBase);
555 UNLOCK_REFRESH(targetwindow->WScreen);
557 #if 0
558 if (size_dx || size_dy)
560 if (!(((struct IntWindow *)targetwindow)->CustomShape))
562 struct wdpWindowShape shapemsg;
563 struct Region *shape;
564 shapemsg.MethodID = WDM_WINDOWSHAPE;
565 shapemsg.wdp_Width = targetwindow->Width;
566 shapemsg.wdp_Height = targetwindow->Height;
567 shapemsg.wdp_Window = targetwindow;
568 shapemsg.wdp_TrueColor = (((struct IntScreen *)targetwindow->WScreen)->DInfo.dri.dri_Flags & DRIF_DIRECTCOLOR);
569 shapemsg.wdp_UserBuffer = ((struct IntWindow *)targetwindow)->DecorUserBuffer;
570 shape = DoMethodA(((struct IntScreen *)(targetwindow->WScreen))->WinDecorObj, (Msg)&shapemsg);
572 if (((struct IntWindow *)targetwindow)->OutlineShape) DisposeRegion(((struct IntWindow *)targetwindow)->OutlineShape);
573 ((struct IntWindow *)targetwindow)->OutlineShape = shape;
574 ChangeWindowShape(targetwindow, shape, NULL);
575 ((struct IntWindow *)targetwindow)->CustomShape = FALSE;
578 #endif
582 /*******************************************************************************************************/
584 void DoSyncAction(void (*func)(struct IntuiActionMsg *, struct IntuitionBase *),
585 struct IntuiActionMsg *msg,
586 struct IntuitionBase *IntuitionBase)
588 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
589 struct Task *me = FindTask(NULL);
591 if (me == iihd->InputDeviceTask)
593 func(msg, IntuitionBase);
595 else
597 struct IOStdReq req;
598 struct MsgPort *port = CreateMsgPort();
599 struct InputEvent ie;
601 if (port)
603 msg->handler = func;
604 msg->task = me;
605 msg->done = FALSE;
607 // Free MsgPort's signal - we will be using SIGB_INTUITION
608 FreeSignal(port->mp_SigBit);
610 ObtainSemaphore(&GetPrivIBase(IntuitionBase)->IntuiActionLock);
611 AddTail((struct List *)GetPrivIBase(IntuitionBase)->IntuiActionQueue, (struct Node *)msg);
612 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->IntuiActionLock);
614 port->mp_SigTask = me;
615 port->mp_SigBit = SIGB_INTUITION;
617 req.io_Message.mn_ReplyPort = port;
618 req.io_Device = GetPrivIBase(IntuitionBase)->InputIO->io_Device;
619 req.io_Unit = GetPrivIBase(IntuitionBase)->InputIO->io_Unit;
620 req.io_Command = IND_WRITEEVENT;
621 req.io_Length = sizeof(ie);
622 req.io_Data = &ie;
624 ie.ie_Class = IECLASS_NULL;
626 if (!msg->done)
628 DoIO((APTR)&req);
629 while (!msg->done)
631 Wait(SIGF_INTUITION);
634 // Set mp_SigBit to -1 so that exec does not free SIGB_INTUITION
635 port->mp_SigBit = -1;
636 DeleteMsgPort(port);
641 /*******************************************************************************************************/
643 BOOL DoASyncAction(void (*func)(struct IntuiActionMsg *, struct IntuitionBase *),
644 struct IntuiActionMsg *msg, ULONG size,
645 struct IntuitionBase *IntuitionBase)
647 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
648 struct Task *me = FindTask(NULL);
649 struct IntuiActionMsg *new_msg;
651 if (me == iihd->InputDeviceTask)
653 func(msg, IntuitionBase);
654 return TRUE;
656 else if ((new_msg = AllocVecPooled(iihd->ActionsMemPool,size)))
658 new_msg->handler = func;
659 new_msg->task = NULL;
660 if (size > sizeof(*msg))
662 CopyMem(msg + 1, new_msg + 1, size - sizeof(*msg));
665 ObtainSemaphore(&GetPrivIBase(IntuitionBase)->IntuiActionLock);
666 AddTail((struct List *)GetPrivIBase(IntuitionBase)->IntuiActionQueue, (struct Node *)new_msg);
667 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->IntuiActionLock);
669 return TRUE;
671 else
673 return FALSE;
677 /*******************************************************************************************************/
679 void HandleIntuiActions(struct IIHData *iihdata,
680 struct IntuitionBase *IntuitionBase)
682 struct IntuiActionMsg *am;
684 D(bug("Handle Intuition action messages\n"));
686 if (iihdata->ActiveSysGadget)
688 D(bug("Handle Intuition action messages. Doing nothing because of active drag or resize gadget!\n"));
689 return;
692 for (;;)
694 LOCK_ACTIONS();
695 am = (struct IntuiActionMsg *)RemHead((struct List *)&iihdata->IntuiActionQueue);
696 UNLOCK_ACTIONS();
698 if (!am)
699 break;
701 am->handler(am, IntuitionBase);
703 if (am->task)
705 Forbid();
706 am->done = TRUE;
707 Signal(am->task, SIGF_INTUITION);
708 Permit();
710 else
712 FreeVecPooled(iihdata->ActionsMemPool,am);
716 D(bug("Intuition action messages handled\n"));
719 #ifndef __MORPHOS__
720 static void move_family(struct Window * w, int dx, int dy)
722 struct Window * _w = w->firstchild;
724 while (_w)
726 _w->LeftEdge += dx,
727 _w->TopEdge += dy;
728 if (HAS_CHILDREN(_w))
729 move_family(_w,dx,dy);
730 _w=_w->nextchild;
733 #endif