2 Copyright 1995-2005, 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 /****************************************************************************/
50 #define IntuitionBase ((struct IntuitionBase *)cl->cl_UserData)
52 /* set gadget attributes
54 static ULONG
set_gadgetclass(Class
*cl
, struct ExtGadget
*eg
, struct opSet
*msg
)
56 const struct TagItem
*tstate
= msg
->ops_AttrList
;
59 ULONG retval
= 0UL; /* set to non-zero to signal visual changes */
61 while ( (tag
= NextTagItem(&tstate
)) )
63 tidata
= tag
->ti_Data
;
68 eg
->LeftEdge
= (WORD
)tidata
;
69 //eg->Flags &= ~GFLG_RELRIGHT;
74 eg
->TopEdge
= (WORD
)tidata
;
75 //eg->Flags &= ~GFLG_RELBOTTOM;
80 eg
->Width
= (WORD
)tidata
;
81 eg
->Flags
&= ~GFLG_RELWIDTH
;
86 eg
->Height
= (WORD
)tidata
;
87 eg
->Flags
&= ~GFLG_RELHEIGHT
;
92 eg
->LeftEdge
= (WORD
)tidata
;
93 eg
->Flags
|= GFLG_RELRIGHT
;
98 eg
->TopEdge
= (WORD
)tidata
;
99 eg
->Flags
|= GFLG_RELBOTTOM
;
104 eg
->Width
= (WORD
)tidata
;
105 eg
->Flags
|= GFLG_RELWIDTH
;
110 eg
->Height
= (WORD
)tidata
;
111 eg
->Flags
|= GFLG_RELHEIGHT
;
118 eg
->Flags
|= GFLG_RELSPECIAL
;
122 eg
->Flags
&= ~GFLG_RELSPECIAL
;
130 eg
->BoundsLeftEdge
= ((struct IBox
*)tidata
)->Left
;
131 eg
->BoundsTopEdge
= ((struct IBox
*)tidata
)->Top
;
132 eg
->BoundsWidth
= ((struct IBox
*)tidata
)->Width
;
133 eg
->BoundsHeight
= ((struct IBox
*)tidata
)->Height
;
134 eg
->MoreFlags
|= GMORE_BOUNDS
;
142 eg
->MoreFlags
|= GMORE_GADGETHELP
;
146 eg
->MoreFlags
&= ~GMORE_GADGETHELP
;
152 eg
->NextGadget
= (struct ExtGadget
*)tidata
;
156 if( (tidata
!= 0L) && (msg
->MethodID
== OM_NEW
) )
158 eg
->NextGadget
= ((struct ExtGadget
*)tidata
)->NextGadget
;
159 ((struct ExtGadget
*)tidata
)->NextGadget
= eg
;
164 eg
->GadgetText
= (struct IntuiText
*)tidata
;
167 eg
->Flags
&= ~GFLG_LABELMASK
;
168 eg
->Flags
|= GFLG_LABELITEXT
;
174 eg
->GadgetText
= (struct IntuiText
*)tidata
;
177 eg
->Flags
&= ~GFLG_LABELMASK
;
178 eg
->Flags
|= GFLG_LABELSTRING
;
184 eg
->GadgetText
= (struct IntuiText
*)tidata
;
187 eg
->Flags
&= ~GFLG_LABELMASK
;
188 eg
->Flags
|= GFLG_LABELIMAGE
;
194 eg
->GadgetRender
= (APTR
)tidata
;
197 eg
->Flags
|= GFLG_GADGIMAGE
;
203 eg
->GadgetRender
= (APTR
)tidata
;
206 eg
->Flags
&= ~GFLG_GADGIMAGE
;
211 case GA_SelectRender
:
212 eg
->SelectRender
= (APTR
)tidata
;
214 eg
->Flags
|= (GFLG_GADGIMAGE
& GFLG_GADGHIMAGE
);
220 eg
->SpecialInfo
= (APTR
)tidata
;
224 if ( tidata
!= FALSE
)
226 eg
->GadgetType
|= GTYP_GZZGADGET
;
230 eg
->GadgetType
&= ~GTYP_GZZGADGET
;
235 if ( tidata
!= FALSE
)
237 eg
->GadgetType
|= GTYP_SYSGADGET
;
241 eg
->GadgetType
&= ~GTYP_SYSGADGET
;
246 if ( tidata
!= FALSE
)
248 eg
->Flags
|= GFLG_SELECTED
;
252 eg
->Flags
&= ~GFLG_SELECTED
;
258 if ( tidata
!= FALSE
)
260 eg
->Flags
|= GFLG_DISABLED
;
264 eg
->Flags
&= ~GFLG_DISABLED
;
270 if ( tidata
!= FALSE
)
272 eg
->Activation
|= GACT_ENDGADGET
;
276 eg
->Activation
&= ~GACT_ENDGADGET
;
281 if ( tidata
!= FALSE
)
283 eg
->Activation
|= GACT_IMMEDIATE
;
287 eg
->Activation
&= ~GACT_IMMEDIATE
;
292 if ( tidata
!= FALSE
)
294 eg
->Activation
|= GACT_RELVERIFY
;
298 eg
->Activation
&= ~GACT_RELVERIFY
;
303 if ( tidata
!= FALSE
)
305 eg
->Activation
|= GACT_FOLLOWMOUSE
;
309 eg
->Activation
&= ~GACT_FOLLOWMOUSE
;
314 if ( tidata
!= FALSE
)
316 eg
->Activation
|= GACT_RIGHTBORDER
;
320 eg
->Activation
&= ~GACT_RIGHTBORDER
;
325 if ( tidata
!= FALSE
)
327 eg
->Activation
|= GACT_LEFTBORDER
;
331 eg
->Activation
&= ~GACT_LEFTBORDER
;
336 if ( tidata
!= FALSE
)
338 eg
->Activation
|= GACT_TOPBORDER
;
342 eg
->Activation
&= ~GACT_TOPBORDER
;
346 case GA_BottomBorder
:
347 if ( tidata
!= FALSE
)
349 eg
->Activation
|= GACT_BOTTOMBORDER
;
353 eg
->Activation
&= ~GACT_BOTTOMBORDER
;
357 case GA_ToggleSelect
:
360 eg
->Activation
|= GACT_TOGGLESELECT
;
364 eg
->Activation
&= ~GACT_TOGGLESELECT
;
371 eg
->Flags
|= GFLG_TABCYCLE
;
375 eg
->Flags
&= ~GFLG_TABCYCLE
;
380 eg
->Flags
&= ~GFLG_GADGHIGHBITS
;
381 eg
->Flags
|= tidata
& GFLG_GADGHIGHBITS
;
385 eg
->GadgetType
&= ~GTYP_SYSTYPEMASK
;
386 eg
->GadgetType
|= tidata
& GTYP_SYSTYPEMASK
;
390 /* GA_ID should NOT be set if this is a OM_UPDATE.
391 ** This is because gadgets should send their GA_ID
392 ** when doing a OM_NOTIFY, so that the receiver
393 ** might see who sent the message.
394 ** But we surely don't want to change the GA_ID
395 ** of the reciver to that of the sender.
397 if (msg
->MethodID
!= OM_UPDATE
)
399 eg
->GadgetID
= tidata
;
404 eg
->UserData
= (APTR
)tidata
;
405 DEBUG_GADGET(dprintf("set_gadgetclass: UserData 0x%lx\n",tidata
));
409 ((struct GadgetData
*)eg
)->IC
.ic_Target
= (Object
*)tidata
;
413 ((struct GadgetData
*)eg
)->IC
.ic_Mapping
= (struct TagItem
*)tidata
;
418 } /* while NextTagItem */
421 /* This seems to be wrong here. Instead buttongclass is where
422 something like this happens, so look there (stegerg) */
424 if ((msg
->MethodID
== OM_NEW
) &&
425 (eg
->Flags
& GFLG_GADGIMAGE
) &&
426 (eg
->GadgetRender
!= NULL
))
428 if (eg
->Width
== 0) eg
->Width
= ((struct Image
*)eg
->GadgetRender
)->Width
;
429 if (eg
->Height
== 0) eg
->Height
= ((struct Image
*)eg
->GadgetRender
)->Height
;
437 IPTR
GadgetClass__OM_NEW(Class
*cl
, Object
*o
, struct opSet
*msg
)
439 struct ExtGadget
*eg
= (struct ExtGadget
*)DoSuperMethodA(cl
, o
, (Msg
)msg
);
443 /* set some defaults */
445 * The instance object is cleared memory!
446 * memset (eg, 0, sizeof(struct GadgetData));
448 eg
->Flags
= GFLG_EXTENDED
;
449 eg
->GadgetType
= GTYP_CUSTOMGADGET
;
450 eg
->MoreFlags
= GMORE_BOOPSIGADGET
;
451 eg
->MutualExclude
= (LONG
)&((Class
*)o
)->cl_Dispatcher
;
453 /* Handle our special tags - overrides defaults */
454 set_gadgetclass(cl
, eg
, msg
);
460 IPTR
GadgetClass__OM_SET(Class
*cl
, struct ExtGadget
*eg
, struct opSet
*msg
)
462 return DoSuperMethodA(cl
, (Object
*)eg
, (Msg
)msg
) + set_gadgetclass(cl
, eg
, (struct opSet
*)msg
);
465 IPTR
GadgetClass__OM_NOTIFY(Class
*cl
, struct GadgetData
*gd
, struct opUpdate
*msg
)
467 DEBUG_GADGET(dprintf("dispatch_gadgetclass: OM_NOTIFY\n"));
468 DoNotify(cl
, (Object
*)gd
, &(gd
->IC
), msg
);
469 DEBUG_GADGET(dprintf("dispatch_gadgetclass: OM_NOTIFY done\n"));
474 IPTR
GadgetClass__OM_DISPOSE(Class
*cl
, struct GadgetData
*gd
, Msg msg
)
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
;