Less sloppy handling of IoErr().
[AROS.git] / rom / intuition / windowclasses.c
blob5b45d0fa87646eaddc43dad46679114cf8a98672
1 /*
2 Copyright © 1995-2013, 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 //#define DELAYEDSIZE
67 /***********************************************************************************/
69 #define WSIG_MOVE SIGF_INTUITION
70 #define WSIG_DIE SIGF_ABORT
72 /***********************************************************************************/
74 void MoveTask(struct dragbar_data *data,struct Window *w,struct Screen *screen,struct IntuitionBase *IntuitionBase)
76 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
77 ULONG signals;
79 for (;;)
81 signals = Wait(WSIG_DIE|WSIG_MOVE);
83 if (signals & WSIG_DIE)
85 Forbid();
86 data->movetask = 0;
87 Permit();
88 WindowAction(w,WAC_CHANGEWINDOWBOX,0);
89 return;
92 if (signals & WSIG_MOVE)
94 struct Layer *L;
96 LockLayers(&screen->LayerInfo);
98 for (L = screen->LayerInfo.top_layer; L; L = L->back)
100 if (L->Window == w)
102 //window not closed yet!
103 if (data->curleft != w->LeftEdge || data->curtop != w->TopEdge)
105 struct Requester *req;
107 if (BLAYER(w))
109 /* move outer window first */
110 MoveSizeLayer(BLAYER(w), data->curleft - w->LeftEdge, data->curtop - w->TopEdge, 0, 0);
113 MoveSizeLayer(WLAYER(w), data->curleft - w->LeftEdge, data->curtop - w->TopEdge, 0, 0);
115 for (req = w->FirstRequest; req; req = req->OlderRequest)
117 struct Layer *layer = req->ReqLayer;
119 if (layer)
121 int dx, dy, dw, dh;
122 int left, top, right, bottom;
124 left = data->curleft + req->LeftEdge;
125 top = data->curtop + req->TopEdge;
126 right = left + req->Width - 1;
127 bottom = top + req->Height - 1;
129 if (left > data->curleft + w->Width - 1)
130 left = data->curleft + w->Width - 1;
132 if (top > data->curtop + w->Height - 1)
133 top = data->curtop + w->Height - 1;
135 if (right > data->curleft + w->Width - 1)
136 right = data->curleft + w->Width - 1;
138 if (bottom > data->curtop + w->Height - 1)
139 bottom = data->curtop + w->Height - 1;
141 dx = left - layer->bounds.MinX;
142 dy = top - layer->bounds.MinY;
143 dw = right - left - layer->bounds.MaxX + layer->bounds.MinX;
144 dh = bottom - top - layer->bounds.MaxY + layer->bounds.MinY;
146 MoveSizeLayer(layer, dx, dy, dw, dh);
150 w->LeftEdge = data->curleft;
151 w->TopEdge = data->curtop;
152 UpdateMouseCoords(w);
158 #ifdef DAMAGECACHE
159 RecordDamage(screen,IntuitionBase);
160 #endif
161 data->drag_refreshed = FALSE;
163 UnlockLayers(&screen->LayerInfo);
168 /***********************************************************************************/
170 /* drawwindowframe is used when the user drags or resizes a window */
172 #define DWF_THICK_X 2
173 #define DWF_THICK_Y 2
175 /***********************************************************************************/
177 static void cliprectfill(struct Screen *scr, struct RastPort *rp,
178 WORD x1, WORD y1, WORD x2, WORD y2,
179 struct IntuitionBase *IntuitionBase)
181 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
182 WORD scrx2 = scr->Width - 1;
183 WORD scry2 = scr->Height - 1;
185 /* Check if inside at all */
187 if (!((x1 > scrx2) || (x2 < 0) || (y1 > scry2) || (y2 < 0)))
189 if (x1 < 0) x1 = 0;
190 if (y1 < 0) y1 = 0;
191 if (x2 > scrx2) x2 = scrx2;
192 if (y2 > scry2) y2 = scry2;
194 /* paranoia */
196 if ((x2 >= x1) && (y2 >= y1))
198 RectFill(rp, x1, y1, x2, y2);
204 /***********************************************************************************/
206 static void drawwindowframe(struct Screen *scr, struct RastPort *rp,
207 WORD x1, WORD y1, WORD x2, WORD y2,
208 struct IntuitionBase *IntuitionBase)
210 /* this checks should not be necessary, but just to be sure */
212 if (x2 < x1)
214 /* swap x2 and x1 */
215 x2 ^= x1;
216 x1 ^= x2;
217 x2 ^= x1;
220 if (y2 < y1)
222 /* swap y2 and y1 */
223 y2 ^= y1;
224 y1 ^= y2;
225 y2 ^= y1;
228 if (((x2 - x1) < (DWF_THICK_X * 2)) ||
229 ((y2 - y1) < (DWF_THICK_Y * 2)))
231 cliprectfill(scr, rp, x1, y1, x2, y2, IntuitionBase);
233 else
235 cliprectfill(scr, rp, x1, y1, x2, y1 + DWF_THICK_Y - 1, IntuitionBase);
236 cliprectfill(scr, rp, x2 - DWF_THICK_X + 1, y1 + DWF_THICK_Y, x2, y2, IntuitionBase);
237 cliprectfill(scr, rp, x1, y2 - DWF_THICK_Y + 1, x2 - DWF_THICK_X, y2, IntuitionBase);
238 cliprectfill(scr, rp, x1, y1 + DWF_THICK_Y, x1 + DWF_THICK_X - 1, y2 - DWF_THICK_Y, IntuitionBase);
242 /***********************************************************************************/
244 #if 0
245 IPTR DragBarClass__GM_RENDER(Class *cl, struct Gadget *g, struct gpRender * msg)
247 EnterFunc(bug("DragBar::Render()\n"));
248 /* We will let the AROS gadgetclass test if it is safe to render */
250 if ( DoSuperMethodA(cl, (Object *)g, (Msg)msg) != 0)
252 struct DrawInfo *dri = msg->gpr_GInfo->gi_DrInfo;
253 UWORD *pens = dri->dri_Pens;
254 struct RastPort *rp = msg->gpr_RPort;
255 struct IBox container;
256 struct Window *win = msg->gpr_GInfo->gi_Window;
257 struct TextExtent te;
259 GetGadgetIBox(g, msg->gpr_GInfo, &container);
261 if (container.Width <= 1 || container.Height <= 1)
262 return;
265 /* Clear the dragbar */
267 SetAPen(rp, (win->Flags & WFLG_WINDOWACTIVE) ?
268 pens[FILLPEN] : pens[BACKGROUNDPEN]);
270 SetDrMd(rp, JAM1);
272 D(bug("Filling from (%d, %d) to (%d, %d)\n",
273 container.Left,
274 container.Top,
275 container.Left + container.Width - 1,
276 container.Top + container.Height - 1));
278 RectFill(rp,
279 container.Left,
280 container.Top,
281 container.Left + container.Width - 1,
282 container.Top + container.Height - 2);
284 /* Draw a thin dark line around the bar */
286 SetAPen(rp, pens[SHINEPEN]);
287 RectFill(rp,container.Left,
288 container.Top,
289 container.Left,
290 container.Top + container.Height - 1 - ((container.Left == 0) ? 0 : 1));
291 RectFill(rp,container.Left + 1,
292 container.Top,
293 container.Left + container.Width - 1,
294 container.Top);
296 SetAPen(rp,pens[SHADOWPEN]);
297 RectFill(rp,container.Left + container.Width - 1,
298 container.Top + 1,
299 container.Left + container.Width - 1,
300 container.Top + container.Height - 1);
301 RectFill(rp,container.Left + ((container.Left == 0) ? 1 : 0),
302 container.Top + container.Height - 1,
303 container.Left + container.Width - 2,
304 container.Top + container.Height - 1);
306 /* Render the titlebar */
307 if (NULL != win->Title)
309 ULONG textlen, titlelen;
311 SetFont(rp, dri->dri_Font);
313 titlelen = strlen(win->Title);
314 textlen = TextFit(rp
315 , win->Title
316 , titlelen
317 , &te
318 , NULL
320 , container.Width - 6
321 , container.Height);
323 SetAPen(rp, pens[(win->Flags & WFLG_WINDOWACTIVE) ? FILLTEXTPEN : TEXTPEN]);
324 Move(rp, container.Left + 3, container.Top + dri->dri_Font->tf_Baseline + 2);
326 Text(rp, win->Title, textlen);
329 } /* if (allowed to render) */
331 return (IPTR)0;
333 #endif
335 /***********************************************************************************/
337 IPTR DragBarClass__GM_GOACTIVE(Class *cl, struct Gadget *g, struct gpInput *msg)
339 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
340 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
341 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
342 struct InputEvent *ie = msg->gpi_IEvent;
343 IPTR retval = GMR_NOREUSE;
345 if (ie)
347 /* The gadget was activated via mouse input */
348 struct dragbar_data *data;
349 struct Window *w;
351 /* There is no point in rerendering ourseleves here, as this is done
352 by a call to RefreshWindowFrame() in the intuition inputhandler
355 w = msg->gpi_GInfo->gi_Window;
357 data = INST_DATA(cl, g);
359 #ifdef USEWINDOWLOCK
360 /* do NOT ObtainSemaphore here since this would lead to deadlocks!!! */
361 /* when the semaphore can not be obtained we simply ignore gadget activation */
363 /* in movehack the task that locks windowlock is the one that calls MoveWindow*/
364 if (!(AttemptSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock)))
366 goto fail;
368 data->drag_windowlock = TRUE;
369 #endif
371 data->curleft = w->LeftEdge;
372 data->curtop = w->TopEdge;
374 data->startleft = w->LeftEdge;
375 data->starttop = w->TopEdge;
377 data->mousex = w->WScreen->MouseX - data->curleft;
378 data->mousey = w->WScreen->MouseY - data->curtop;
380 data->drag_refreshed = TRUE;
382 data->rp = CloneRastPort(&w->WScreen->RastPort);
383 if (data->rp)
386 /* Lock all layers while the window is dragged.
387 * Get the gadget lock first to avoid deadlocks
388 * with ObtainGIRPort. */
390 D(bug("locking all layers\n"));
392 if (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE))
394 #ifdef USEGADGETLOCK
395 ObtainSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
396 data->drag_inputhandlerlock = TRUE;
398 if (AttemptSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock))
400 data->drag_gadgetlock = TRUE;
402 else
404 goto fail;
406 #endif
407 #ifndef DELAYEDDRAG
408 LockLayers(&w->WScreen->LayerInfo);
409 data->drag_layerlock = TRUE;
410 #endif
411 } else {
412 /* MOVEHACK ? */
413 if (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_PRIVILEDGEDREFRESH)
415 #ifdef __MORPHOS__
416 data->movetask =
417 NewCreateTask(TASKTAG_CODETYPE, CODETYPE_PPC, TASKTAG_PC, (ULONG)MoveTask,
418 TASKTAG_PRI, 0,
419 TASKTAG_PPC_ARG1,(ULONG)data,
420 TASKTAG_PPC_ARG2,(ULONG)w,
421 TASKTAG_PPC_ARG3,(ULONG)w->WScreen,
422 TASKTAG_PPC_ARG4,(ULONG)IntuitionBase,
423 TAG_DONE);
424 #else
425 // FIXME!
426 /* FIXME: Implemente MOVEHACK support for AROS (?) */
427 #endif
431 SetDrMd(data->rp, COMPLEMENT);
433 #ifndef DELAYEDDRAG
434 if (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE))
435 drawwindowframe(w->WScreen
436 , data->rp
437 , data->curleft
438 , data->curtop
439 , data->curleft + w->Width - 1
440 , data->curtop + w->Height - 1
441 , IntuitionBase
444 data->isrendered = TRUE;
445 #endif
447 data->drag_canceled = FALSE;
450 UQUAD currenttime;
452 currenttime = ie->ie_TimeStamp.tv_secs;
453 currenttime = currenttime * 50;
454 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
456 data->lasteventtime = currenttime;
459 /* size mouse bounds such that mouse pointer cannot move if window cannot move, if offscreenlayers is turned off */
460 if (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS)) {
461 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
462 iihd->MouseBoundsActiveFlag = TRUE;
463 iihd->MouseBoundsLeft = data->mousex;
464 iihd->MouseBoundsRight = w->WScreen->Width - (w->Width - data->mousex);
465 iihd->MouseBoundsTop = data->mousey;
466 iihd->MouseBoundsBottom = w->WScreen->Height - (w->Height - data->mousey);
469 return GMR_MEACTIVE;
472 fail:
473 if (data->drag_layerlock)
475 UnlockLayers(&w->WScreen->LayerInfo);
476 data->drag_layerlock = FALSE;
480 #ifdef USEGADGETLOCK
481 if (data->drag_gadgetlock)
483 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock);
484 data->drag_gadgetlock = FALSE;
487 if (data->drag_inputhandlerlock)
489 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
490 data->drag_inputhandlerlock = FALSE;
492 #endif
494 #ifdef USEWINDOWLOCK
495 if (data->drag_windowlock)
497 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
498 data->drag_windowlock = FALSE;
500 #endif
503 return retval;
507 /***********************************************************************************/
509 IPTR DragBarClass__GM_MOVETEST(Class *cl, struct Gadget *g, struct gpInput *msg)
511 IPTR retval = MOVETEST_MOVE;
512 #ifdef SKINS
513 struct dragbar_data *data = INST_DATA(cl, g);
514 struct Window *w = msg->gpi_GInfo->gi_Window;
515 struct InputEvent myie;
516 LONG new_left;
517 LONG new_top;
519 CopyMem(msg->gpi_IEvent,&myie,sizeof (struct InputEvent));
520 myie.ie_Code = 0x68; //mouse_leftpress
522 /* Can we move to the new position, or is window at edge of display ? */
523 new_left = msg->gpi_Mouse.X - data->mousex;
524 new_top = msg->gpi_Mouse.Y - data->mousey;
526 if ((!((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (w->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS))) ||
527 MatchHotkey(&myie,IA_TOGGLEOFFSCREEN,IntuitionBase))
529 if (new_left < 0)
531 msg->gpi_Mouse.X -= new_left;
532 retval = MOVETEST_ADJUSTPOS;
535 if (new_top < 0)
537 msg->gpi_Mouse.Y -= new_top;
538 retval = MOVETEST_ADJUSTPOS;
541 if (new_left + w->Width > w->WScreen->Width)
543 msg->gpi_Mouse.X -= new_left - (w->WScreen->Width - w->Width);
544 retval = MOVETEST_ADJUSTPOS;
547 if (new_top + w->Height > w->WScreen->Height)
549 msg->gpi_Mouse.Y -= new_top - (w->WScreen->Height - w->Height);
550 retval = MOVETEST_ADJUSTPOS;
553 #endif
555 return retval;
559 /***********************************************************************************/
561 IPTR DragBarClass__GM_HANDLEINPUT(Class *cl, struct Gadget *g, struct gpInput *msg)
563 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
564 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
565 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
566 struct GadgetInfo *gi = msg->gpi_GInfo;
567 IPTR retval = GMR_MEACTIVE;
569 if (gi)
571 struct InputEvent *ie = msg->gpi_IEvent;
572 struct dragbar_data *data = INST_DATA(cl, g);
573 struct Window *w = msg->gpi_GInfo->gi_Window;
575 switch (ie->ie_Class)
577 case IECLASS_RAWMOUSE:
578 switch (ie->ie_Code)
580 case MENUDOWN:
581 retval = GMR_NOREUSE;
582 data->drag_canceled = TRUE;
583 break;
585 case SELECTUP:
586 retval = GMR_NOREUSE;
587 break;
590 case IECODE_NOBUTTON:
592 struct Screen *scr = w->WScreen;
593 struct InputEvent myie;
594 LONG new_left;
595 LONG new_top;
597 /* Can we move to the new position, or is window at edge of display ? */
598 new_left = scr->MouseX - data->mousex;
599 new_top = scr->MouseY - data->mousey;
601 CopyMem(ie,&myie,sizeof (struct InputEvent));
602 myie.ie_Code = SELECTDOWN; //mouse_leftpress
604 #ifdef SKINS
605 if ((!((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (w->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS))) ||
606 MatchHotkey(&myie,IA_TOGGLEOFFSCREEN,IntuitionBase))
607 #else
608 if (!((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (w->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS)))
609 #endif
611 if (new_left < 0)
613 data->mousex += new_left;
614 new_left = 0;
617 if (new_top < 0)
619 data->mousey += new_top;
620 new_top = 0;
623 if (new_left + w->Width > scr->Width)
625 LONG correct_left;
626 correct_left = scr->Width - w->Width; /* align to screen border */
627 data->mousex += new_left - correct_left;
628 new_left = correct_left;
631 if (new_top + w->Height > scr->Height)
633 LONG correct_top;
634 correct_top = scr->Height - w->Height; /* align to screen border */
635 data->mousey += new_top - correct_top;
636 new_top = correct_top;
640 if (data->curleft != new_left || data->curtop != new_top)
642 SetDrMd(data->rp, COMPLEMENT);
644 if ((data->isrendered) && (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)))
646 /* Erase old frame */
647 drawwindowframe(w->WScreen
648 , data->rp
649 , data->curleft
650 , data->curtop
651 , data->curleft + w->Width - 1
652 , data->curtop + w->Height - 1
653 , IntuitionBase
657 data->curleft = new_left;
658 data->curtop = new_top;
660 if (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)
662 WORD newx = new_left - w->LeftEdge, newy = new_top - w->TopEdge;
664 if (newx || newy)
666 UQUAD currenttime;
668 currenttime = ie->ie_TimeStamp.tv_secs;
669 currenttime = currenttime * 50;
670 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
672 if (currenttime > data->lasteventtime + 10) //10 delay should result in intuitick freq
674 ih_fire_intuimessage(w,
675 IDCMP_CHANGEWINDOW,
676 CWCODE_MOVESIZE,
678 IntuitionBase);
679 data->lasteventtime = currenttime;
682 if (data->movetask)
684 Forbid();
685 Signal(data->movetask,WSIG_MOVE);
686 Permit();
688 CheckLayers(w->WScreen, IntuitionBase);
690 else
692 struct Requester *req;
694 LockLayers(&w->WScreen->LayerInfo);
696 w->LeftEdge += newx;
697 w->TopEdge += newy;
699 if (BLAYER(w))
701 MoveSizeLayer(BLAYER(w), newx, newy , 0, 0);
704 MoveSizeLayer(WLAYER(w), newx, newy, 0, 0);
706 for (req = w->FirstRequest; req; req = req->OlderRequest)
708 struct Layer *layer = req->ReqLayer;
710 if (layer)
712 int dx, dy, dw, dh;
713 int left, top, right, bottom;
715 left = data->curleft + req->LeftEdge;
716 top = data->curtop + req->TopEdge;
717 right = left + req->Width - 1;
718 bottom = top + req->Height - 1;
720 if (left > data->curleft + w->Width - 1)
721 left = data->curleft + w->Width - 1;
723 if (top > data->curtop + w->Height - 1)
724 top = data->curtop + w->Height - 1;
726 if (right > data->curleft + w->Width - 1)
727 right = data->curleft + w->Width - 1;
729 if (bottom > data->curtop + w->Height - 1)
730 bottom = data->curtop + w->Height - 1;
732 dx = left - layer->bounds.MinX;
733 dy = top - layer->bounds.MinY;
734 dw = right - left - layer->bounds.MaxX + layer->bounds.MinX;
735 dh = bottom - top - layer->bounds.MaxY + layer->bounds.MinY;
737 MoveSizeLayer(layer, dx, dy, dw, dh);
741 CheckLayers(w->WScreen, IntuitionBase);
743 UnlockLayers(&w->WScreen->LayerInfo);
747 else
749 #ifdef DELAYEDDRAG
750 if ((!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)) && (!data->drag_layerlock))
752 LockLayers(&w->WScreen->LayerInfo);
753 data->drag_layerlock = TRUE;
755 #endif
756 /* Rerender the window frame */
757 drawwindowframe(w->WScreen
758 , data->rp
759 , data->curleft
760 , data->curtop
761 , data->curleft + w->Width - 1
762 , data->curtop + w->Height - 1
763 , IntuitionBase);
764 data->isrendered = TRUE;
769 retval = GMR_MEACTIVE;
771 break;
774 default:
775 retval = GMR_NOREUSE;
776 if (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)) data->drag_canceled = TRUE;
777 break;
779 } /* switch (ie->ie_Code) */
780 break;
782 case IECLASS_TIMER:
783 #ifdef DELAYEDDRAG
784 if ((!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)) && (!data->drag_layerlock))
786 UQUAD currenttime;
788 currenttime = ie->ie_TimeStamp.tv_secs;
789 currenttime = currenttime * 50;
790 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
792 if (currenttime > data->lasteventtime + 10)
794 LockLayers(&w->WScreen->LayerInfo);
795 data->drag_layerlock = TRUE;
797 drawwindowframe(w->WScreen
798 , data->rp
799 , data->curleft
800 , data->curtop
801 , data->curleft + w->Width - 1
802 , data->curtop + w->Height - 1
803 , IntuitionBase
805 data->lasteventtime = currenttime;
806 data->isrendered = TRUE;
809 #endif
811 if (data->movetask)
813 UQUAD currenttime;
815 currenttime = ie->ie_TimeStamp.tv_secs;
816 currenttime = currenttime * 50;
817 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
819 if ((!data->drag_refreshed) && currenttime > data->lasteventtime + 10) //10 delay should result in intuitick freq
821 ih_fire_intuimessage( w,
822 IDCMP_CHANGEWINDOW,
823 CWCODE_MOVESIZE,
825 IntuitionBase);
826 data->drag_refreshed = TRUE;
827 data->lasteventtime = currenttime;
829 CheckLayers(w->WScreen,IntuitionBase);
831 break;
832 } /* switch (ie->ie_Class) */
834 } /* if (gi) */
836 return retval;
839 /***********************************************************************************/
841 IPTR DragBarClass__GM_GOINACTIVE(Class *cl, struct Gadget *g, struct gpGoInactive *msg)
843 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
844 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
845 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
846 struct dragbar_data *data;
847 struct Window *w;
849 data = INST_DATA(cl, g);
851 w = msg->gpgi_GInfo->gi_Window;
853 /* Always clear last drawn frame */
855 if (data->isrendered && data->rp && (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE)))
858 SetDrMd(data->rp, COMPLEMENT);
860 /* Erase old frame */
861 drawwindowframe(w->WScreen
862 , data->rp
863 , data->curleft
864 , data->curtop
865 , data->curleft + w->Width - 1
866 , data->curtop + w->Height - 1
867 , IntuitionBase
872 data->isrendered = FALSE;
874 if (!data->drag_refreshed) CheckLayers(w->WScreen, IntuitionBase);
876 Forbid();
877 if (data->movetask)
879 Signal(data->movetask,WSIG_DIE);
880 data->movetask = 0;
882 Permit();
884 if (!data->drag_canceled)// && !(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE))
886 MoveWindow(w
887 , data->curleft - w->LeftEdge /* dx */
888 , data->curtop - w->TopEdge /* dy */
893 if (data->drag_canceled && (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OPAQUEMOVE))
895 MoveWindow(w
896 , data->startleft - w->LeftEdge /* dx */
897 , data->starttop - w->TopEdge /* dy */
902 ih_fire_intuimessage(w,
903 IDCMP_CHANGEWINDOW,
904 CWCODE_MOVESIZE,
906 IntuitionBase);
908 data->drag_canceled = TRUE;
910 if (data->drag_layerlock)
912 UnlockLayers(&w->WScreen->LayerInfo);
913 data->drag_layerlock = FALSE;
916 #ifdef USEGADGETLOCK
917 if (data->drag_gadgetlock)
919 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock);
920 data->drag_gadgetlock = FALSE;
923 if (data->drag_inputhandlerlock)
925 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
926 data->drag_inputhandlerlock = FALSE;
928 #endif
930 #ifdef USEWINDOWLOCK
931 if (data->drag_windowlock)
933 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
934 data->drag_windowlock = FALSE;
936 #endif
938 /* User through with drag operation. Unlock layers and free
939 rastport clone
942 if (data->rp)
944 FreeRastPort(data->rp);
945 data->rp = NULL;
948 /* shut off mouse bounds checking. */
949 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
950 iihd->MouseBoundsActiveFlag = FALSE;
952 return TRUE;
957 /***********************************************************************************/
959 IPTR DragBarClass__NOP(Class *cl, Object *o, Msg msg)
961 return (IPTR)0;
964 /***********************************************************************************/
966 IPTR DragBarClass__GM_HITTEST(Class *cl, Object *o, Msg msg)
968 return (IPTR)1;
971 /***********************************************************************************/
973 IPTR DragBarClass__OM_NEW(Class *cl, Object *o, Msg msg)
975 struct Gadget *g = (struct Gadget *)DoSuperMethodA(cl, o, msg);
976 if (g)
978 g->GadgetType |= GTYP_SYSGADGET | GTYP_WDRAGGING;
981 return (IPTR)g;
984 /***********************************************************************************/
986 /*********************
987 ** The SizeButtonClass
988 *********************/
990 #ifdef SKINS
991 #define SIZETYPE_RIGHTBOTTOM 1
992 #define SIZETYPE_RIGHT 2
993 #define SIZETYPE_BOTTOM 3
994 #define SIZETYPE_LEFTBOTTOM 4
995 #define SIZETYPE_LEFT 5
996 #define SIZETYPE_LEFTTOP 6
997 #define SIZETYPE_TOP 7
998 #define SIZETYPE_RIGHTTOP 8
999 #endif
1001 /***********************************************************************************/
1003 void smartresize(struct Window *w,struct sizebutton_data *data,Class *cl)
1005 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1006 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
1007 struct IIHData *iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
1009 LockLayers(&w->WScreen->LayerInfo);
1011 if (BLAYER(w))
1013 struct Hook *backfill;
1015 backfill = BLAYER(w)->BackFill;
1016 BLAYER(w)->BackFill = LAYERS_NOBACKFILL;
1018 /* move outer window first */
1019 MoveSizeLayer(BLAYER(w), data->left - w->LeftEdge, data->top - w->TopEdge, data->width - w->Width, data->height - w->Height);
1021 BLAYER(w)->BackFill = backfill;
1025 struct Hook *backfill;
1027 backfill = WLAYER(w)->BackFill;
1028 WLAYER(w)->BackFill = LAYERS_NOBACKFILL;
1029 MoveSizeLayer(WLAYER(w), data->left - w->LeftEdge, data->top - w->TopEdge, data->width - w->Width, data->height - w->Height);
1030 WLAYER(w)->BackFill = backfill;
1033 w->TopEdge = data->top;
1034 w->LeftEdge = data->left;
1035 w->Width = data->width;
1036 w->Height = data->height;
1038 IW(w)->specialflags |= SPFLAG_LAYERRESIZED;
1040 if ((iihdata->ActiveGadget) && (w == iihdata->GadgetInfo.gi_Window))
1042 GetGadgetDomain(iihdata->ActiveGadget,
1043 iihdata->GadgetInfo.gi_Screen,
1044 iihdata->GadgetInfo.gi_Window,
1045 NULL,
1046 &iihdata->GadgetInfo.gi_Domain);
1049 /* Relayout GFLG_REL??? gadgets */
1050 DoGMLayout(w->FirstGadget, w, NULL, -1, FALSE, IntuitionBase);
1052 ih_fire_intuimessage(w,
1053 IDCMP_NEWSIZE,
1056 IntuitionBase);
1058 CheckLayers(w->WScreen, IntuitionBase);
1060 UnlockLayers(&w->WScreen->LayerInfo);
1063 /***********************************************************************************/
1065 IPTR SizeButtonClass__GM_GOACTIVE(Class *cl, struct Gadget *g, struct gpInput *msg)
1067 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1068 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1069 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
1070 struct InputEvent *ie = msg->gpi_IEvent;
1071 IPTR retval = GMR_NOREUSE;
1073 if (ie)
1075 /* The gadget was activated via mouse input */
1076 struct sizebutton_data *data;
1077 struct Window *w;
1079 /* There is no point in rerendering ourseleves her, as this
1080 is done by a call to RefreshWindowFrame() in the intuition inputhandler
1083 w = msg->gpi_GInfo->gi_Window;
1085 data = INST_DATA(cl, g);
1087 #ifdef USEWINDOWLOCK
1088 /* do NOT ObtainSemaphore here since this would lead to deadlocks!!! */
1089 /* when the semaphore can not be obtained we simply ignore gadget activation */
1090 if (!(AttemptSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock)))
1092 goto fail;
1094 data->drag_windowlock = TRUE;
1095 #endif
1097 data->height = data->Height = w->Height;
1098 data->width = data->Width = w->Width;
1099 data->left = data->LeftEdge = w->LeftEdge;
1100 data->top = data->TopEdge = w->TopEdge;
1102 data->mouseoffsetx = w->WScreen->MouseX;
1103 data->mouseoffsety = w->WScreen->MouseY;
1105 data->drag_refreshed = TRUE;
1106 data->drag_ticks = 2;
1108 #ifdef SKINS
1109 data->drag_type = 0;
1111 if (w->MouseX < IW(w)->sizeimage_width)
1113 if (w->MouseY < IW(w)->sizeimage_height) data->drag_type = SIZETYPE_LEFTTOP;
1114 if (w->MouseY > w->Height - IW(w)->sizeimage_height - 1) data->drag_type = SIZETYPE_LEFTBOTTOM;
1115 if (!data->drag_type) data->drag_type = SIZETYPE_LEFT;
1118 if ((!data->drag_type) && (w->MouseX >= IW(w)->sizeimage_width) && (w->MouseX <= w->Width - 1 - IW(w)->sizeimage_width))
1120 if (w->MouseY < w->BorderTop)
1122 data->drag_type = SIZETYPE_TOP;
1123 } else {
1124 data->drag_type = SIZETYPE_BOTTOM;
1128 if ((!data->drag_type) && (w->MouseX > IW(w)->sizeimage_width))
1130 if (w->MouseY < IW(w)->sizeimage_height) data->drag_type = SIZETYPE_RIGHTTOP;
1131 if (w->MouseY > w->Height - IW(w)->sizeimage_height - 1) data->drag_type = SIZETYPE_RIGHTBOTTOM;
1132 if (!data->drag_type) data->drag_type = SIZETYPE_RIGHT;
1135 if (!data->drag_type) goto fail;
1136 #endif
1138 data->rp = CloneRastPort(&w->WScreen->RastPort);
1139 if (data->rp)
1141 /* Lock all layers while the window is resized.
1142 * Get the gadget lock first to avoid deadlocks
1143 * with ObtainGIRPort. */
1145 if (!OPAQUESIZE)
1147 #ifdef USEGADGETLOCK
1148 ObtainSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
1149 data->drag_inputhandlerlock = TRUE;
1151 if (AttemptSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock))
1153 data->drag_gadgetlock = TRUE;
1155 else
1157 goto fail;
1159 #endif
1160 #ifndef DELAYEDSIZE
1161 LockLayers(&w->WScreen->LayerInfo);
1162 data->drag_layerlock = TRUE;
1163 #endif
1166 SetDrMd(data->rp, COMPLEMENT);
1168 #ifndef DELAYEDSIZE
1169 if(!OPAQUESIZE)
1170 drawwindowframe(w->WScreen
1171 , data->rp
1172 , data->left
1173 , data->top
1174 , data->left + data->width - 1
1175 , data->top + data->height - 1
1176 , IntuitionBase
1179 data->isrendered = TRUE;
1180 #endif
1183 UQUAD currenttime;
1185 currenttime = ie->ie_TimeStamp.tv_secs;
1186 currenttime = currenttime * 50;
1187 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
1188 data->lasteventtime = currenttime;
1191 data->drag_canceled = FALSE;
1193 /* size mouse bounds such that mouse pointer cannot move if window cannot size, if offscreenlayers is turned off */
1194 if (!(GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS)) {
1195 struct IIHData *iihd = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
1196 LONG mousex = data->mouseoffsetx - data->LeftEdge;
1197 LONG mousey = data->mouseoffsety - data->TopEdge;
1199 iihd->MouseBoundsActiveFlag = TRUE;
1200 iihd->MouseBoundsLeft = 0;
1201 iihd->MouseBoundsRight = w->WScreen->Width - (w->Width - mousex);
1202 iihd->MouseBoundsTop = 0;
1203 iihd->MouseBoundsBottom = w->WScreen->Height - (w->Height - mousey);
1206 return GMR_MEACTIVE;
1209 fail:
1210 if (data->drag_layerlock)
1212 UnlockLayers(&w->WScreen->LayerInfo);
1213 data->drag_layerlock = FALSE;
1217 #ifdef USEGADGETLOCK
1218 if (data->drag_gadgetlock)
1220 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock);
1221 data->drag_gadgetlock = FALSE;
1224 if (data->drag_inputhandlerlock)
1226 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
1227 data->drag_inputhandlerlock = FALSE;
1229 #endif
1231 #ifdef USEWINDOWLOCK
1232 if (data->drag_windowlock)
1234 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
1235 data->drag_windowlock = FALSE;
1237 #endif
1240 return retval;
1244 /***********************************************************************************/
1246 IPTR SizeButtonClass__GM_HANDLEINPUT(Class *cl, struct Gadget *g, struct gpInput *msg)
1248 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1249 #ifdef DELAYEDSIZE
1250 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
1251 #endif
1252 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1253 struct GadgetInfo *gi = msg->gpi_GInfo;
1254 IPTR retval = GMR_MEACTIVE;
1256 if (gi)
1258 struct InputEvent *ie = msg->gpi_IEvent;
1259 struct sizebutton_data *data = INST_DATA(cl, g);
1260 struct Window *w = msg->gpi_GInfo->gi_Window;
1262 switch (ie->ie_Class)
1264 case IECLASS_RAWMOUSE:
1265 switch (ie->ie_Code)
1267 case SELECTUP:
1268 retval = GMR_NOREUSE;
1269 break;
1272 case IECODE_NOBUTTON:
1274 struct Screen *scr = w->WScreen;
1275 LONG new_width = 0;
1276 LONG new_height = 0;
1278 /* Can we move to the new position, or is window at edge of display ? */
1279 #ifdef SKINS
1280 switch(data->drag_type)
1282 case SIZETYPE_BOTTOM:
1283 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1284 new_width = data->Width;
1285 break;
1287 case SIZETYPE_TOP:
1288 new_height = data->Height + data->mouseoffsety - scr->MouseY;
1289 new_width = data->Width;
1290 break;
1292 case SIZETYPE_RIGHTBOTTOM:
1293 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1294 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1295 break;
1297 case SIZETYPE_LEFTTOP:
1298 new_width = data->Width + data->mouseoffsetx - scr->MouseX;
1299 new_height = data->Height + data->mouseoffsety - scr->MouseY;
1300 break;
1302 case SIZETYPE_RIGHTTOP:
1303 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1304 new_height = data->Height + data->mouseoffsety - scr->MouseY;
1305 break;
1307 case SIZETYPE_LEFTBOTTOM:
1308 new_width = data->Width + data->mouseoffsetx - scr->MouseX;
1309 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1310 break;
1312 case SIZETYPE_LEFT:
1313 new_width = data->Width + data->mouseoffsetx - scr->MouseX;
1314 new_height = data->Height;
1315 break;
1317 case SIZETYPE_RIGHT:
1318 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1319 new_height = data->Height;
1320 break;
1322 #else
1323 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1324 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1325 #endif
1326 if (new_width < 0)
1327 new_width = 1;
1329 if (w->MinWidth != 0 && new_width < (ULONG)w->MinWidth)
1330 new_width = w->MinWidth;
1332 if (w->MaxWidth != 0 && new_width > (ULONG)w->MaxWidth)
1333 new_width = w->MaxWidth;
1335 if (new_height < 0)
1336 new_height = 1;
1338 if (w->MinHeight != 0 && new_height < (ULONG)w->MinHeight)
1339 new_height = w->MinHeight;
1341 if (w->MaxHeight != 0 && new_height > (ULONG)w->MaxHeight)
1342 new_height = w->MaxHeight;
1345 #ifdef SKINS
1346 if (!((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (w->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS)))
1348 /* limit dimensions so window fits on the screen */
1349 switch (data->drag_type)
1351 case SIZETYPE_RIGHT:
1352 case SIZETYPE_RIGHTTOP:
1353 case SIZETYPE_RIGHTBOTTOM:
1354 if (data->left + new_width > scr->Width)
1355 new_width = scr->Width - data->left;
1356 break;
1358 case SIZETYPE_LEFT:
1359 case SIZETYPE_LEFTBOTTOM:
1360 case SIZETYPE_LEFTTOP:
1361 if (data->LeftEdge + data->Width - new_width < 0)
1362 new_width += (data->LeftEdge + data->Width - new_width);
1363 break;
1366 switch (data->drag_type)
1368 case SIZETYPE_LEFTBOTTOM:
1369 case SIZETYPE_BOTTOM:
1370 case SIZETYPE_RIGHTBOTTOM:
1371 if (data->top + new_height > scr->Height)
1372 new_height = scr->Height - data->top;
1373 break;
1375 case SIZETYPE_TOP:
1376 case SIZETYPE_LEFTTOP:
1377 case SIZETYPE_RIGHTTOP:
1378 if (data->TopEdge + data->Height - new_height < 0)
1379 new_height += (data->TopEdge + data->Height - new_height);
1380 break;
1383 #endif
1385 if (data->height != new_height || data->width != new_width)
1387 SetDrMd(data->rp, COMPLEMENT);
1389 if (data->isrendered && !OPAQUESIZE)
1391 /* Erase old frame */
1392 drawwindowframe(w->WScreen
1393 , data->rp
1394 , data->left
1395 , data->top
1396 , data->left + data->width - 1
1397 , data->top + data->height - 1
1398 , IntuitionBase
1403 #ifdef SKINS
1404 switch(data->drag_type)
1406 case SIZETYPE_LEFT:
1407 data->left = data->LeftEdge + data->Width - new_width;
1408 break;
1410 case SIZETYPE_LEFTTOP:
1411 data->left = data->LeftEdge + data->Width - new_width;
1412 data->top = data->TopEdge + data->Height - new_height;
1413 break;
1415 case SIZETYPE_LEFTBOTTOM:
1416 data->left = data->LeftEdge + data->Width - new_width;
1417 break;
1419 case SIZETYPE_RIGHTTOP:
1420 data->top = data->TopEdge + data->Height - new_height;
1421 break;
1423 case SIZETYPE_TOP:
1424 data->top = data->TopEdge + data->Height - new_height;
1425 break;
1427 #endif
1429 data->width = new_width;
1430 data->height = new_height;
1432 /* Rerender the window frame */
1434 #ifdef DELAYEDSIZE
1435 if (!data->drag_layerlock && !OPAQUESIZE)
1437 LockLayers(&w->WScreen->LayerInfo);
1438 data->drag_layerlock = TRUE;
1440 #endif
1442 data->drag_refreshed = FALSE;
1443 data->drag_ticks = 2;
1445 if (!OPAQUESIZE)
1446 drawwindowframe(w->WScreen
1447 , data->rp
1448 , data->left
1449 , data->top
1450 , data->left + data->width - 1
1451 , data->top + data->height - 1
1452 , IntuitionBase
1455 data->isrendered = TRUE;
1459 retval = GMR_MEACTIVE;
1461 break;
1464 default:
1465 retval = GMR_NOREUSE;
1466 data->drag_canceled = TRUE;
1467 break;
1471 } /* switch (ie->ie_Code) */
1472 break;
1474 case IECLASS_TIMER:
1475 #ifdef DELAYEDSIZE
1476 if (!data->drag_layerlock && !OPAQUESIZE)
1478 UQUAD currenttime;
1479 currenttime = ie->ie_TimeStamp.tv_secs;
1480 currenttime = currenttime * 50;
1481 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
1483 if (currenttime > data->lasteventtime + 10)
1485 LockLayers(&w->WScreen->LayerInfo);
1486 data->drag_layerlock = TRUE;
1488 drawwindowframe(w->WScreen
1489 , data->rp
1490 , data->left
1491 , data->top
1492 , data->left + data->width - 1
1493 , data->top + data->height - 1
1494 , IntuitionBase
1496 data->lasteventtime = currenttime;
1497 data->isrendered = TRUE;
1500 #endif
1502 #if USE_OPAQUESIZE
1503 if (OPAQUESIZE)
1505 data->drag_ticks --;
1506 if (!data->drag_refreshed && !data->drag_ticks && WindowsReplied(w->WScreen,IntuitionBase))
1508 smartresize(w,data,cl);
1509 data->drag_refreshed = TRUE;
1510 data->drag_ticks = 2;
1513 #endif /* USE_OPAQUESIZE */
1515 break;
1517 #ifdef __MORPHOS__
1518 case IECLASS_NEWTIMER:
1519 if (OPAQUESIZE && !data->drag_refreshed && WindowsReplied(w->WScreen,IntuitionBase))
1521 smartresize(w,data,cl);
1522 data->drag_refreshed = TRUE;
1523 data->drag_ticks = 2;
1525 break;
1526 #endif /* __MORPHOS__ */
1528 } /* switch (ie->ie_Class) */
1530 } /* if (gi) */
1532 return retval;
1535 /***********************************************************************************/
1537 IPTR SizeButtonClass__GM_GOINACTIVE(Class *cl, struct Gadget *g, struct gpGoInactive *msg)
1539 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1540 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1541 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
1542 struct sizebutton_data *data;
1543 struct Window *w;
1545 data = INST_DATA(cl, g);
1546 w = msg->gpgi_GInfo->gi_Window;
1548 /* Allways clear last drawn frame */
1550 if (data->isrendered && data->rp)
1553 SetDrMd(data->rp, COMPLEMENT);
1555 /* Erase old frame */
1556 if (!OPAQUESIZE)
1557 drawwindowframe(w->WScreen
1558 , data->rp
1559 , data->left
1560 , data->top
1561 , data->left + data->width - 1
1562 , data->top + data->height - 1
1563 , IntuitionBase
1567 else
1569 if (!OPAQUESIZE)
1571 data->drag_canceled = TRUE;
1574 data->isrendered = FALSE;
1576 if (data->drag_layerlock)
1578 UnlockLayers(&w->WScreen->LayerInfo);
1579 data->drag_layerlock = FALSE;
1582 #ifdef USEGADGETLOCK
1583 if (data->drag_gadgetlock)
1585 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock);
1586 data->drag_gadgetlock = FALSE;
1589 if (data->drag_inputhandlerlock)
1591 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
1592 data->drag_inputhandlerlock = FALSE;
1594 #endif
1596 #ifdef USEWINDOWLOCK
1597 if (data->drag_windowlock)
1599 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
1600 data->drag_windowlock = FALSE;
1602 #endif
1604 //jDc: workarounds refresh pb on GZZ window resize
1605 ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->ActiveSysGadget->Flags &= ~GFLG_SELECTED;
1607 if (!data->drag_canceled || OPAQUESIZE)
1609 if (OPAQUESIZE && data->drag_canceled)
1611 DoMoveSizeWindow(w,data->LeftEdge,data->TopEdge,data->Width,data->Height,TRUE,IntuitionBase);
1613 else
1615 DoMoveSizeWindow(w,data->left,data->top,data->width,data->height,TRUE,IntuitionBase);
1617 //ChangeWindowBox(w,data->left,data->top,data->width,data->height);
1619 data->drag_canceled = TRUE;
1621 /* User through with drag operation. Unlock layers and free
1622 rastport clone
1624 if (data->rp)
1626 FreeRastPort(data->rp);
1627 data->rp = NULL;
1630 /* shut off mouse bounds checking. */
1631 ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->MouseBoundsActiveFlag = FALSE;
1633 return TRUE;
1636 /***********************************************************************************/
1638 IPTR SizeButtonClass__OM_NEW(Class *cl, Object *o, Msg msg)
1640 struct Gadget *g = (struct Gadget *)DoSuperMethodA(cl, o, msg);
1641 if (g)
1643 g->GadgetType |= GTYP_SYSGADGET | GTYP_SIZING;
1646 return (IPTR)g;
1649 /***********************************************************************************/