2 Copyright 1995-2011, The AROS Development Team. All rights reserved.
3 Copyright 2001-2003, The MorphOS Development Team. All Rights Reserved.
7 #include <exec/types.h>
10 #include <dos/dosextens.h>
12 #include <intuition/intuition.h>
13 #include <intuition/intuitionbase.h>
14 #include <intuition/classes.h>
15 #include <intuition/classusr.h>
16 #include <intuition/gadgetclass.h>
17 #include <intuition/cghooks.h>
18 #include <intuition/icclass.h>
20 #include <graphics/gfxbase.h>
21 #include <graphics/gfxmacros.h>
23 #include <utility/tagitem.h>
24 #include <utility/hooks.h>
26 #include <clib/macros.h>
30 #include <proto/exec.h>
31 #include <proto/intuition.h>
32 #include <proto/graphics.h>
33 #include <proto/utility.h>
38 #include "intuition_intern.h"
39 #include <aros/asmcall.h>
40 #include <proto/alib.h>
43 #endif /* !__MORPHOS__ */
45 #define DEBUG_GADGET(x) ;
47 /****************************************************************************/
49 /* set gadget attributes
51 static ULONG
set_gadgetclass(Class
*cl
, struct ExtGadget
*eg
, struct opSet
*msg
)
53 struct IntuitionBase
*IntuitionBase
= (struct IntuitionBase
*)cl
->cl_UserData
;
54 struct Library
*UtilityBase
= GetPrivIBase(IntuitionBase
)->UtilityBase
;
55 struct TagItem
*tag
, *tstate
= msg
->ops_AttrList
;
57 ULONG retval
= 0UL; /* set to non-zero to signal visual changes */
59 while ( (tag
= NextTagItem(&tstate
)) )
61 tidata
= tag
->ti_Data
;
66 eg
->LeftEdge
= (WORD
)tidata
;
67 //eg->Flags &= ~GFLG_RELRIGHT;
72 eg
->TopEdge
= (WORD
)tidata
;
73 //eg->Flags &= ~GFLG_RELBOTTOM;
78 eg
->Width
= (WORD
)tidata
;
79 eg
->Flags
&= ~GFLG_RELWIDTH
;
84 eg
->Height
= (WORD
)tidata
;
85 eg
->Flags
&= ~GFLG_RELHEIGHT
;
90 eg
->LeftEdge
= (WORD
)tidata
;
91 eg
->Flags
|= GFLG_RELRIGHT
;
96 eg
->TopEdge
= (WORD
)tidata
;
97 eg
->Flags
|= GFLG_RELBOTTOM
;
102 eg
->Width
= (WORD
)tidata
;
103 eg
->Flags
|= GFLG_RELWIDTH
;
108 eg
->Height
= (WORD
)tidata
;
109 eg
->Flags
|= GFLG_RELHEIGHT
;
116 eg
->Flags
|= GFLG_RELSPECIAL
;
120 eg
->Flags
&= ~GFLG_RELSPECIAL
;
128 eg
->BoundsLeftEdge
= ((struct IBox
*)tidata
)->Left
;
129 eg
->BoundsTopEdge
= ((struct IBox
*)tidata
)->Top
;
130 eg
->BoundsWidth
= ((struct IBox
*)tidata
)->Width
;
131 eg
->BoundsHeight
= ((struct IBox
*)tidata
)->Height
;
132 eg
->MoreFlags
|= GMORE_BOUNDS
;
140 eg
->MoreFlags
|= GMORE_GADGETHELP
;
144 eg
->MoreFlags
&= ~GMORE_GADGETHELP
;
150 eg
->NextGadget
= (struct ExtGadget
*)tidata
;
154 if( (tidata
!= 0L) && (msg
->MethodID
== OM_NEW
) )
156 eg
->NextGadget
= ((struct ExtGadget
*)tidata
)->NextGadget
;
157 ((struct ExtGadget
*)tidata
)->NextGadget
= eg
;
162 eg
->GadgetText
= (struct IntuiText
*)tidata
;
165 eg
->Flags
&= ~GFLG_LABELMASK
;
166 eg
->Flags
|= GFLG_LABELITEXT
;
172 eg
->GadgetText
= (struct IntuiText
*)tidata
;
175 eg
->Flags
&= ~GFLG_LABELMASK
;
176 eg
->Flags
|= GFLG_LABELSTRING
;
182 eg
->GadgetText
= (struct IntuiText
*)tidata
;
185 eg
->Flags
&= ~GFLG_LABELMASK
;
186 eg
->Flags
|= GFLG_LABELIMAGE
;
192 eg
->GadgetRender
= (APTR
)tidata
;
195 eg
->Flags
|= GFLG_GADGIMAGE
;
201 eg
->GadgetRender
= (APTR
)tidata
;
204 eg
->Flags
&= ~GFLG_GADGIMAGE
;
209 case GA_SelectRender
:
210 eg
->SelectRender
= (APTR
)tidata
;
212 eg
->Flags
|= (GFLG_GADGIMAGE
& GFLG_GADGHIMAGE
);
218 eg
->SpecialInfo
= (APTR
)tidata
;
222 if ( tidata
!= FALSE
)
224 eg
->GadgetType
|= GTYP_GZZGADGET
;
228 eg
->GadgetType
&= ~GTYP_GZZGADGET
;
233 if ( tidata
!= FALSE
)
235 eg
->GadgetType
|= GTYP_SYSGADGET
;
239 eg
->GadgetType
&= ~GTYP_SYSGADGET
;
244 if ( tidata
!= FALSE
)
246 eg
->Flags
|= GFLG_SELECTED
;
250 eg
->Flags
&= ~GFLG_SELECTED
;
256 if ( tidata
!= FALSE
)
258 eg
->Flags
|= GFLG_DISABLED
;
262 eg
->Flags
&= ~GFLG_DISABLED
;
268 if ( tidata
!= FALSE
)
270 eg
->Activation
|= GACT_ENDGADGET
;
274 eg
->Activation
&= ~GACT_ENDGADGET
;
279 if ( tidata
!= FALSE
)
281 eg
->Activation
|= GACT_IMMEDIATE
;
285 eg
->Activation
&= ~GACT_IMMEDIATE
;
290 if ( tidata
!= FALSE
)
292 eg
->Activation
|= GACT_RELVERIFY
;
296 eg
->Activation
&= ~GACT_RELVERIFY
;
301 if ( tidata
!= FALSE
)
303 eg
->Activation
|= GACT_FOLLOWMOUSE
;
307 eg
->Activation
&= ~GACT_FOLLOWMOUSE
;
312 if ( tidata
!= FALSE
)
314 eg
->Activation
|= GACT_RIGHTBORDER
;
318 eg
->Activation
&= ~GACT_RIGHTBORDER
;
323 if ( tidata
!= FALSE
)
325 eg
->Activation
|= GACT_LEFTBORDER
;
329 eg
->Activation
&= ~GACT_LEFTBORDER
;
334 if ( tidata
!= FALSE
)
336 eg
->Activation
|= GACT_TOPBORDER
;
340 eg
->Activation
&= ~GACT_TOPBORDER
;
344 case GA_BottomBorder
:
345 if ( tidata
!= FALSE
)
347 eg
->Activation
|= GACT_BOTTOMBORDER
;
351 eg
->Activation
&= ~GACT_BOTTOMBORDER
;
355 case GA_ToggleSelect
:
358 eg
->Activation
|= GACT_TOGGLESELECT
;
362 eg
->Activation
&= ~GACT_TOGGLESELECT
;
369 eg
->Flags
|= GFLG_TABCYCLE
;
373 eg
->Flags
&= ~GFLG_TABCYCLE
;
378 eg
->Flags
&= ~GFLG_GADGHIGHBITS
;
379 eg
->Flags
|= tidata
& GFLG_GADGHIGHBITS
;
383 eg
->GadgetType
&= ~GTYP_SYSTYPEMASK
;
384 eg
->GadgetType
|= tidata
& GTYP_SYSTYPEMASK
;
388 /* GA_ID should NOT be set if this is a OM_UPDATE.
389 ** This is because gadgets should send their GA_ID
390 ** when doing a OM_NOTIFY, so that the receiver
391 ** might see who sent the message.
392 ** But we surely don't want to change the GA_ID
393 ** of the reciver to that of the sender.
395 if (msg
->MethodID
!= OM_UPDATE
)
397 eg
->GadgetID
= tidata
;
402 eg
->UserData
= (APTR
)tidata
;
403 DEBUG_GADGET(dprintf("set_gadgetclass: UserData 0x%lx\n",tidata
));
407 ((struct GadgetData
*)eg
)->IC
.ic_Target
= (Object
*)tidata
;
411 ((struct GadgetData
*)eg
)->IC
.ic_Mapping
= (struct TagItem
*)tidata
;
416 } /* while NextTagItem */
419 /* This seems to be wrong here. Instead buttongclass is where
420 something like this happens, so look there (stegerg) */
422 if ((msg
->MethodID
== OM_NEW
) &&
423 (eg
->Flags
& GFLG_GADGIMAGE
) &&
424 (eg
->GadgetRender
!= NULL
))
426 if (eg
->Width
== 0) eg
->Width
= ((struct Image
*)eg
->GadgetRender
)->Width
;
427 if (eg
->Height
== 0) eg
->Height
= ((struct Image
*)eg
->GadgetRender
)->Height
;
435 IPTR
GadgetClass__OM_NEW(Class
*cl
, Object
*o
, struct opSet
*msg
)
437 struct ExtGadget
*eg
= (struct ExtGadget
*)DoSuperMethodA(cl
, o
, (Msg
)msg
);
441 /* set some defaults */
443 * The instance object is cleared memory!
444 * memset (eg, 0, sizeof(struct GadgetData));
446 eg
->Flags
= GFLG_EXTENDED
;
447 eg
->GadgetType
= GTYP_CUSTOMGADGET
;
448 eg
->MoreFlags
= GMORE_BOOPSIGADGET
;
449 eg
->MutualExclude
= (IPTR
)&((Class
*)o
)->cl_Dispatcher
;
451 /* Handle our special tags - overrides defaults */
452 set_gadgetclass(cl
, eg
, msg
);
458 IPTR
GadgetClass__OM_SET(Class
*cl
, struct ExtGadget
*eg
, struct opSet
*msg
)
460 return DoSuperMethodA(cl
, (Object
*)eg
, (Msg
)msg
) + set_gadgetclass(cl
, eg
, (struct opSet
*)msg
);
463 IPTR
GadgetClass__OM_NOTIFY(Class
*cl
, struct GadgetData
*gd
, struct opUpdate
*msg
)
465 struct IntuitionBase
*IntuitionBase
= (struct IntuitionBase
*)cl
->cl_UserData
;
466 DEBUG_GADGET(dprintf("dispatch_gadgetclass: OM_NOTIFY\n"));
467 DoNotify(cl
, (Object
*)gd
, &(gd
->IC
), msg
);
468 DEBUG_GADGET(dprintf("dispatch_gadgetclass: OM_NOTIFY done\n"));
473 IPTR
GadgetClass__OM_DISPOSE(Class
*cl
, struct GadgetData
*gd
, Msg msg
)
475 struct IntuitionBase
*IntuitionBase
= (struct IntuitionBase
*)cl
->cl_UserData
;
476 FreeICData((struct ICData
*)&gd
->IC
);
477 return DoSuperMethodA(cl
, (Object
*)gd
, (Msg
)msg
);
480 /* get gadget attributes - gadgetclass really has no gettable
481 * attributes, but we will implement some useful ones anyway. ;0
483 IPTR
GadgetClass__OM_GET(Class
*cl
, struct ExtGadget
*eg
, struct opGet
*msg
)
487 switch (msg
->opg_AttrID
)
491 *msg
->opg_Storage
= (IPTR
) eg
->LeftEdge
;
496 *msg
->opg_Storage
= (IPTR
) eg
->TopEdge
;
501 *msg
->opg_Storage
= (IPTR
) eg
->Width
;
506 *msg
->opg_Storage
= (IPTR
) eg
->Height
;
510 *msg
->opg_Storage
= (IPTR
)((eg
->Flags
& GFLG_SELECTED
) != 0);
514 *msg
->opg_Storage
= (IPTR
)((eg
->Flags
& GFLG_DISABLED
) != 0);
518 *msg
->opg_Storage
= (IPTR
)eg
->GadgetID
;
522 *msg
->opg_Storage
= (IPTR
)eg
->UserData
;
526 *msg
->opg_Storage
= (IPTR
)(eg
->Flags
& GFLG_RELSPECIAL
) ? TRUE
: FALSE
;
530 *msg
->opg_Storage
= (IPTR
)(eg
->MoreFlags
& GMORE_GADGETHELP
) ? TRUE
: FALSE
;
534 *msg
->opg_Storage
= (IPTR
)eg
->NextGadget
;
538 *msg
->opg_Storage
= (IPTR
)((eg
->Flags
& GFLG_LABELITEXT
) ? eg
->GadgetText
: 0);
542 *msg
->opg_Storage
= (IPTR
)((eg
->Flags
& GFLG_LABELSTRING
) ? eg
->GadgetText
: 0);
546 *msg
->opg_Storage
= (IPTR
)((eg
->Flags
& GFLG_LABELIMAGE
) ? eg
->GadgetText
: 0);
550 *msg
->opg_Storage
= (IPTR
)((eg
->Flags
& GFLG_GADGIMAGE
) ? eg
->GadgetRender
: 0);
554 *msg
->opg_Storage
= (IPTR
)((eg
->Flags
& GFLG_GADGIMAGE
) ? 0 : eg
->GadgetRender
);
557 case GA_SelectRender
:
558 *msg
->opg_Storage
= (IPTR
)((eg
->Flags
& GFLG_GADGHIMAGE
) ? eg
->SelectRender
: 0);
562 *msg
->opg_Storage
= (IPTR
)eg
->SpecialInfo
;
566 *msg
->opg_Storage
= (IPTR
)((eg
->GadgetType
& GTYP_GZZGADGET
) ? TRUE
: FALSE
);
570 *msg
->opg_Storage
= (IPTR
)((eg
->GadgetType
& GTYP_SYSGADGET
) ? TRUE
: FALSE
);
574 *msg
->opg_Storage
= (IPTR
)((eg
->Activation
& GACT_ENDGADGET
) ? TRUE
: FALSE
);
578 *msg
->opg_Storage
= (IPTR
)((eg
->Activation
& GACT_IMMEDIATE
) ? TRUE
: FALSE
);
582 *msg
->opg_Storage
= (IPTR
)((eg
->Activation
& GACT_RELVERIFY
) ? TRUE
: FALSE
);
586 *msg
->opg_Storage
= (IPTR
)((eg
->Activation
& GACT_FOLLOWMOUSE
) ? TRUE
: FALSE
);
590 *msg
->opg_Storage
= (IPTR
)((eg
->Activation
& GACT_RIGHTBORDER
) ? TRUE
: FALSE
);
594 *msg
->opg_Storage
= (IPTR
)((eg
->Activation
& GACT_LEFTBORDER
) ? TRUE
: FALSE
);
598 *msg
->opg_Storage
= (IPTR
)((eg
->Activation
& GACT_TOPBORDER
) ? TRUE
: FALSE
);
601 case GA_BottomBorder
:
602 *msg
->opg_Storage
= (IPTR
)((eg
->Activation
& GACT_BOTTOMBORDER
) ? TRUE
: FALSE
);
605 case GA_ToggleSelect
:
606 *msg
->opg_Storage
= (IPTR
)((eg
->Activation
& GACT_TOGGLESELECT
) ? TRUE
: FALSE
);
610 *msg
->opg_Storage
= (IPTR
)((eg
->Flags
& GFLG_TABCYCLE
) ? TRUE
: FALSE
);
614 *msg
->opg_Storage
= (IPTR
)((eg
->Flags
& GFLG_GADGHIGHBITS
) ? TRUE
: FALSE
);
618 *msg
->opg_Storage
= (IPTR
)(eg
->GadgetType
& GTYP_SYSTYPEMASK
);
622 *msg
->opg_Storage
= (IPTR
)((struct GadgetData
*)eg
)->IC
.ic_Target
;
626 *msg
->opg_Storage
= (IPTR
)((struct GadgetData
*)eg
)->IC
.ic_Mapping
;
630 if (msg
->opg_Storage
)
632 struct IBox
*ibox
= (struct IBox
*)msg
->opg_Storage
;
634 ibox
->Left
= eg
->BoundsLeftEdge
;
635 ibox
->Top
= eg
->BoundsTopEdge
;
636 ibox
->Width
= eg
->BoundsWidth
;
637 ibox
->Height
= eg
->BoundsHeight
;
644 /* DONT DO THIS!! For example BGUI propclass relies on this not happening!! */
646 *msg
->opg_Storage
= (IPTR
)NULL
;
652 } /* switch attrid) */
657 /* test if we should try to activate this gadget...
659 IPTR
GadgetClass__GM_HITTEST(Class
*cl
, Object
*o
, struct gpHitTest
*gpht
)
661 return (IPTR
)GMR_GADGETHIT
;
664 /* Methods follows that only need to return a value because they should be handled by
667 IPTR
GadgetClass__One(Class
*cl
, Object
*o
, Msg msg
)
672 IPTR
GadgetClass__Zero(Class
*cl
, Object
*o
, Msg msg
)
677 IPTR
GadgetClass_NoReuse(Class
*cl
, Object
*o
, Msg msg
)
679 return (IPTR
)GMR_NOREUSE
;
682 IPTR
GadgetClass__GM_HELPTEST(Class
*cl
, Object
*o
, Msg msg
)
684 DEBUG_GADGET(dprintf("dispatch_gadgetclass: GM_HELPTEST\n"));
685 return (IPTR
)GMR_HELPHIT
;
688 IPTR
GadgetClass__ICM_SETLOOP(Class
*cl
, struct GadgetData
*gd
, Msg msg
)
690 DEBUG_GADGET(dprintf("dispatch_gadgetclass: ICM_SETLOOP\n"));
691 gd
->IC
.ic_LoopCounter
+= 1UL;
696 IPTR
GadgetClass__ICM_CLEARLOOP(Class
*cl
, struct GadgetData
*gd
, Msg msg
)
698 DEBUG_GADGET(dprintf("dispatch_gadgetclass: ICM_CLEARLOOP\n"));
699 gd
->IC
.ic_LoopCounter
-= 1UL;
704 IPTR
GadgetClass__ICM_CHECKLOOP(Class
*cl
, struct GadgetData
*gd
, Msg msg
)
706 DEBUG_GADGET(dprintf("dispatch_gadgetclass: ICM_CHECKLOOP\n"));
707 return (IPTR
)gd
->IC
.ic_LoopCounter
;