Minor fixes to comments.
[AROS.git] / rom / intuition / propgclass.c
blob9962784332f6fc5a777f79453f1cfda3eb1a31cd
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$
5 */
7 #include <exec/types.h>
9 #include <proto/intuition.h>
10 #include <proto/graphics.h>
11 #include <proto/utility.h>
12 #include <intuition/intuition.h>
13 #include <intuition/classes.h>
14 #include <intuition/classusr.h>
15 #include <intuition/gadgetclass.h>
16 #include <intuition/cghooks.h>
17 #include <graphics/clip.h>
18 #include <aros/asmcall.h>
19 #include <string.h>
21 #define DEBUG 0
22 #include <aros/debug.h>
24 #include "intuition_intern.h"
25 #include "inputhandler.h"
26 #include "propgadgets.h"
28 #define DEBUG_PROP(x) ;
30 #ifdef PROPHACK
31 void PropRefreshTask(struct IntuitionBase *IntuitionBase,struct Gadget *gadget,struct Window *window,struct Requester *requester)
33 ULONG signals;
35 for (;;)
37 signals = Wait(PSIG_REFRESHALL|PSIG_DIE);
39 //go_inactive refreshes the gadget on it's own, so we do not need to care about queued refreshes!
40 if (signals & PSIG_DIE)
42 Forbid();
43 ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->PropTask = 0;
44 Permit();
45 Signal(((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->InputDeviceTask,SIGF_INTUITION);
46 return;
49 if (signals & PSIG_REFRESHALL)
51 RefreshPropGadget (gadget, window, requester, IntuitionBase);
54 //no need to refresh the knob when whole gadget was refreshed already
55 //if ((signals & PSIG_REFRESHKNOB) && (!(signals & PSIG_REFRESHALL)))
56 //{
57 //}
61 #endif
63 /*****************************************************************************************
65 stegerg: Tested behaviour under AmigaOS:
67 propgclass object:
68 renders itself during OM_SET(PGA_Top) : yes, method retval = 0
69 renders itself during OM_UPDATE(PGA_Top) : yes, method retval = 0
70 sends OM_NOTIFY during OM_SET(PGA_Top) : no
71 sends OM_NOTIFY during OM_UPDATE(PGA_Top): no
72 sends OM_NOTIFY when user drags knob : yes
74 -> only when user uses gadget, OM_NOTIFY is sent
76 propgclass subclass object:
77 renders itself during OM_SET(PGA_Top) : no, method retval = 1 [*]
78 renders itself during OM_UPDATE(PGA_Top) : no, method retval = 1 [*]
79 sends OM_NOTIFY during OM_SET(PGA_Top) : no
80 sends OM_NOTIFY during OM_UPDATE(PGA_Top): no
81 sends OM_NOTIFY when user drags knob : yes
83 Here [*], another weird behaviour is, that the ~internal (??) PGA_Top value
84 stays at the old value, so you can click at the knob where you see it
85 (although because of the real PGA_Top it could in reality be in some
86 completely different place) and use it. Only when the gadget is re-rendered
87 (completely?), or you click somewhere in the prop box to cause a ~one page knob
88 move, the ~internal PGA_Top gets updated to the real value. Note, that
89 GetAttr(PGA_Top) will always be correct, so when I say ~internal PGA_Top,
90 this must be some internal variable only for inputhandling of gadget!!
91 BTW: With PGA_Total (and most likely also PGA_Visible) it's exactly the
92 same: imagine before the OM_SET/OM_UPDATE the prop knob was 10 % of the
93 size of the prop box. And after the OM_SET/OM_UPDATE(PGA_Total) the prop knob
94 would be 50 % of the size of the prop box -> again - before a rerendering of
95 the gadget happens, or a jump-one-page click by user - the gadget behaves
96 like it was still having the old PGA_Total value (-> knob size == 10 % of
97 prop box).
99 AROS propgclass at the moment does not copy this behaviour!!!!
101 *****************************************************************************************/
103 #define SetGadgetType(gad, type) ((struct Gadget *)gad)->GadgetType &= ~GTYP_GTYPEMASK; \
104 ((struct Gadget *)gad)->GadgetType |= type;
106 #define PRIVFLAG_NICERENDER 1
107 #define PRIVFLAG_NICENOTIFY 2
109 /****************************************************************************************/
111 static VOID FindScrollerValues(UWORD total, UWORD visible, UWORD top,
112 WORD overlap, UWORD *body, UWORD *pot)
114 UWORD hidden;
116 if (total > visible)
117 hidden = total - visible;
118 else
119 hidden = 0;
121 if (top > hidden)
122 top = hidden;
124 *body = (hidden > 0) ?
125 (UWORD)(((ULONG)(visible - overlap) * MAXBODY) / (total - overlap)) :
126 MAXBODY;
128 *pot = (hidden > 0) ? (UWORD)(((ULONG) top * MAXPOT) / hidden) : 0;
130 return;
133 /****************************************************************************************/
135 static UWORD FindScrollerTop(UWORD total, UWORD visible, UWORD pot)
137 UWORD top, hidden;
139 if (total > visible)
140 hidden = total - visible;
141 else
142 hidden = 0;
144 top = (((ULONG) hidden * pot) + (MAXPOT / 2)) / MAXPOT;
146 return (top);
149 /****************************************************************************************/
151 static VOID NotifyTop(Class *cl, struct Gadget *g, struct GadgetInfo *gi, BOOL final)
153 struct PropGData *data = INST_DATA(cl, g);
154 struct opUpdate notifymsg;
155 struct TagItem notifyattrs[3];
157 D(bug("PropGClass: NotifyTop(top=%d, final=%d)\n",
158 data->top, final));
160 notifyattrs[0].ti_Tag = PGA_Top;
161 notifyattrs[0].ti_Data = data->top;
162 notifyattrs[1].ti_Tag = GA_ID;
163 notifyattrs[1].ti_Data = g->GadgetID;
164 notifyattrs[2].ti_Tag = TAG_END;
166 notifymsg.MethodID = OM_NOTIFY;
167 notifymsg.opu_AttrList = notifyattrs;
168 notifymsg.opu_GInfo = gi;
169 notifymsg.opu_Flags = (final != FALSE) ? 0 : OPUF_INTERIM;
171 DoSuperMethodA(cl, (Object *)g, (Msg)&notifymsg);
173 return;
176 /****************************************************************************************/
178 static VOID UpdateTop(Class *cl, struct Gadget *g, struct GadgetInfo *gi, BOOL final)
180 /* Updates the PGA_Top attribute accordin to the Bofy/Pot vars.
181 ** Also triggers notifcation if PGA_Top has changed.
184 struct PropGData *data = (struct PropGData *)INST_DATA(cl, g);
185 UWORD top, pot;
187 D(bug("PropGClass: UpdateTop()\n"));
189 pot = (data->propinfo.Flags & FREEVERT) ? data->propinfo.VertPot :
190 data->propinfo.HorizPot;
192 top = FindScrollerTop(data->total, data->visible, pot);
194 D(bug("PropGClass: Found scroller top: %d, old %d\n", top, data->top));
196 /* PGA_Top changed by user ? */
197 if ((top != data->top) || final)
199 D(bug("PropGClass: top != data->top, calling NotifyTop\n"));
201 data->top = top;
203 NotifyTop(cl, g, gi, final);
206 return;
209 /****************************************************************************************/
211 #define SETFLAG(flagvar, boolvar, flag) \
212 if (boolvar) \
213 flagvar |= flag; \
214 else \
215 flagvar &= ~flag;
217 /****************************************************************************************/
219 IPTR PropGClass__OM_SET(Class *cl, struct Gadget *g, struct opSet *msg)
221 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
222 struct Library *UtilityBase = GetPrivIBase(IntuitionBase)->UtilityBase;
223 struct TagItem *tag, *tstate;
224 struct PropGData *data;
225 struct BBox old_knobbox;
226 struct opSet method;
227 UWORD newtop;
228 BOOL set_flag = FALSE;
229 BOOL was_disabled = FALSE;
230 BOOL full_redraw = FALSE;
231 BOOL old_knobbox_ok = FALSE;
232 IPTR retval;
234 data = INST_DATA(cl, g);
235 tstate = msg->ops_AttrList;
237 was_disabled = (g->Flags & GFLG_DISABLED) ? TRUE : FALSE;
239 method.MethodID = OM_SET;
240 method.ops_AttrList = msg->ops_AttrList;
241 method.ops_GInfo = msg->ops_GInfo;
242 retval = DoSuperMethodA(cl, (Object *)g, (Msg)&method);
244 if ( ((g->Flags & GFLG_DISABLED) ? TRUE : FALSE) != was_disabled ) full_redraw = TRUE;
246 if (msg->ops_GInfo)
248 CalcBBox (msg->ops_GInfo->gi_Window, msg->ops_GInfo->gi_Requester, g, &old_knobbox);
249 old_knobbox_ok = CalcKnobSize(g, &old_knobbox);
252 newtop = data->top; /* !! */
254 /* Set to 1 to signal visual changes */
255 while ((tag = NextTagItem(&tstate)) != NULL)
257 switch (tag->ti_Tag)
259 case PGA_Top:
260 newtop = (UWORD)tag->ti_Data;
261 /* This will be poked into data->top later below, because the
262 value might have to be adjusted. It depends on PGA_Total
263 and PGA_Visible which might be also set later in the taglist */
264 set_flag= TRUE;
265 retval += 1UL;
266 break;
268 case PGA_Visible:
269 data->visible = tag->ti_Data;
270 set_flag = TRUE;
271 retval += 1UL;
272 break;
274 case PGA_Total:
275 data->total = tag->ti_Data;
276 set_flag = TRUE;
277 retval += 1UL;
278 break;
280 /* When one of the four next ones is set, what should then happen
281 with PGA_Top, Total and Visible ?
282 For example decreasing Body could mean both a decrease of
283 Visible or an increase in Total. Which of them it is,
284 we cannot know. So we say that the PGA_xxxPot/Body
285 attrs should not be used along with Top, Total and Visible. */
287 case PGA_HorizPot:
288 data->propinfo.HorizPot = (UWORD)tag->ti_Data;
289 retval += 1UL;
290 break;
292 case PGA_HorizBody:
293 data->propinfo.HorizBody= (UWORD)tag->ti_Data;
294 retval += 1UL;
295 break;
297 case PGA_VertPot:
298 data->propinfo.VertPot = (UWORD)tag->ti_Data;
299 retval += 1UL;
300 break;
302 case PGA_VertBody:
303 data->propinfo.VertBody = (UWORD)tag->ti_Data;
304 retval += 1UL;
305 break;
307 case PGA_Freedom:
308 data->propinfo.Flags &= ~(FREEHORIZ|FREEVERT);
309 data->propinfo.Flags |= tag->ti_Data;
310 break;
312 case PGA_NewLook:
313 SETFLAG(data->propinfo.Flags, tag->ti_Data, PROPNEWLOOK);
314 break;
316 case PGA_Borderless:
317 SETFLAG(data->propinfo.Flags, tag->ti_Data, PROPBORDERLESS);
318 break;
320 case GA_Image:
321 break;
323 case GA_Border:
324 break;
326 case GA_Highlight:
327 /* Convert GADGHBOX to GADGHCOMP */
328 if (tag->ti_Data & GFLG_GADGHBOX)
330 /* Clear GADCHBOX */
331 tag->ti_Data &= ~GFLG_GADGHBOX;
332 /* Set GADGHCOMP */
333 tag->ti_Data |= GFLG_GADGHCOMP;
335 break;
338 default:
339 break;
341 } /* switch (tag->ti_Tag) */
343 } /* while ((tag = NextTagItem(&tstate)) != NULL) */
345 /* Top, Visible or Total set? */
347 if (set_flag)
349 UWORD *bodyptr, *potptr;
351 /* fix top value if necessary */
353 if (data->total > data->visible)
355 if (newtop > (data->total - data->visible))
356 newtop = data->total - data->visible;
358 else
360 newtop = 0;
363 if (data->top != newtop)
365 data->top = newtop;
366 if (data->flags & PRIVFLAG_NICENOTIFY)
368 NotifyTop(cl, g, msg->ops_GInfo, TRUE);
372 if (data->propinfo.Flags & FREEVERT)
374 bodyptr = &(data->propinfo.VertBody);
375 potptr = &(data->propinfo.VertPot);
377 else
379 bodyptr = &(data->propinfo.HorizBody);
380 potptr = &(data->propinfo.HorizPot);
383 FindScrollerValues
385 data->total,
386 data->visible,
387 data->top,
389 bodyptr,
390 potptr
395 /* The two last tests below may be redundant */
396 if ((retval || full_redraw) && (NULL != msg->ops_GInfo) &&
397 ((OCLASS(g) == cl) || (data->flags & PRIVFLAG_NICERENDER)))
399 struct RastPort *rp;
401 rp = ObtainGIRPort(msg->ops_GInfo);
402 if (NULL != rp)
404 struct gpRender method;
406 data->old_knobbox = old_knobbox_ok ? &old_knobbox : 0;
408 method.MethodID = GM_RENDER;
409 method.gpr_GInfo = msg->ops_GInfo;
410 method.gpr_RPort = rp;
411 method.gpr_Redraw = full_redraw ? GREDRAW_REDRAW : GREDRAW_UPDATE;
413 DoMethodA((Object *)g, (Msg)&method);
415 ReleaseGIRPort(rp);
417 if (!(data->flags & PRIVFLAG_NICERENDER))
419 /* retval of 1 indicates that user needs to rerender gadget
420 manually, while 0 means he does not need to do so */
421 retval = 0;
425 return (retval);
428 /****************************************************************************************/
430 IPTR PropGClass__OM_NEW(Class *cl, Object *o, struct opSet *msg)
432 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
433 struct Library *UtilityBase = GetPrivIBase(IntuitionBase)->UtilityBase;
434 struct Gadget *g = (struct Gadget *)DoSuperMethodA(cl, o, (Msg)msg);
436 D(bug("PropGClass: new %p\n", o));
438 if (g)
440 struct PropGData *data = INST_DATA(cl, g);
442 /* A hack to make the functions in propgadgets.c work
443 with this class */
444 g->SpecialInfo = &(data->propinfo);
446 /* Set some default values in the propinfo structure */
448 The instance object is cleared memory!
449 memset(&(data->propinfo), 0, sizeof (struct PropInfo));
451 data->propinfo.Flags = PROPNEWLOOK|AUTOKNOB|FREEVERT;
452 data->propinfo.VertPot = 0;
453 data->propinfo.VertBody = MAXBODY;
454 data->propinfo.HorizPot = 0;
455 data->propinfo.HorizBody = MAXBODY;
456 data->DisplayHook = (struct Hook *)GetTagData(PGA_DisplayHook, 0, msg->ops_AttrList);
457 data->top = 0;
458 data->visible = 1;
459 data->total = 1;
461 if (GetTagData(PGA_NotifyBehaviour, PG_BEHAVIOUR_COMPATIBLE, msg->ops_AttrList) ==
462 PG_BEHAVIOUR_NICE)
464 data->flags |= PRIVFLAG_NICENOTIFY;
467 if (GetTagData(PGA_RenderBehaviour, PG_BEHAVIOUR_COMPATIBLE, msg->ops_AttrList) ==
468 PG_BEHAVIOUR_NICE)
470 data->flags |= PRIVFLAG_NICERENDER;
473 SetGadgetType(g, GTYP_CUSTOMGADGET);
475 /* Handle our special tags - overrides defaults */
476 PropGClass__OM_SET(cl, g, msg);
478 } /* if (object created) */
480 return (IPTR)g;
483 /****************************************************************************************/
485 IPTR PropGClass__OM_GET(Class *cl, struct Gadget *g,struct opGet *msg)
487 struct PropGData *data;
488 IPTR retval = 1UL;
490 data = INST_DATA(cl, g);
492 switch (msg->opg_AttrID)
494 case PGA_Top:
495 *(msg->opg_Storage) = data->top;
496 break;
498 case PGA_Total:
499 *(msg->opg_Storage) = data->total;
500 break;
502 case PGA_DisplayHook:
503 *(msg->opg_Storage) = (IPTR)data->DisplayHook;
504 break;
506 case PGA_Visible:
507 *(msg->opg_Storage) = data->visible;
508 break;
510 case PGA_HorizPot:
511 *(msg->opg_Storage) = data->propinfo.HorizPot;
512 break;
514 case PGA_HorizBody:
515 *(msg->opg_Storage) = data->propinfo.HorizBody;
516 break;
518 case PGA_VertPot:
519 *(msg->opg_Storage) = data->propinfo.VertPot;
520 break;
522 case PGA_VertBody:
523 *(msg->opg_Storage) = data->propinfo.VertBody;
524 break;
526 case PGA_Freedom:
527 *(msg->opg_Storage) = data->propinfo.Flags & (FREEHORIZ|FREEVERT);
528 break;
530 default:
531 retval = DoSuperMethodA(cl, (Object *)g, (Msg)msg);
532 break;
534 return (retval);
537 /****************************************************************************************/
539 IPTR PropGClass__GM_GOACTIVE(Class *cl, struct Gadget *g, struct gpInput *msg)
541 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
542 IPTR retval = GMR_NOREUSE;
544 /* Was GOACTIVE caused by an input event ? */
545 if (msg->gpi_IEvent)
547 struct PropGData *data = INST_DATA(cl, g);
549 /* Fake a standard intuition prop gadget.
550 Of course this is a hack. */
551 SetGadgetType(g, GTYP_PROPGADGET);
553 /* Handle SelectDown event */
554 HandlePropSelectDown
557 msg->gpi_GInfo->gi_Window,
558 msg->gpi_GInfo->gi_Requester,
559 msg->gpi_Mouse.X,
560 msg->gpi_Mouse.Y,
561 IntuitionBase
563 SetGadgetType(g, GTYP_CUSTOMGADGET);
565 if (!(data->propinfo.Flags & KNOBHIT))
567 /* If the knob was not hit, swallow hit-event.
568 (Gadget has allready been updated) */
570 /* Update PGA_Top. Final update. */
571 UpdateTop(cl, g, msg->gpi_GInfo, TRUE);
573 *(msg->gpi_Termination) = data->top;
574 retval = GMR_NOREUSE|GMR_VERIFY;
576 else
578 /* We must remember mousepos for use in GM_HANDLEINPUT */
579 data->last_x = msg->gpi_Mouse.X;
580 data->last_y = msg->gpi_Mouse.Y;
582 retval = GMR_MEACTIVE; /* Stay active */
584 /* enable buffering to speed up refresh */
585 ((struct IntWindow *)(msg->gpi_GInfo->gi_Window))->specialflags |= SPFLAG_WANTBUFFER;
587 #ifdef PROPHACK
588 ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->PropTask =
589 NewCreateTask(TASKTAG_CODETYPE, CODETYPE_PPC, TASKTAG_PC, (ULONG)PropRefreshTask,
590 TASKTAG_PRI,0,
591 TASKTAG_PPC_ARG1,(ULONG)IntuitionBase,
592 TASKTAG_PPC_ARG2,(ULONG)g,
593 TASKTAG_PPC_ARG3,(ULONG)msg->gpi_GInfo->gi_Window,
594 TASKTAG_PPC_ARG4,(ULONG)msg->gpi_GInfo->gi_Requester,
595 TAG_DONE);
596 #endif
598 } /* if not knob was hit */
600 } /* if gadget was activated by an input event */
602 return (retval);
605 /****************************************************************************************/
607 IPTR PropGClass__GM_HANDLEINPUT(Class *cl, struct Gadget *g, struct gpInput *msg)
609 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
610 struct InputEvent *ie;
611 struct PropGData *data = INST_DATA(cl, g);
613 /* Default: stay active */
614 IPTR retval = GMR_MEACTIVE;
616 ie = msg->gpi_IEvent;
617 if (ie->ie_Class == IECLASS_RAWMOUSE)
619 switch (ie->ie_Code)
621 case IECODE_NOBUTTON:
622 if ((msg->gpi_Mouse.X != data->last_x) || (msg->gpi_Mouse.Y != data->last_y))
624 /* Fake a standard intuition prop gadget */
625 SetGadgetType(g, GTYP_PROPGADGET);
626 HandlePropMouseMove
629 msg->gpi_GInfo->gi_Window,
630 msg->gpi_GInfo->gi_Requester,
631 msg->gpi_Mouse.X, /* - data->last_x, */
632 msg->gpi_Mouse.Y, /* - data->last_y, */
633 IntuitionBase
636 SetGadgetType(g, GTYP_CUSTOMGADGET);
638 data->last_x = msg->gpi_Mouse.X;
639 data->last_y = msg->gpi_Mouse.Y;
641 D(bug("PropGClass: Calling UpdateTop\n"));
643 /* Update PGA_Top. Interim update. */
644 UpdateTop(cl, g, msg->gpi_GInfo, FALSE);
647 break;
649 case SELECTUP:
650 /* User has released the knob. Refresh knob */
652 #ifdef PROPHACK
653 if (((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->PropTask)
655 ULONG oldSignals = SetSignal(0,SIGF_INTUITION);
656 struct Task *task = ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->PropTask;
657 ULONG signals = 0;
659 Forbid();
660 ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->PropTask = 0;
661 Permit();
663 if (task) //small protection
665 Signal(task,PSIG_DIE);
667 signals = Wait(SIGF_INTUITION);
670 SetSignal(oldSignals | (signals & ~SIGF_INTUITION),0xFFFFFFFF);
672 #endif
674 SetGadgetType(g, GTYP_PROPGADGET);
676 HandlePropSelectUp
679 msg->gpi_GInfo->gi_Window,
680 msg->gpi_GInfo->gi_Requester,
681 IntuitionBase
684 SetGadgetType(g, GTYP_CUSTOMGADGET);
686 /* Update PGA_Top. Final update. */
687 UpdateTop(cl, g, msg->gpi_GInfo, TRUE);
689 *(msg->gpi_Termination) = data->top;
690 retval = GMR_NOREUSE|GMR_VERIFY;
691 break;
693 } /* switch (ie->ie_Code) */
695 } /* if (ie->ie_Class == IECLASS_RAWMOUSE) */
697 return (retval);
700 /****************************************************************************************/
702 IPTR PropGClass__GM_RENDER(Class *cl, struct Gadget *g, struct gpRender *msg)
704 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
705 struct PropGData *data = INST_DATA(cl, g);
707 DEBUG_PROP(dprintf("render_propgclass:\n"));
709 #ifdef PROPHACK
710 Forbid();
711 if ((g == ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->ActiveGadget) && (FindTask(0) == ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->InputDeviceTask) && ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->PropTask)
713 Signal(((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->PropTask,PSIG_REFRESHALL);
714 return (IPTR)1;
716 Permit();
717 #endif
719 /* Fake a standard intuition prop gadget */
720 SetGadgetType(g, GTYP_PROPGADGET);
722 if ((msg->gpr_Redraw == GREDRAW_UPDATE) && (data->old_knobbox))
724 struct BBox new_knobbox;
726 CalcBBox (msg->gpr_GInfo->gi_Window, msg->gpr_GInfo->gi_Requester, g, &new_knobbox);
728 DEBUG_PROP(dprintf("render_propgclass: BBox Left %ld Top %ld Width %ld Height %ld\n",
729 new_knobbox.Left,
730 new_knobbox.Width,
731 new_knobbox.Top,
732 new_knobbox.Height));
734 if (CalcKnobSize(g, &new_knobbox))
736 #if PROP_RENDER_OPTIMIZATION
737 RefreshPropGadgetKnob (g, data->old_knobbox, &new_knobbox, msg->gpr_GInfo->gi_Window, msg->gpr_GInfo->gi_Requester, IntuitionBase);
738 #else
739 struct BBox gbox;
741 CalcBBox (msg->gpr_GInfo->gi_Window, msg->gpr_GInfo->gi_Requester, g, &gbox);
742 RefreshPropGadgetKnob (g, &gbox, &new_knobbox, msg->gpr_GInfo->gi_Window, msg->gpr_GInfo->gi_Requester, IntuitionBase);
743 #endif
746 data->old_knobbox = 0;
748 else
750 /* Redraw the whole gadget */
751 RefreshPropGadget
754 msg->gpr_GInfo->gi_Window,
755 msg->gpr_GInfo->gi_Requester,
756 IntuitionBase
760 SetGadgetType(g, GTYP_CUSTOMGADGET);
762 return (IPTR)1;
766 /****************************************************************************************/
768 IPTR PropGClass__GM_GOINACTIVE(Class *cl, struct Gadget *g, struct gpGoInactive *msg)
770 struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
771 /* Gadget cancelled by intuition ? */
773 if (msg->gpgi_Abort == 1)
776 #ifdef PROPHACK
777 if (((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->PropTask)
779 ULONG oldSignals = SetSignal(0,SIGF_INTUITION);
780 struct Task *task = ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->PropTask;
781 ULONG signals = 0;
783 Forbid();
784 ((struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data)->PropTask = 0;
785 Permit();
787 if (task) //small protection
789 Signal(task,PSIG_DIE);
791 signals = Wait(SIGF_INTUITION);
794 SetSignal(oldSignals | (signals & ~SIGF_INTUITION),0xFFFFFFFF);
796 #endif
798 SetGadgetType(g, GTYP_PROPGADGET);
800 HandlePropSelectUp
803 msg->gpgi_GInfo->gi_Window,
804 msg->gpgi_GInfo->gi_Requester,
805 IntuitionBase
808 SetGadgetType(g, GTYP_CUSTOMGADGET);
810 ((struct IntWindow *)(msg->gpgi_GInfo->gi_Window ))->specialflags &= ~SPFLAG_WANTBUFFER;
812 /* Update PGA_Top. Final update */
813 UpdateTop(cl, g, msg->gpgi_GInfo, TRUE);
815 return (IPTR)0;
818 /****************************************************************************************/