Fixed typos in comments.
[AROS.git] / rom / intuition / windowclasses.c
blobfa280cc07366b9a6d0d045dd2fb683f58089eda5
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 //#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 throught with drag operation. Unlock layesr 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 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1250 struct GadgetInfo *gi = msg->gpi_GInfo;
1251 IPTR retval = GMR_MEACTIVE;
1253 if (gi)
1255 struct InputEvent *ie = msg->gpi_IEvent;
1256 struct sizebutton_data *data = INST_DATA(cl, g);
1257 struct Window *w = msg->gpi_GInfo->gi_Window;
1259 switch (ie->ie_Class)
1261 case IECLASS_RAWMOUSE:
1262 switch (ie->ie_Code)
1264 case SELECTUP:
1265 retval = GMR_NOREUSE;
1266 break;
1269 case IECODE_NOBUTTON:
1271 struct Screen *scr = w->WScreen;
1272 LONG new_width = 0;
1273 LONG new_height = 0;
1275 /* Can we move to the new position, or is window at edge of display ? */
1276 #ifdef SKINS
1277 switch(data->drag_type)
1279 case SIZETYPE_BOTTOM:
1280 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1281 new_width = data->Width;
1282 break;
1284 case SIZETYPE_TOP:
1285 new_height = data->Height + data->mouseoffsety - scr->MouseY;
1286 new_width = data->Width;
1287 break;
1289 case SIZETYPE_RIGHTBOTTOM:
1290 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1291 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1292 break;
1294 case SIZETYPE_LEFTTOP:
1295 new_width = data->Width + data->mouseoffsetx - scr->MouseX;
1296 new_height = data->Height + data->mouseoffsety - scr->MouseY;
1297 break;
1299 case SIZETYPE_RIGHTTOP:
1300 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1301 new_height = data->Height + data->mouseoffsety - scr->MouseY;
1302 break;
1304 case SIZETYPE_LEFTBOTTOM:
1305 new_width = data->Width + data->mouseoffsetx - scr->MouseX;
1306 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1307 break;
1309 case SIZETYPE_LEFT:
1310 new_width = data->Width + data->mouseoffsetx - scr->MouseX;
1311 new_height = data->Height;
1312 break;
1314 case SIZETYPE_RIGHT:
1315 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1316 new_height = data->Height;
1317 break;
1319 #else
1320 new_width = data->Width + scr->MouseX - data->mouseoffsetx;
1321 new_height = data->Height + scr->MouseY - data->mouseoffsety;
1322 #endif
1323 if (new_width < 0)
1324 new_width = 1;
1326 if (w->MinWidth != 0 && new_width < (ULONG)w->MinWidth)
1327 new_width = w->MinWidth;
1329 if (w->MaxWidth != 0 && new_width > (ULONG)w->MaxWidth)
1330 new_width = w->MaxWidth;
1332 if (new_height < 0)
1333 new_height = 1;
1335 if (w->MinHeight != 0 && new_height < (ULONG)w->MinHeight)
1336 new_height = w->MinHeight;
1338 if (w->MaxHeight != 0 && new_height > (ULONG)w->MaxHeight)
1339 new_height = w->MaxHeight;
1342 #ifdef SKINS
1343 if (!((GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_OFFSCREENLAYERS) && (w->WScreen->LayerInfo.Flags & LIFLG_SUPPORTS_OFFSCREEN_LAYERS)))
1345 /* limit dimensions so window fits on the screen */
1346 switch (data->drag_type)
1348 case SIZETYPE_RIGHT:
1349 case SIZETYPE_RIGHTTOP:
1350 case SIZETYPE_RIGHTBOTTOM:
1351 if (data->left + new_width > scr->Width)
1352 new_width = scr->Width - data->left;
1353 break;
1355 case SIZETYPE_LEFT:
1356 case SIZETYPE_LEFTBOTTOM:
1357 case SIZETYPE_LEFTTOP:
1358 if (data->LeftEdge + data->Width - new_width < 0)
1359 new_width += (data->LeftEdge + data->Width - new_width);
1360 break;
1363 switch (data->drag_type)
1365 case SIZETYPE_LEFTBOTTOM:
1366 case SIZETYPE_BOTTOM:
1367 case SIZETYPE_RIGHTBOTTOM:
1368 if (data->top + new_height > scr->Height)
1369 new_height = scr->Height - data->top;
1370 break;
1372 case SIZETYPE_TOP:
1373 case SIZETYPE_LEFTTOP:
1374 case SIZETYPE_RIGHTTOP:
1375 if (data->TopEdge + data->Height - new_height < 0)
1376 new_height += (data->TopEdge + data->Height - new_height);
1377 break;
1380 #endif
1382 if (data->height != new_height || data->width != new_width)
1384 SetDrMd(data->rp, COMPLEMENT);
1386 if (data->isrendered && !OPAQUESIZE)
1388 /* Erase old frame */
1389 drawwindowframe(w->WScreen
1390 , data->rp
1391 , data->left
1392 , data->top
1393 , data->left + data->width - 1
1394 , data->top + data->height - 1
1395 , IntuitionBase
1400 #ifdef SKINS
1401 switch(data->drag_type)
1403 case SIZETYPE_LEFT:
1404 data->left = data->LeftEdge + data->Width - new_width;
1405 break;
1407 case SIZETYPE_LEFTTOP:
1408 data->left = data->LeftEdge + data->Width - new_width;
1409 data->top = data->TopEdge + data->Height - new_height;
1410 break;
1412 case SIZETYPE_LEFTBOTTOM:
1413 data->left = data->LeftEdge + data->Width - new_width;
1414 break;
1416 case SIZETYPE_RIGHTTOP:
1417 data->top = data->TopEdge + data->Height - new_height;
1418 break;
1420 case SIZETYPE_TOP:
1421 data->top = data->TopEdge + data->Height - new_height;
1422 break;
1424 #endif
1426 data->width = new_width;
1427 data->height = new_height;
1429 /* Rerender the window frame */
1431 #ifdef DELAYEDSIZE
1432 if (!data->drag_layerlock && !OPAQUESIZE)
1434 LockLayers(&w->WScreen->LayerInfo);
1435 data->drag_layerlock = TRUE;
1437 #endif
1439 data->drag_refreshed = FALSE;
1440 data->drag_ticks = 2;
1442 if (!OPAQUESIZE)
1443 drawwindowframe(w->WScreen
1444 , data->rp
1445 , data->left
1446 , data->top
1447 , data->left + data->width - 1
1448 , data->top + data->height - 1
1449 , IntuitionBase
1452 data->isrendered = TRUE;
1456 retval = GMR_MEACTIVE;
1458 break;
1461 default:
1462 retval = GMR_NOREUSE;
1463 data->drag_canceled = TRUE;
1464 break;
1468 } /* switch (ie->ie_Code) */
1469 break;
1471 case IECLASS_TIMER:
1472 #ifdef DELAYEDSIZE
1473 if (!data->drag_layerlock && !OPAQUESIZE)
1475 UQUAD currenttime;
1476 currenttime = ie->ie_TimeStamp.tv_secs;
1477 currenttime = currenttime * 50;
1478 currenttime += ie->ie_TimeStamp.tv_micro / 20000;
1480 if (currenttime > data->lasteventtime + 10)
1482 LockLayers(&w->WScreen->LayerInfo);
1483 data->drag_layerlock = TRUE;
1485 drawwindowframe(w->WScreen
1486 , data->rp
1487 , data->left
1488 , data->top
1489 , data->left + data->width - 1
1490 , data->top + data->height - 1
1491 , IntuitionBase
1493 data->lasteventtime = currenttime;
1494 data->isrendered = TRUE;
1497 #endif
1499 #if USE_OPAQUESIZE
1500 if (OPAQUESIZE)
1502 data->drag_ticks --;
1503 if (!data->drag_refreshed && !data->drag_ticks && WindowsReplied(w->WScreen,IntuitionBase))
1505 smartresize(w,data,cl);
1506 data->drag_refreshed = TRUE;
1507 data->drag_ticks = 2;
1510 #endif /* USE_OPAQUESIZE */
1512 break;
1514 #ifdef __MORPHOS__
1515 case IECLASS_NEWTIMER:
1516 if (OPAQUESIZE && !data->drag_refreshed && WindowsReplied(w->WScreen,IntuitionBase))
1518 smartresize(w,data,cl);
1519 data->drag_refreshed = TRUE;
1520 data->drag_ticks = 2;
1522 break;
1523 #endif /* __MORPHOS__ */
1525 } /* switch (ie->ie_Class) */
1527 } /* if (gi) */
1529 return retval;
1532 /***********************************************************************************/
1534 IPTR SizeButtonClass__GM_GOINACTIVE(Class *cl, struct Gadget *g, struct gpGoInactive *msg)
1536 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
1537 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
1538 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
1539 struct sizebutton_data *data;
1540 struct Window *w;
1542 data = INST_DATA(cl, g);
1543 w = msg->gpgi_GInfo->gi_Window;
1545 /* Allways clear last drawn frame */
1547 if (data->isrendered && data->rp)
1550 SetDrMd(data->rp, COMPLEMENT);
1552 /* Erase old frame */
1553 if (!OPAQUESIZE)
1554 drawwindowframe(w->WScreen
1555 , data->rp
1556 , data->left
1557 , data->top
1558 , data->left + data->width - 1
1559 , data->top + data->height - 1
1560 , IntuitionBase
1564 else
1566 if (!OPAQUESIZE)
1568 data->drag_canceled = TRUE;
1571 data->isrendered = FALSE;
1573 if (data->drag_layerlock)
1575 UnlockLayers(&w->WScreen->LayerInfo);
1576 data->drag_layerlock = FALSE;
1579 #ifdef USEGADGETLOCK
1580 if (data->drag_gadgetlock)
1582 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->GadgetLock);
1583 data->drag_gadgetlock = FALSE;
1586 if (data->drag_inputhandlerlock)
1588 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->InputHandlerLock);
1589 data->drag_inputhandlerlock = FALSE;
1591 #endif
1593 #ifdef USEWINDOWLOCK
1594 if (data->drag_windowlock)
1596 ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
1597 data->drag_windowlock = FALSE;
1599 #endif
1601 //jDc: workarounds refresh pb on GZZ window resize
1602 ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->ActiveSysGadget->Flags &= ~GFLG_SELECTED;
1604 if (!data->drag_canceled || OPAQUESIZE)
1606 if (OPAQUESIZE && data->drag_canceled)
1608 DoMoveSizeWindow(w,data->LeftEdge,data->TopEdge,data->Width,data->Height,TRUE,IntuitionBase);
1610 else
1612 DoMoveSizeWindow(w,data->left,data->top,data->width,data->height,TRUE,IntuitionBase);
1614 //ChangeWindowBox(w,data->left,data->top,data->width,data->height);
1616 data->drag_canceled = TRUE;
1618 /* User throught with drag operation. Unlock layesr and free
1619 rastport clone
1621 if (data->rp)
1623 FreeRastPort(data->rp);
1624 data->rp = NULL;
1627 /* shut off mouse bounds checking. */
1628 ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->MouseBoundsActiveFlag = FALSE;
1630 return TRUE;
1633 /***********************************************************************************/
1635 IPTR SizeButtonClass__OM_NEW(Class *cl, Object *o, Msg msg)
1637 struct Gadget *g = (struct Gadget *)DoSuperMethodA(cl, o, msg);
1638 if (g)
1640 g->GadgetType |= GTYP_SYSGADGET | GTYP_SIZING;
1643 return (IPTR)g;
1646 /***********************************************************************************/