Minor fixes to comments.
[AROS.git] / rom / intuition / windowclasses.c
blob1b93d4ad26910209cd8a7d8c64713b3b233d80e0
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
6 Classes for window decor stuff, like dragbar, close etc.
7 */
9 /***********************************************************************************/
11 #include <string.h>
13 #include <proto/exec.h>
14 #include <proto/intuition.h>
15 #include <proto/graphics.h>
16 #include <proto/utility.h>
17 #include <proto/layers.h>
19 #include <intuition/classes.h>
20 #include <intuition/gadgetclass.h>
21 #include <intuition/cghooks.h>
22 #include <intuition/imageclass.h>
23 #include <intuition/extensions.h>
24 #include <aros/asmcall.h>
26 #include "gadgets.h"
28 #include "intuition_intern.h"
29 #include "inputhandler.h"
30 #include "inputhandler_support.h"
31 #include "inputhandler_actions.h"
33 #ifdef SKINS
34 #include "intuition_customizesupport.h"
35 #include "renderwindowframe.h"
36 #include "mosmisc.h"
37 #endif
39 #undef SDEBUG
40 #undef DEBUG
41 #define SDEBUG 0
42 #define DEBUG 0
43 #include <aros/debug.h>
47 jDc: opaque resize code is NOT suitable for other apps than MUI, I have no intentions in fixing it so that
48 it would work with all apps out there. Use mui or die :)
50 The idea behind the trick is that we use a func that checks if apps reply to idcmps in some period
51 of time. As long as they are replying fast we can do another layer resize, send idcmp to app.
52 If they do not then we wait for a while and after some time, if one or more apps don't reply
53 we do the resize again (the timeout is also useful when we have some dead app with windows
54 on screen.
58 #if USE_OPAQUESIZE
59 # define OPAQUESIZE (w->MoreFlags & WMFLG_IAMMUI)
60 #else
61 # define OPAQUESIZE 0
62 #endif
64 //#define DELAYEDDRAG
65 /* Delayed resizing is enabled, due to a layer deadlock
66 * that can occur between console.device and this
67 * gadget when Commodities/ClickToFront is enabled and
68 * DELAYEDSIZE is disabled.
70 #define DELAYEDSIZE
72 /***********************************************************************************/
74 #define WSIG_MOVE SIGF_INTUITION
75 #define WSIG_DIE SIGF_ABORT
77 /***********************************************************************************/
79 void MoveTask(struct dragbar_data *data,struct Window *w,struct Screen *screen,struct IntuitionBase *IntuitionBase)
81 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
82 ULONG signals;
84 for (;;)
86 signals = Wait(WSIG_DIE|WSIG_MOVE);
88 if (signals & WSIG_DIE)
90 Forbid();
91 data->movetask = 0;
92 Permit();
93 WindowAction(w,WAC_CHANGEWINDOWBOX,0);
94 return;
97 if (signals & WSIG_MOVE)
99 struct Layer *L;
101 LockLayers(&screen->LayerInfo);
103 for (L = screen->LayerInfo.top_layer; L; L = L->back)
105 if (L->Window == w)
107 //window not closed yet!
108 if (data->curleft != w->LeftEdge || data->curtop != w->TopEdge)
110 struct Requester *req;
112 if (BLAYER(w))
114 /* move outer window first */
115 MoveSizeLayer(BLAYER(w), data->curleft - w->LeftEdge, data->curtop - w->TopEdge, 0, 0);
118 MoveSizeLayer(WLAYER(w), data->curleft - w->LeftEdge, data->curtop - w->TopEdge, 0, 0);
120 for (req = w->FirstRequest; req; req = req->OlderRequest)
122 struct Layer *layer = req->ReqLayer;
124 if (layer)
126 int dx, dy, dw, dh;
127 int left, top, right, bottom;
129 left = data->curleft + req->LeftEdge;
130 top = data->curtop + req->TopEdge;
131 right = left + req->Width - 1;
132 bottom = top + req->Height - 1;
134 if (left > data->curleft + w->Width - 1)
135 left = data->curleft + w->Width - 1;
137 if (top > data->curtop + w->Height - 1)
138 top = data->curtop + w->Height - 1;
140 if (right > data->curleft + w->Width - 1)
141 right = data->curleft + w->Width - 1;
143 if (bottom > data->curtop + w->Height - 1)
144 bottom = data->curtop + w->Height - 1;
146 dx = left - layer->bounds.MinX;
147 dy = top - layer->bounds.MinY;
148 dw = right - left - layer->bounds.MaxX + layer->bounds.MinX;
149 dh = bottom - top - layer->bounds.MaxY + layer->bounds.MinY;
151 MoveSizeLayer(layer, dx, dy, dw, dh);
155 w->LeftEdge = data->curleft;
156 w->TopEdge = data->curtop;
157 UpdateMouseCoords(w);
163 #ifdef DAMAGECACHE
164 RecordDamage(screen,IntuitionBase);
165 #endif
166 data->drag_refreshed = FALSE;
168 UnlockLayers(&screen->LayerInfo);
173 /***********************************************************************************/
175 /* drawwindowframe is used when the user drags or resizes a window */
177 #define DWF_THICK_X 2
178 #define DWF_THICK_Y 2
180 /***********************************************************************************/
182 static void cliprectfill(struct Screen *scr, struct RastPort *rp,
183 WORD x1, WORD y1, WORD x2, WORD y2,
184 struct IntuitionBase *IntuitionBase)
186 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
187 WORD scrx2 = scr->Width - 1;
188 WORD scry2 = scr->Height - 1;
190 /* Check if inside at all */
192 if (!((x1 > scrx2) || (x2 < 0) || (y1 > scry2) || (y2 < 0)))
194 if (x1 < 0) x1 = 0;
195 if (y1 < 0) y1 = 0;
196 if (x2 > scrx2) x2 = scrx2;
197 if (y2 > scry2) y2 = scry2;
199 /* paranoia */
201 if ((x2 >= x1) && (y2 >= y1))
203 RectFill(rp, x1, y1, x2, y2);
209 /***********************************************************************************/
211 static void drawwindowframe(struct Screen *scr, struct RastPort *rp,
212 WORD x1, WORD y1, WORD x2, WORD y2,
213 struct IntuitionBase *IntuitionBase)
215 /* this checks should not be necessary, but just to be sure */
217 if (x2 < x1)
219 /* swap x2 and x1 */
220 x2 ^= x1;
221 x1 ^= x2;
222 x2 ^= x1;
225 if (y2 < y1)
227 /* swap y2 and y1 */
228 y2 ^= y1;
229 y1 ^= y2;
230 y2 ^= y1;
233 if (((x2 - x1) < (DWF_THICK_X * 2)) ||
234 ((y2 - y1) < (DWF_THICK_Y * 2)))
236 cliprectfill(scr, rp, x1, y1, x2, y2, IntuitionBase);
238 else
240 cliprectfill(scr, rp, x1, y1, x2, y1 + DWF_THICK_Y - 1, IntuitionBase);
241 cliprectfill(scr, rp, x2 - DWF_THICK_X + 1, y1 + DWF_THICK_Y, x2, y2, IntuitionBase);
242 cliprectfill(scr, rp, x1, y2 - DWF_THICK_Y + 1, x2 - DWF_THICK_X, y2, IntuitionBase);
243 cliprectfill(scr, rp, x1, y1 + DWF_THICK_Y, x1 + DWF_THICK_X - 1, y2 - DWF_THICK_Y, IntuitionBase);
247 /***********************************************************************************/
249 #if 0
250 IPTR DragBarClass__GM_RENDER(Class *cl, struct Gadget *g, struct gpRender * msg)
252 EnterFunc(bug("DragBar::Render()\n"));
253 /* We will let the AROS gadgetclass test if it is safe to render */
255 if ( DoSuperMethodA(cl, (Object *)g, (Msg)msg) != 0)
257 struct DrawInfo *dri = msg->gpr_GInfo->gi_DrInfo;
258 UWORD *pens = dri->dri_Pens;
259 struct RastPort *rp = msg->gpr_RPort;
260 struct IBox container;
261 struct Window *win = msg->gpr_GInfo->gi_Window;
262 struct TextExtent te;
264 GetGadgetIBox(g, msg->gpr_GInfo, &container);
266 if (container.Width <= 1 || container.Height <= 1)
267 return;
270 /* Clear the dragbar */
272 SetAPen(rp, (win->Flags & WFLG_WINDOWACTIVE) ?
273 pens[FILLPEN] : pens[BACKGROUNDPEN]);
275 SetDrMd(rp, JAM1);
277 D(bug("Filling from (%d, %d) to (%d, %d)\n",
278 container.Left,
279 container.Top,
280 container.Left + container.Width - 1,
281 container.Top + container.Height - 1));
283 RectFill(rp,
284 container.Left,
285 container.Top,
286 container.Left + container.Width - 1,
287 container.Top + container.Height - 2);
289 /* Draw a thin dark line around the bar */
291 SetAPen(rp, pens[SHINEPEN]);
292 RectFill(rp,container.Left,
293 container.Top,
294 container.Left,
295 container.Top + container.Height - 1 - ((container.Left == 0) ? 0 : 1));
296 RectFill(rp,container.Left + 1,
297 container.Top,
298 container.Left + container.Width - 1,
299 container.Top);
301 SetAPen(rp,pens[SHADOWPEN]);
302 RectFill(rp,container.Left + container.Width - 1,
303 container.Top + 1,
304 container.Left + container.Width - 1,
305 container.Top + container.Height - 1);
306 RectFill(rp,container.Left + ((container.Left == 0) ? 1 : 0),
307 container.Top + container.Height - 1,
308 container.Left + container.Width - 2,
309 container.Top + container.Height - 1);
311 /* Render the titlebar */
312 if (NULL != win->Title)
314 ULONG textlen, titlelen;
316 SetFont(rp, dri->dri_Font);
318 titlelen = strlen(win->Title);
319 textlen = TextFit(rp
320 , win->Title
321 , titlelen
322 , &te
323 , NULL
325 , container.Width - 6
326 , container.Height);
328 SetAPen(rp, pens[(win->Flags & WFLG_WINDOWACTIVE) ? FILLTEXTPEN : TEXTPEN]);
329 Move(rp, container.Left + 3, container.Top + dri->dri_Font->tf_Baseline + 2);
331 Text(rp, win->Title, textlen);
334 } /* if (allowed to render) */
336 return (IPTR)0;
338 #endif
340 /***********************************************************************************/
342 IPTR DragBarClass__GM_GOACTIVE(Class *cl, struct Gadget *g, struct gpInput *msg)
344 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
345 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
346 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
347 struct InputEvent *ie = msg->gpi_IEvent;
348 IPTR retval = GMR_NOREUSE;
350 if (ie)
352 /* The gadget was activated via mouse input */
353 struct dragbar_data *data;
354 struct Window *w;
356 /* There is no point in rerendering ourseleves here, as this is done
357 by a call to RefreshWindowFrame() in the intuition inputhandler
360 w = msg->gpi_GInfo->gi_Window;
362 data = INST_DATA(cl, g);
364 #ifdef USEWINDOWLOCK
365 /* do NOT ObtainSemaphore here since this would lead to deadlocks!!! */
366 /* when the semaphore can not be obtained we simply ignore gadget activation */
368 /* in movehack the task that locks windowlock is the one that calls MoveWindow*/
369 if (!(AttemptSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock)))
371 goto fail;
373 data->drag_windowlock = TRUE;
374 #endif
376 data->curleft = w->LeftEdge;
377 data->curtop = w->TopEdge;
379 data->startleft = w->LeftEdge;
380 data->starttop = w->TopEdge;
382 data->mousex = w->WScreen->MouseX - data->curleft;
383 data->mousey = w->WScreen->MouseY - data->curtop;
385 data->drag_refreshed = TRUE;
387 data->rp = CloneRastPort(&w->WScreen->RastPort);
388 if (data->rp)
391 /* Lock all layers while the window is dragged.
392 * Get the gadget lock first to avoid deadlocks
393 * with ObtainGIRPort. */
395 D(bug("locking all layers\n"));
397 if (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE))
399 #ifdef USEGADGETLOCK
400 ObtainSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
401 data->drag_inputhandlerlock = TRUE;
403 if (AttemptSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock))
405 data->drag_gadgetlock = TRUE;
407 else
409 goto fail;
411 #endif
412 #ifndef DELAYEDDRAG
413 LockLayers(&w->WScreen->LayerInfo);
414 data->drag_layerlock = TRUE;
415 #endif
416 } else {
417 /* MOVEHACK ? */
418 if (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_PRIVILEDGEDREFRESH)
420 #ifdef __MORPHOS__
421 data->movetask =
422 NewCreateTask(TASKTAG_CODETYPE, CODETYPE_PPC, TASKTAG_PC, (ULONG)MoveTask,
423 TASKTAG_PRI, 0,
424 TASKTAG_PPC_ARG1,(ULONG)data,
425 TASKTAG_PPC_ARG2,(ULONG)w,
426 TASKTAG_PPC_ARG3,(ULONG)w->WScreen,
427 TASKTAG_PPC_ARG4,(ULONG)IntuitionBase,
428 TAG_DONE);
429 #else
430 // FIXME!
431 /* FIXME: Implemente MOVEHACK support for AROS (?) */
432 #endif
436 SetDrMd(data->rp, COMPLEMENT);
438 #ifndef DELAYEDDRAG
439 if (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE))
440 drawwindowframe(w->WScreen
441 , data->rp
442 , data->curleft
443 , data->curtop
444 , data->curleft + w->Width - 1
445 , data->curtop + w->Height - 1
446 , IntuitionBase
449 data->isrendered = TRUE;
450 #endif
452 data->drag_canceled = FALSE;
455 UQUAD currenttime;
457 currenttime = ie->ie_TimeStamp.tv_secs;
458 currenttime = currenttime * 50;
459 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
461 data->lasteventtime = currenttime;
464 /* size mouse bounds such that mouse pointer cannot move if window cannot move, if offscreenlayers is turned off */
465 if (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS)) {
466 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
467 iihd->MouseBoundsActiveFlag = TRUE;
468 iihd->MouseBoundsLeft = data->mousex;
469 iihd->MouseBoundsRight = w->WScreen->Width - (w->Width - data->mousex);
470 iihd->MouseBoundsTop = data->mousey;
471 iihd->MouseBoundsBottom = w->WScreen->Height - (w->Height - data->mousey);
474 return GMR_MEACTIVE;
477 fail:
478 if (data->drag_layerlock)
480 UnlockLayers(&w->WScreen->LayerInfo);
481 data->drag_layerlock = FALSE;
485 #ifdef USEGADGETLOCK
486 if (data->drag_gadgetlock)
488 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock);
489 data->drag_gadgetlock = FALSE;
492 if (data->drag_inputhandlerlock);
494 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
495 data->drag_inputhandlerlock = FALSE;
497 #endif
499 #ifdef USEWINDOWLOCK
500 if (data->drag_windowlock)
502 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
503 data->drag_windowlock = FALSE;
505 #endif
508 return retval;
512 /***********************************************************************************/
514 IPTR DragBarClass__GM_MOVETEST(Class *cl, struct Gadget *g, struct gpInput *msg)
516 IPTR retval = MOVETEST_MOVE;
517 #ifdef SKINS
518 struct dragbar_data *data = INST_DATA(cl, g);
519 struct Window *w = msg->gpi_GInfo->gi_Window;
520 struct InputEvent myie;
521 LONG new_left;
522 LONG new_top;
524 CopyMem(msg->gpi_IEvent,&myie,sizeof (struct InputEvent));
525 myie.ie_Code = 0x68; //mouse_leftpress
527 /* Can we move to the new position, or is window at edge of display ? */
528 new_left = msg->gpi_Mouse.X - data->mousex;
529 new_top = msg->gpi_Mouse.Y - data->mousey;
531 if ((!((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (w->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS))) ||
532 MatchHotkey(&myie,IA_TOGGLEOFFSCREEN,IntuitionBase))
534 if (new_left < 0)
536 msg->gpi_Mouse.X -= new_left;
537 retval = MOVETEST_ADJUSTPOS;
540 if (new_top < 0)
542 msg->gpi_Mouse.Y -= new_top;
543 retval = MOVETEST_ADJUSTPOS;
546 if (new_left + w->Width > w->WScreen->Width)
548 msg->gpi_Mouse.X -= new_left - (w->WScreen->Width - w->Width);
549 retval = MOVETEST_ADJUSTPOS;
552 if (new_top + w->Height > w->WScreen->Height)
554 msg->gpi_Mouse.Y -= new_top - (w->WScreen->Height - w->Height);
555 retval = MOVETEST_ADJUSTPOS;
558 #endif
560 return retval;
564 /***********************************************************************************/
566 IPTR DragBarClass__GM_HANDLEINPUT(Class *cl, struct Gadget *g, struct gpInput *msg)
568 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
569 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
570 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
571 struct GadgetInfo *gi = msg->gpi_GInfo;
572 IPTR retval = GMR_MEACTIVE;
574 if (gi)
576 struct InputEvent *ie = msg->gpi_IEvent;
577 struct dragbar_data *data = INST_DATA(cl, g);
578 struct Window *w = msg->gpi_GInfo->gi_Window;
580 switch (ie->ie_Class)
582 case IECLASS_RAWMOUSE:
583 switch (ie->ie_Code)
585 case MENUDOWN:
586 retval = GMR_NOREUSE;
587 data->drag_canceled = TRUE;
588 break;
590 case SELECTUP:
591 retval = GMR_NOREUSE;
592 break;
595 case IECODE_NOBUTTON:
597 struct Screen *scr = w->WScreen;
598 struct InputEvent myie;
599 LONG new_left;
600 LONG new_top;
602 /* Can we move to the new position, or is window at edge of display ? */
603 new_left = scr->MouseX - data->mousex;
604 new_top = scr->MouseY - data->mousey;
606 CopyMem(ie,&myie,sizeof (struct InputEvent));
607 myie.ie_Code = SELECTDOWN; //mouse_leftpress
609 #ifdef SKINS
610 if ((!((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (w->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS))) ||
611 MatchHotkey(&myie,IA_TOGGLEOFFSCREEN,IntuitionBase))
612 #else
613 if (!((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (w->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS)))
614 #endif
616 if (new_left < 0)
618 data->mousex += new_left;
619 new_left = 0;
622 if (new_top < 0)
624 data->mousey += new_top;
625 new_top = 0;
628 if (new_left + w->Width > scr->Width)
630 LONG correct_left;
631 correct_left = scr->Width - w->Width; /* align to screen border */
632 data->mousex += new_left - correct_left;
633 new_left = correct_left;
636 if (new_top + w->Height > scr->Height)
638 LONG correct_top;
639 correct_top = scr->Height - w->Height; /* align to screen border */
640 data->mousey += new_top - correct_top;
641 new_top = correct_top;
645 if (data->curleft != new_left || data->curtop != new_top)
647 SetDrMd(data->rp, COMPLEMENT);
649 if ((data->isrendered) && (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)))
651 /* Erase old frame */
652 drawwindowframe(w->WScreen
653 , data->rp
654 , data->curleft
655 , data->curtop
656 , data->curleft + w->Width - 1
657 , data->curtop + w->Height - 1
658 , IntuitionBase
662 data->curleft = new_left;
663 data->curtop = new_top;
665 if (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)
667 WORD newx = new_left - w->LeftEdge, newy = new_top - w->TopEdge;
669 if (newx || newy)
671 UQUAD currenttime;
673 currenttime = ie->ie_TimeStamp.tv_secs;
674 currenttime = currenttime * 50;
675 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
677 if (currenttime > data->lasteventtime + 10) //10 delay should result in intuitick freq
679 ih_fire_intuimessage(w,
680 IDCMP_CHANGEWINDOW,
681 CWCODE_MOVESIZE,
683 IntuitionBase);
684 data->lasteventtime = currenttime;
687 if (data->movetask)
689 Forbid();
690 Signal(data->movetask,WSIG_MOVE);
691 Permit();
693 CheckLayers(w->WScreen, IntuitionBase);
695 else
697 struct Requester *req;
699 LockLayers(&w->WScreen->LayerInfo);
701 w->LeftEdge += newx;
702 w->TopEdge += newy;
704 if (BLAYER(w))
706 MoveSizeLayer(BLAYER(w), newx, newy , 0, 0);
709 MoveSizeLayer(WLAYER(w), newx, newy, 0, 0);
711 for (req = w->FirstRequest; req; req = req->OlderRequest)
713 struct Layer *layer = req->ReqLayer;
715 if (layer)
717 int dx, dy, dw, dh;
718 int left, top, right, bottom;
720 left = data->curleft + req->LeftEdge;
721 top = data->curtop + req->TopEdge;
722 right = left + req->Width - 1;
723 bottom = top + req->Height - 1;
725 if (left > data->curleft + w->Width - 1)
726 left = data->curleft + w->Width - 1;
728 if (top > data->curtop + w->Height - 1)
729 top = data->curtop + w->Height - 1;
731 if (right > data->curleft + w->Width - 1)
732 right = data->curleft + w->Width - 1;
734 if (bottom > data->curtop + w->Height - 1)
735 bottom = data->curtop + w->Height - 1;
737 dx = left - layer->bounds.MinX;
738 dy = top - layer->bounds.MinY;
739 dw = right - left - layer->bounds.MaxX + layer->bounds.MinX;
740 dh = bottom - top - layer->bounds.MaxY + layer->bounds.MinY;
742 MoveSizeLayer(layer, dx, dy, dw, dh);
746 CheckLayers(w->WScreen, IntuitionBase);
748 UnlockLayers(&w->WScreen->LayerInfo);
752 else
754 #ifdef DELAYEDDRAG
755 if ((!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)) && (!data->drag_layerlock))
757 LockLayers(&w->WScreen->LayerInfo);
758 data->drag_layerlock = TRUE;
760 #endif
761 /* Rerender the window frame */
762 drawwindowframe(w->WScreen
763 , data->rp
764 , data->curleft
765 , data->curtop
766 , data->curleft + w->Width - 1
767 , data->curtop + w->Height - 1
768 , IntuitionBase);
769 data->isrendered = TRUE;
774 retval = GMR_MEACTIVE;
776 break;
779 default:
780 retval = GMR_NOREUSE;
781 if (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)) data->drag_canceled = TRUE;
782 break;
784 } /* switch (ie->ie_Code) */
785 break;
787 case IECLASS_TIMER:
788 #ifdef DELAYEDDRAG
789 if ((!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)) && (!data->drag_layerlock))
791 UQUAD currenttime;
793 currenttime = ie->ie_TimeStamp.tv_secs;
794 currenttime = currenttime * 50;
795 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
797 if (currenttime > data->lasteventtime + 10)
799 LockLayers(&w->WScreen->LayerInfo);
800 data->drag_layerlock = TRUE;
802 drawwindowframe(w->WScreen
803 , data->rp
804 , data->curleft
805 , data->curtop
806 , data->curleft + w->Width - 1
807 , data->curtop + w->Height - 1
808 , IntuitionBase
810 data->lasteventtime = currenttime;
811 data->isrendered = TRUE;
814 #endif
816 if (data->movetask)
818 UQUAD currenttime;
820 currenttime = ie->ie_TimeStamp.tv_secs;
821 currenttime = currenttime * 50;
822 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
824 if ((!data->drag_refreshed) && currenttime > data->lasteventtime + 10) //10 delay should result in intuitick freq
826 ih_fire_intuimessage( w,
827 IDCMP_CHANGEWINDOW,
828 CWCODE_MOVESIZE,
830 IntuitionBase);
831 data->drag_refreshed = TRUE;
832 data->lasteventtime = currenttime;
834 CheckLayers(w->WScreen,IntuitionBase);
836 break;
837 } /* switch (ie->ie_Class) */
839 } /* if (gi) */
841 return retval;
844 /***********************************************************************************/
846 IPTR DragBarClass__GM_GOINACTIVE(Class *cl, struct Gadget *g, struct gpGoInactive *msg)
848 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
849 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
850 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
851 struct dragbar_data *data;
852 struct Window *w;
854 data = INST_DATA(cl, g);
856 w = msg->gpgi_GInfo->gi_Window;
858 /* Always clear last drawn frame */
860 if (data->isrendered && data->rp && (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)))
863 SetDrMd(data->rp, COMPLEMENT);
865 /* Erase old frame */
866 drawwindowframe(w->WScreen
867 , data->rp
868 , data->curleft
869 , data->curtop
870 , data->curleft + w->Width - 1
871 , data->curtop + w->Height - 1
872 , IntuitionBase
877 data->isrendered = FALSE;
879 if (!data->drag_refreshed) CheckLayers(w->WScreen, IntuitionBase);
881 Forbid();
882 if (data->movetask)
884 Signal(data->movetask,WSIG_DIE);
885 data->movetask = 0;
887 Permit();
889 if (!data->drag_canceled)// && !(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE))
891 MoveWindow(w
892 , data->curleft - w->LeftEdge /* dx */
893 , data->curtop - w->TopEdge /* dy */
898 if (data->drag_canceled && (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE))
900 MoveWindow(w
901 , data->startleft - w->LeftEdge /* dx */
902 , data->starttop - w->TopEdge /* dy */
907 ih_fire_intuimessage(w,
908 IDCMP_CHANGEWINDOW,
909 CWCODE_MOVESIZE,
911 IntuitionBase);
913 data->drag_canceled = TRUE;
915 if (data->drag_layerlock)
917 UnlockLayers(&w->WScreen->LayerInfo);
918 data->drag_layerlock = FALSE;
921 #ifdef USEGADGETLOCK
922 if (data->drag_gadgetlock)
924 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock);
925 data->drag_gadgetlock = FALSE;
928 if (data->drag_inputhandlerlock)
930 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
931 data->drag_inputhandlerlock = FALSE;
933 #endif
935 #ifdef USEWINDOWLOCK
936 if (data->drag_windowlock)
938 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
939 data->drag_windowlock = FALSE;
941 #endif
943 /* User throught with drag operation. Unlock layesr and free
944 rastport clone
947 if (data->rp)
949 FreeRastPort(data->rp);
950 data->rp = NULL;
953 /* shut off mouse bounds checking. */
954 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
955 iihd->MouseBoundsActiveFlag = FALSE;
957 return TRUE;
962 /***********************************************************************************/
964 IPTR DragBarClass__NOP(Class *cl, Object *o, Msg msg)
966 return (IPTR)0;
969 /***********************************************************************************/
971 IPTR DragBarClass__GM_HITTEST(Class *cl, Object *o, Msg msg)
973 return (IPTR)1;
976 /***********************************************************************************/
978 IPTR DragBarClass__OM_NEW(Class *cl, Object *o, Msg msg)
980 struct Gadget *g = (struct Gadget *)DoSuperMethodA(cl, o, msg);
981 if (g)
983 g->GadgetType |= GTYP_SYSGADGET | GTYP_WDRAGGING;
986 return (IPTR)g;
989 /***********************************************************************************/
991 /*********************
992 ** The SizeButtonClass
993 *********************/
995 #ifdef SKINS
996 #define SIZETYPE_RIGHTBOTTOM 1
997 #define SIZETYPE_RIGHT 2
998 #define SIZETYPE_BOTTOM 3
999 #define SIZETYPE_LEFTBOTTOM 4
1000 #define SIZETYPE_LEFT 5
1001 #define SIZETYPE_LEFTTOP 6
1002 #define SIZETYPE_TOP 7
1003 #define SIZETYPE_RIGHTTOP 8
1004 #endif
1006 /***********************************************************************************/
1008 void smartresize(struct Window *w,struct sizebutton_data *data,Class *cl)
1010 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1011 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
1012 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
1014 LockLayers(&w->WScreen->LayerInfo);
1016 if (BLAYER(w))
1018 struct Hook *backfill;
1020 backfill = BLAYER(w)->BackFill;
1021 BLAYER(w)->BackFill = LAYERS_NOBACKFILL;
1023 /* move outer window first */
1024 MoveSizeLayer(BLAYER(w), data->left - w->LeftEdge, data->top - w->TopEdge, data->width - w->Width, data->height - w->Height);
1026 BLAYER(w)->BackFill = backfill;
1030 struct Hook *backfill;
1032 backfill = WLAYER(w)->BackFill;
1033 WLAYER(w)->BackFill = LAYERS_NOBACKFILL;
1034 MoveSizeLayer(WLAYER(w), data->left - w->LeftEdge, data->top - w->TopEdge, data->width - w->Width, data->height - w->Height);
1035 WLAYER(w)->BackFill = backfill;
1038 w->TopEdge = data->top;
1039 w->LeftEdge = data->left;
1040 w->Width = data->width;
1041 w->Height = data->height;
1043 IW(w)->specialflags |= SPFLAG_LAYERRESIZED;
1045 if ((iihdata->ActiveGadget) && (w == iihdata->GadgetInfo.gi_Window))
1047 GetGadgetDomain(iihdata->ActiveGadget,
1048 iihdata->GadgetInfo.gi_Screen,
1049 iihdata->GadgetInfo.gi_Window,
1050 NULL,
1051 &iihdata->GadgetInfo.gi_Domain);
1054 /* Relayout GFLG_REL??? gadgets */
1055 DoGMLayout(w->FirstGadget, w, NULL, -1, FALSE, IntuitionBase);
1057 ih_fire_intuimessage(w,
1058 IDCMP_NEWSIZE,
1061 IntuitionBase);
1063 CheckLayers(w->WScreen, IntuitionBase);
1065 UnlockLayers(&w->WScreen->LayerInfo);
1068 /***********************************************************************************/
1070 IPTR SizeButtonClass__GM_GOACTIVE(Class *cl, struct Gadget *g, struct gpInput *msg)
1072 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1073 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1074 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
1075 struct InputEvent *ie = msg->gpi_IEvent;
1076 IPTR retval = GMR_NOREUSE;
1078 if (ie)
1080 /* The gadget was activated via mouse input */
1081 struct sizebutton_data *data;
1082 struct Window *w;
1084 /* There is no point in rerendering ourseleves her, as this
1085 is done by a call to RefreshWindowFrame() in the intuition inputhandler
1088 w = msg->gpi_GInfo->gi_Window;
1090 data = INST_DATA(cl, g);
1092 #ifdef USEWINDOWLOCK
1093 /* do NOT ObtainSemaphore here since this would lead to deadlocks!!! */
1094 /* when the semaphore can not be obtained we simply ignore gadget activation */
1095 if (!(AttemptSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock)))
1097 goto fail;
1099 data->drag_windowlock = TRUE;
1100 #endif
1102 data->height = data->Height = w->Height;
1103 data->width = data->Width = w->Width;
1104 data->left = data->LeftEdge = w->LeftEdge;
1105 data->top = data->TopEdge = w->TopEdge;
1107 data->mouseoffsetx = w->WScreen->MouseX;
1108 data->mouseoffsety = w->WScreen->MouseY;
1110 data->drag_refreshed = TRUE;
1111 data->drag_ticks = 2;
1113 #ifdef SKINS
1114 data->drag_type = 0;
1116 if (w->MouseX < IW(w)->sizeimage_width)
1118 if (w->MouseY < IW(w)->sizeimage_height) data->drag_type = SIZETYPE_LEFTTOP;
1119 if (w->MouseY > w->Height - IW(w)->sizeimage_height - 1) data->drag_type = SIZETYPE_LEFTBOTTOM;
1120 if (!data->drag_type) data->drag_type = SIZETYPE_LEFT;
1123 if ((!data->drag_type) && (w->MouseX >= IW(w)->sizeimage_width) && (w->MouseX <= w->Width - 1 - IW(w)->sizeimage_width))
1125 if (w->MouseY < w->BorderTop)
1127 data->drag_type = SIZETYPE_TOP;
1128 } else {
1129 data->drag_type = SIZETYPE_BOTTOM;
1133 if ((!data->drag_type) && (w->MouseX > IW(w)->sizeimage_width))
1135 if (w->MouseY < IW(w)->sizeimage_height) data->drag_type = SIZETYPE_RIGHTTOP;
1136 if (w->MouseY > w->Height - IW(w)->sizeimage_height - 1) data->drag_type = SIZETYPE_RIGHTBOTTOM;
1137 if (!data->drag_type) data->drag_type = SIZETYPE_RIGHT;
1140 if (!data->drag_type) goto fail;
1141 #endif
1143 data->rp = CloneRastPort(&w->WScreen->RastPort);
1144 if (data->rp)
1146 /* Lock all layers while the window is resized.
1147 * Get the gadget lock first to avoid deadlocks
1148 * with ObtainGIRPort. */
1150 if (!OPAQUESIZE)
1152 #ifdef USEGADGETLOCK
1153 ObtainSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
1154 data->drag_inputhandlerlock = TRUE;
1156 if (AttemptSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock))
1158 data->drag_gadgetlock = TRUE;
1160 else
1162 goto fail;
1164 #endif
1165 #ifndef DELAYEDSIZE
1166 LockLayers(&w->WScreen->LayerInfo);
1167 data->drag_layerlock = TRUE;
1168 #endif
1171 SetDrMd(data->rp, COMPLEMENT);
1173 #ifndef DELAYEDSIZE
1174 if(!OPAQUESIZE)
1175 drawwindowframe(w->WScreen
1176 , data->rp
1177 , data->left
1178 , data->top
1179 , data->left + data->width - 1
1180 , data->top + data->height - 1
1181 , IntuitionBase
1184 data->isrendered = TRUE;
1185 #endif
1188 UQUAD currenttime;
1190 currenttime = ie->ie_TimeStamp.tv_secs;
1191 currenttime = currenttime * 50;
1192 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
1193 data->lasteventtime = currenttime;
1196 data->drag_canceled = FALSE;
1198 /* size mouse bounds such that mouse pointer cannot move if window cannot size, if offscreenlayers is turned off */
1199 if (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS)) {
1200 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
1201 LONG mousex = data->mouseoffsetx - data->LeftEdge;
1202 LONG mousey = data->mouseoffsety - data->TopEdge;
1204 iihd->MouseBoundsActiveFlag = TRUE;
1205 iihd->MouseBoundsLeft = 0;
1206 iihd->MouseBoundsRight = w->WScreen->Width - (w->Width - mousex);
1207 iihd->MouseBoundsTop = 0;
1208 iihd->MouseBoundsBottom = w->WScreen->Height - (w->Height - mousey);
1211 return GMR_MEACTIVE;
1214 fail:
1215 if (data->drag_layerlock)
1217 UnlockLayers(&w->WScreen->LayerInfo);
1218 data->drag_layerlock = FALSE;
1222 #ifdef USEGADGETLOCK
1223 if (data->drag_gadgetlock)
1225 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock);
1226 data->drag_gadgetlock = FALSE;
1229 if (data->drag_inputhandlerlock);
1231 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
1232 data->drag_inputhandlerlock = FALSE;
1234 #endif
1236 #ifdef USEWINDOWLOCK
1237 if (data->drag_windowlock)
1239 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
1240 data->drag_windowlock = FALSE;
1242 #endif
1245 return retval;
1249 /***********************************************************************************/
1251 IPTR SizeButtonClass__GM_HANDLEINPUT(Class *cl, struct Gadget *g, struct gpInput *msg)
1253 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1254 #ifdef DELAYEDSIZE
1255 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
1256 #endif
1257 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1258 struct GadgetInfo *gi = msg->gpi_GInfo;
1259 IPTR retval = GMR_MEACTIVE;
1261 if (gi)
1263 struct InputEvent *ie = msg->gpi_IEvent;
1264 struct sizebutton_data *data = INST_DATA(cl, g);
1265 struct Window *w = msg->gpi_GInfo->gi_Window;
1267 switch (ie->ie_Class)
1269 case IECLASS_RAWMOUSE:
1270 switch (ie->ie_Code)
1272 case SELECTUP:
1273 retval = GMR_NOREUSE;
1274 break;
1277 case IECODE_NOBUTTON:
1279 struct Screen *scr = w->WScreen;
1280 LONG new_width = 0;
1281 LONG new_height = 0;
1283 /* Can we move to the new position, or is window at edge of display ? */
1284 #ifdef SKINS
1285 switch(data->drag_type)
1287 case SIZETYPE_BOTTOM:
1288 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1289 new_width = data->Width;
1290 break;
1292 case SIZETYPE_TOP:
1293 new_height = data->Height + data->mouseoffsety - scr->MouseY;
1294 new_width = data->Width;
1295 break;
1297 case SIZETYPE_RIGHTBOTTOM:
1298 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1299 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1300 break;
1302 case SIZETYPE_LEFTTOP:
1303 new_width = data->Width + data->mouseoffsetx - scr->MouseX;
1304 new_height = data->Height + data->mouseoffsety - scr->MouseY;
1305 break;
1307 case SIZETYPE_RIGHTTOP:
1308 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1309 new_height = data->Height + data->mouseoffsety - scr->MouseY;
1310 break;
1312 case SIZETYPE_LEFTBOTTOM:
1313 new_width = data->Width + data->mouseoffsetx - scr->MouseX;
1314 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1315 break;
1317 case SIZETYPE_LEFT:
1318 new_width = data->Width + data->mouseoffsetx - scr->MouseX;
1319 new_height = data->Height;
1320 break;
1322 case SIZETYPE_RIGHT:
1323 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1324 new_height = data->Height;
1325 break;
1327 #else
1328 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1329 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1330 #endif
1331 if (new_width < 0)
1332 new_width = 1;
1334 if (w->MinWidth != 0 && new_width < (ULONG)w->MinWidth)
1335 new_width = w->MinWidth;
1337 if (w->MaxWidth != 0 && new_width > (ULONG)w->MaxWidth)
1338 new_width = w->MaxWidth;
1340 if (new_height < 0)
1341 new_height = 1;
1343 if (w->MinHeight != 0 && new_height < (ULONG)w->MinHeight)
1344 new_height = w->MinHeight;
1346 if (w->MaxHeight != 0 && new_height > (ULONG)w->MaxHeight)
1347 new_height = w->MaxHeight;
1350 #ifdef SKINS
1351 if (!((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (w->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS)))
1353 /* limit dimensions so window fits on the screen */
1354 switch (data->drag_type)
1356 case SIZETYPE_RIGHT:
1357 case SIZETYPE_RIGHTTOP:
1358 case SIZETYPE_RIGHTBOTTOM:
1359 if (data->left + new_width > scr->Width)
1360 new_width = scr->Width - data->left;
1361 break;
1363 case SIZETYPE_LEFT:
1364 case SIZETYPE_LEFTBOTTOM:
1365 case SIZETYPE_LEFTTOP:
1366 if (data->LeftEdge + data->Width - new_width < 0)
1367 new_width += (data->LeftEdge + data->Width - new_width);
1368 break;
1371 switch (data->drag_type)
1373 case SIZETYPE_LEFTBOTTOM:
1374 case SIZETYPE_BOTTOM:
1375 case SIZETYPE_RIGHTBOTTOM:
1376 if (data->top + new_height > scr->Height)
1377 new_height = scr->Height - data->top;
1378 break;
1380 case SIZETYPE_TOP:
1381 case SIZETYPE_LEFTTOP:
1382 case SIZETYPE_RIGHTTOP:
1383 if (data->TopEdge + data->Height - new_height < 0)
1384 new_height += (data->TopEdge + data->Height - new_height);
1385 break;
1388 #endif
1390 if (data->height != new_height || data->width != new_width)
1392 SetDrMd(data->rp, COMPLEMENT);
1394 if (data->isrendered && !OPAQUESIZE)
1396 /* Erase old frame */
1397 drawwindowframe(w->WScreen
1398 , data->rp
1399 , data->left
1400 , data->top
1401 , data->left + data->width - 1
1402 , data->top + data->height - 1
1403 , IntuitionBase
1408 #ifdef SKINS
1409 switch(data->drag_type)
1411 case SIZETYPE_LEFT:
1412 data->left = data->LeftEdge + data->Width - new_width;
1413 break;
1415 case SIZETYPE_LEFTTOP:
1416 data->left = data->LeftEdge + data->Width - new_width;
1417 data->top = data->TopEdge + data->Height - new_height;
1418 break;
1420 case SIZETYPE_LEFTBOTTOM:
1421 data->left = data->LeftEdge + data->Width - new_width;
1422 break;
1424 case SIZETYPE_RIGHTTOP:
1425 data->top = data->TopEdge + data->Height - new_height;
1426 break;
1428 case SIZETYPE_TOP:
1429 data->top = data->TopEdge + data->Height - new_height;
1430 break;
1432 #endif
1434 data->width = new_width;
1435 data->height = new_height;
1437 /* Rerender the window frame */
1439 #ifdef DELAYEDSIZE
1440 if (!data->drag_layerlock && !OPAQUESIZE)
1442 LockLayers(&w->WScreen->LayerInfo);
1443 data->drag_layerlock = TRUE;
1445 #endif
1447 data->drag_refreshed = FALSE;
1448 data->drag_ticks = 2;
1450 if (!OPAQUESIZE)
1451 drawwindowframe(w->WScreen
1452 , data->rp
1453 , data->left
1454 , data->top
1455 , data->left + data->width - 1
1456 , data->top + data->height - 1
1457 , IntuitionBase
1460 data->isrendered = TRUE;
1464 retval = GMR_MEACTIVE;
1466 break;
1469 default:
1470 retval = GMR_NOREUSE;
1471 data->drag_canceled = TRUE;
1472 break;
1476 } /* switch (ie->ie_Code) */
1477 break;
1479 case IECLASS_TIMER:
1480 #ifdef DELAYEDSIZE
1481 if (!data->drag_layerlock && !OPAQUESIZE)
1483 UQUAD currenttime;
1484 currenttime = ie->ie_TimeStamp.tv_secs;
1485 currenttime = currenttime * 50;
1486 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
1488 if (currenttime > data->lasteventtime + 10)
1490 LockLayers(&w->WScreen->LayerInfo);
1491 data->drag_layerlock = TRUE;
1493 drawwindowframe(w->WScreen
1494 , data->rp
1495 , data->left
1496 , data->top
1497 , data->left + data->width - 1
1498 , data->top + data->height - 1
1499 , IntuitionBase
1501 data->lasteventtime = currenttime;
1502 data->isrendered = TRUE;
1505 #endif
1507 #if USE_OPAQUESIZE
1508 if (OPAQUESIZE)
1510 data->drag_ticks --;
1511 if (!data->drag_refreshed && !data->drag_ticks && WindowsReplied(w->WScreen,IntuitionBase))
1513 smartresize(w,data,cl);
1514 data->drag_refreshed = TRUE;
1515 data->drag_ticks = 2;
1518 #endif /* USE_OPAQUESIZE */
1520 break;
1522 #ifdef __MORPHOS__
1523 case IECLASS_NEWTIMER:
1524 if (OPAQUESIZE && !data->drag_refreshed && WindowsReplied(w->WScreen,IntuitionBase))
1526 smartresize(w,data,cl);
1527 data->drag_refreshed = TRUE;
1528 data->drag_ticks = 2;
1530 break;
1531 #endif /* __MORPHOS__ */
1533 } /* switch (ie->ie_Class) */
1535 } /* if (gi) */
1537 return retval;
1540 /***********************************************************************************/
1542 IPTR SizeButtonClass__GM_GOINACTIVE(Class *cl, struct Gadget *g, struct gpGoInactive *msg)
1544 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1545 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1546 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
1547 struct sizebutton_data *data;
1548 struct Window *w;
1550 data = INST_DATA(cl, g);
1551 w = msg->gpgi_GInfo->gi_Window;
1553 /* Allways clear last drawn frame */
1555 if (data->isrendered && data->rp)
1558 SetDrMd(data->rp, COMPLEMENT);
1560 /* Erase old frame */
1561 if (!OPAQUESIZE)
1562 drawwindowframe(w->WScreen
1563 , data->rp
1564 , data->left
1565 , data->top
1566 , data->left + data->width - 1
1567 , data->top + data->height - 1
1568 , IntuitionBase
1572 else
1574 if (!OPAQUESIZE)
1576 data->drag_canceled = TRUE;
1579 data->isrendered = FALSE;
1581 if (data->drag_layerlock)
1583 UnlockLayers(&w->WScreen->LayerInfo);
1584 data->drag_layerlock = FALSE;
1587 #ifdef USEGADGETLOCK
1588 if (data->drag_gadgetlock)
1590 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock);
1591 data->drag_gadgetlock = FALSE;
1594 if (data->drag_inputhandlerlock)
1596 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
1597 data->drag_inputhandlerlock = FALSE;
1599 #endif
1601 #ifdef USEWINDOWLOCK
1602 if (data->drag_windowlock)
1604 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
1605 data->drag_windowlock = FALSE;
1607 #endif
1609 //jDc: workarounds refresh pb on GZZ window resize
1610 ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->ActiveSysGadget->Flags &= ~GFLG_SELECTED;
1612 if (!data->drag_canceled || OPAQUESIZE)
1614 if (OPAQUESIZE && data->drag_canceled)
1616 DoMoveSizeWindow(w,data->LeftEdge,data->TopEdge,data->Width,data->Height,TRUE,IntuitionBase);
1618 else
1620 DoMoveSizeWindow(w,data->left,data->top,data->width,data->height,TRUE,IntuitionBase);
1622 //ChangeWindowBox(w,data->left,data->top,data->width,data->height);
1624 data->drag_canceled = TRUE;
1626 /* User throught with drag operation. Unlock layesr and free
1627 rastport clone
1629 if (data->rp)
1631 FreeRastPort(data->rp);
1632 data->rp = NULL;
1635 /* shut off mouse bounds checking. */
1636 ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->MouseBoundsActiveFlag = FALSE;
1638 return TRUE;
1641 /***********************************************************************************/
1643 IPTR SizeButtonClass__OM_NEW(Class *cl, Object *o, Msg msg)
1645 struct Gadget *g = (struct Gadget *)DoSuperMethodA(cl, o, msg);
1646 if (g)
1648 g->GadgetType |= GTYP_SYSGADGET | GTYP_SIZING;
1651 return (IPTR)g;
1654 /***********************************************************************************/