7 * (C) Copyright 1998 Manuel Lemos.
8 * (C) Copyright 1996-1997 Ian J. Einman.
9 * (C) Copyright 1993-1996 Jaba Development.
10 * (C) Copyright 1993-1996 Jan van den Baard.
11 * All Rights Reserved.
14 * Revision 42.9 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.8 2003/01/18 19:09:55 chodorowski
18 * Instead of using the _AROS or __AROS preprocessor symbols, use __AROS__.
20 * Revision 42.7 2000/08/09 11:45:57 chodorowski
21 * Removed a lot of #ifdefs that disabled the AROS_LIB* macros when not building on AROS. This is now handled in contrib/bgui/include/bgui_compilerspecific.h.
23 * Revision 42.6 2000/07/06 16:42:03 stegerg
24 * the function ForwardMsg relied on gpInput->gpht_Mouse.X/Y and
25 * gpHitTest.gpht_Mouse.X/Y being of type WORD. For example
26 * it used LONG reads to backup this values and a WORD * pointer
27 * to change them. Does not work with AROS where these are of
28 * type STACKWORD and not WORD.
30 * This caused the problems with the gadgets which could not be
31 * activated, or only activated by clicking somewhere outside.
33 * Revision 42.5 2000/06/01 01:41:37 bergers
34 * Only 2 linker problems left: stch_l & stcu_d. Somebody might want to replace them (embraced by #ifdef __AROS__), please.
36 * Revision 42.4 2000/05/31 01:23:10 bergers
37 * Changes to make BGUI compilable and linkable.
39 * Revision 42.3 2000/05/29 00:40:23 bergers
40 * Update to compile with AROS now. Should also still compile with SASC etc since I only made changes that test the define __AROS__. The compilation is still very noisy but it does the trick for the main directory. Maybe members of the BGUI team should also have a look at the compiler warnings because some could also cause problems on other systems... (Comparison always TRUE due to datatype (or something like that)). And please compile it on an Amiga to see whether it still works... Thanks.
42 * Revision 42.2 2000/05/15 19:27:00 stegerg
43 * another hundreds of REG() macro replacements in func headers/protos.
45 * Revision 42.1 2000/05/14 23:32:46 stegerg
46 * changed over 200 function headers which all use register
47 * parameters (oh boy ...), because the simple REG() macro
48 * doesn't work with AROS. And there are still hundreds
49 * of headers left to be fixed :(
51 * Many of these functions would also work with stack
52 * params, but since i have fixed every single one
53 * I encountered up to now, I guess will have to do
54 * the same for the rest.
56 * Revision 42.0 2000/05/09 22:08:37 mlemos
57 * Bumped to revision 42.0 before handing BGUI to AROS team
59 * Revision 41.11 2000/05/09 19:54:03 mlemos
60 * Merged with the branch Manuel_Lemos_fixes.
62 * Revision 41.10.2.12 1999/08/09 23:01:25 mlemos
63 * Optimized method lookup by using a 256 positions hash table and a simple
64 * UBYTE conversion as hash function.
66 * Revision 41.10.2.11 1999/07/29 00:42:12 mlemos
67 * Added a call MarkFreedClass at the end of a successful call to
70 * Revision 41.10.2.10 1999/01/06 19:18:18 mlemos
71 * Prevented division by 0 in the class statistics when no methods were
74 * Revision 41.10.2.9 1998/12/14 19:56:13 mlemos
75 * Replaced the binary search method lookup by hash table method lookup.
76 * Added debug code to produce statistics about method lookup on dispatching.
78 * Revision 41.10.2.8 1998/12/14 18:36:25 mlemos
79 * Added support for method inheritance to speed up method dispatching.
81 * Revision 41.10.2.7 1998/12/14 04:59:47 mlemos
82 * Replaced the assembly method dispatcher by a C dispatcher that uses binary
83 * search as method lookup.
85 * Revision 41.10.2.6 1998/11/13 18:08:10 mlemos
86 * Fixed mistaken default value for BaseInfo screen pointer in AllocBaseInfo.
88 * Revision 41.10.2.5 1998/10/18 18:22:59 mlemos
89 * Ensured that the allocated Baseinfo structure is cleared when it is not
90 * being copied from another BaseInfo structure.
92 * Revision 41.10.2.4 1998/10/12 01:21:54 mlemos
93 * Added the support for class constructor and destructor methods.
95 * Revision 41.10.2.3 1998/10/01 04:24:40 mlemos
96 * Made the class data store also BGUI global data pointer.
98 * Revision 41.10.2.2 1998/03/02 23:48:09 mlemos
99 * Switched vector allocation functions calls to BGUI allocation functions.
101 * Revision 41.10.2.1 1998/03/01 15:32:02 mlemos
102 * Added support to track BaseInfo memory leaks.
104 * Revision 41.10 1998/02/25 21:11:47 mlemos
107 * Revision 1.1 1998/02/25 17:07:51 mlemos
113 #include "include/classdefs.h"
121 #warning If something is wrong with the dispatcherfunction then look here!
123 typedef AROS_UFP4(ULONG
,* ClassMethodDispatcher
,
124 AROS_UFPA(Class
*, cl
, A0
),
125 AROS_UFPA(Object
*, obj
, A2
),
126 AROS_UFPA(Msg
, msg
, A1
),
127 AROS_UFPA(APTR
, global_data
, A4
));
130 //typedef ClassMethodDispatcher (void *);
133 typedef ASM
ULONG (*ClassMethodDispatcher
)(REG(a0
) Class
*cl
, REG(a2
) Object
*obj
, REG(a1
) Msg msg
, REG(a4
) APTR global_data
);
136 typedef struct SortedMethod
140 ULONG (*DispatcherFunction
)(Class
*, Object
*, Msg
, APTR
);
142 ClassMethodDispatcher DispatcherFunction
;
146 struct SortedMethod
*NextHashedMethod
;
153 DPFUNC
*ClassMethodFunctions
;
155 ULONG (*ClassDispatcher
)(Class
*, Object
*, Msg
, APTR
);
157 ClassMethodDispatcher ClassDispatcher
;
160 APTR ClassGlobalData
;
161 SortedMethod
*MethodFunctions
;
163 SortedMethod
**MethodHashTable
;
166 ULONG MethodComparisions
;
167 ULONG MethodColisions
;
175 #define METHOD_HASH_TABLE_SIZE 256
176 #define MethodHashValue(method) ((UBYTE)(method))
178 makeproto UBYTE
*RootClass
= "rootclass";
179 makeproto UBYTE
*ImageClass
= "imageclass";
180 makeproto UBYTE
*GadgetClass
= "gadgetclass";
181 makeproto UBYTE
*PropGClass
= "propgclass";
182 makeproto UBYTE
*StrGClass
= "strgclass";
184 makeproto Class
*BGUI_MakeClass(ULONG tag
, ...)
186 return BGUI_MakeClassA((struct TagItem
*)&tag
);
189 //static ASM ULONG ClassCallDispatcher(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) Msg msg, REG(a4) APTR global_data)
190 static ASM
REGFUNC4(ULONG
, ClassCallDispatcher
,
191 REGPARAM(A0
, Class
*, cl
),
192 REGPARAM(A2
, Object
*, obj
),
193 REGPARAM(A1
, Msg
, msg
),
194 REGPARAM(A4
, APTR
, global_data
))
196 BGUIClassData
*class_data
;
197 DPFUNC
*class_methods
;
200 && (class_data
=(BGUIClassData
*)cl
->cl_UserData
)
201 && (class_methods
=class_data
[-1].ClassMethodFunctions
))
203 for(;class_methods
->df_MethodID
!=DF_END
;class_methods
++)
204 if(class_methods
->df_MethodID
==msg
->MethodID
)
206 return AROS_UFC4(ULONG
, class_methods
->df_Func
,
207 AROS_UFCA(Class
*, cl
, A0
),
208 AROS_UFCA(Object
*, obj
, A1
),
209 AROS_UFCA(Msg
, msg
, A2
),
210 AROS_UFCA(APTR
, global_data
, A4
));
212 return(((ClassMethodDispatcher
)class_methods
->df_Func
)(cl
,obj
,msg
,global_data
));
215 switch(msg
->MethodID
)
228 ULONG (*dispatcher
)(Class
*, Object
*, Msg
, APTR
);
230 ClassMethodDispatcher dispatcher
;
238 //static ULONG ASM CallMethod(REG(a3) struct CallData *call_data)
239 static ASM
REGFUNC1(ULONG
, CallMethod
,
240 REGPARAM(A3
, struct CallData
*, call_data
))
243 register ULONG result
;
246 #warning Commented EnsureStack
250 result
=(*call_data
->dispatcher
)(call_data
->cl
,call_data
->obj
,call_data
->msg
,call_data
->global_data
);
259 static int CompareMethods(const void *method_1
, const void *method_2
)
261 return(((SortedMethod
*)method_1
)->MethodID
==((SortedMethod
*)method_2
)->MethodID
? 0 : (((SortedMethod
*)method_1
)->MethodID
>((SortedMethod
*)method_2
)->MethodID
? 1 : -1));
264 static SortedMethod
*LookupMethod(BGUIClassData
*class_data
,ULONG method
)
266 SortedMethod
*method_found
;
267 size_t lower
,upper
,index
;
270 class_data
->MethodLookups
++;
272 for(lower
=0,upper
=class_data
->MethodCount
;lower
<upper
;)
275 class_data
->MethodComparisions
++;
277 index
=(lower
+upper
)/2;
278 method_found
=class_data
->MethodFunctions
+index
;
279 if(method
==method_found
->MethodID
)
280 return(method_found
);
281 if(method
>method_found
->MethodID
)
287 class_data
->MethodComparisions
++;
292 //makeproto SAVEDS ASM ULONG __GCD( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) Msg msg)
293 makeproto SAVEDS ASM
REGFUNC3(ULONG
, __GCD
,
294 REGPARAM(A0
, Class
*, cl
),
295 REGPARAM(A2
, Object
*, obj
),
296 REGPARAM(A1
, Msg
, msg
))
298 struct CallData call_data
;
299 BGUIClassData
*class_data
;
300 SortedMethod
*method_found
;
303 || (class_data
=((BGUIClassData
*)cl
->cl_UserData
))==NULL
304 || ((--class_data
)->MethodFunctions
)==NULL
)
306 D(bug("BGUI method dispatcher was called to handle an invalid class!!\n"));
310 class_data
->MethodLookups
++;
312 for(method_found
=class_data
->MethodHashTable
[MethodHashValue(msg
->MethodID
)];method_found
&& method_found
->MethodID
!=msg
->MethodID
;method_found
=method_found
->NextHashedMethod
)
315 class_data
->MethodComparisions
++;
319 class_data
->MethodComparisions
++;
323 call_data
.cl
=method_found
->Class
;
325 call_data
.dispatcher
=method_found
->DispatcherFunction
;
327 call_data
.dispatcher
=(ClassMethodDispatcher
)method_found
->DispatcherFunction
;
329 call_data
.global_data
=method_found
->GlobalData
;
334 call_data
.dispatcher
=(call_data
.cl
=cl
->cl_Super
)->cl_Dispatcher
.h_Entry
;
336 call_data
.dispatcher
=(ClassMethodDispatcher
)(call_data
.cl
=cl
->cl_Super
)->cl_Dispatcher
.h_Entry
;
338 call_data
.global_data
=class_data
->BGUIGlobalData
;
342 return(CallMethod(&call_data
));
351 AROS_LH1(Class
*, BGUI_MakeClassA
,
352 AROS_LHA(struct TagItem
*, tags
, A0
),
353 struct Library
*, BGUIBase
, 24, BGUI
)
355 makeproto ASM Class
*BGUI_MakeClassA(REG(a0
) struct TagItem
*tags
)
362 ULONG old_a4
= (ULONG
)getreg(REG_A4
);
364 ULONG SuperClass
, SuperClass_ID
, Class_ID
, Flags
, ClassSize
, ObjectSize
;
365 BGUIClassData
*ClassData
;
373 if ((SuperClass
= GetTagData(CLASS_SuperClassBGUI
, (ULONG
)~0, tags
)) == (ULONG
)~0)
374 SuperClass
= GetTagData(CLASS_SuperClass
, NULL
, tags
);
376 SuperClass
= (ULONG
)BGUI_GetClassPtr(SuperClass
);
379 SuperClass_ID
= NULL
;
381 SuperClass_ID
= GetTagData(CLASS_SuperClassID
, (ULONG
)"rootclass", tags
);
383 Class_ID
= GetTagData(CLASS_ClassID
, NULL
, tags
);
384 Flags
= GetTagData(CLASS_Flags
, 0, tags
);
385 ClassSize
= GetTagData(CLASS_ClassSize
, 0, tags
);
386 ObjectSize
= GetTagData(CLASS_ObjectSize
, 0, tags
);
388 if (ClassData
= BGUI_AllocPoolMem(ClassSize
+ sizeof(BGUIClassData
)))
390 if (cl
= MakeClass((UBYTE
*)Class_ID
, (UBYTE
*)SuperClass_ID
, (Class
*)SuperClass
, ObjectSize
, Flags
))
392 DPFUNC
*method_functions
;
394 cl
->cl_UserData
= (LONG
)(ClassData
+1);
395 cl
->cl_Dispatcher
.h_Entry
= (HOOKFUNC
)GetTagData(CLASS_Dispatcher
, (ULONG
)__GCD
, tags
);
396 ClassData
->ClassMethodFunctions
= (DPFUNC
*)GetTagData(CLASS_ClassDFTable
, NULL
, tags
);
398 ClassData
->ClassDispatcher
= GetTagData(CLASS_ClassDispatcher
, (ULONG
)ClassCallDispatcher
, tags
);
400 ClassData
->ClassDispatcher
= (ClassMethodDispatcher
)GetTagData(CLASS_ClassDispatcher
, (ULONG
)ClassCallDispatcher
, tags
);
404 #warning Missing code here!
406 ClassData
->BGUIGlobalData
= (APTR
)getreg(REG_A4
);
407 ClassData
->ClassGlobalData
= (APTR
)old_a4
;
410 if((method_functions
=(DPFUNC
*)GetTagData(CLASS_DFTable
, NULL
, tags
)))
415 for(ClassData
->MethodCount
=0,methods
=method_functions
;methods
->df_MethodID
!=DF_END
;ClassData
->MethodCount
++,methods
++);
417 if((ClassData
->MethodFunctions
=BGUI_AllocPoolMem(sizeof(*ClassData
->MethodFunctions
)*ClassData
->MethodCount
)))
421 for(method
=0;method
<ClassData
->MethodCount
;method
++)
423 ClassData
->MethodFunctions
[method
].MethodID
=method_functions
[method
].df_MethodID
;
425 ClassData
->MethodFunctions
[method
].DispatcherFunction
=method_functions
[method
].df_Func
;
427 ClassData
->MethodFunctions
[method
].DispatcherFunction
=(ClassMethodDispatcher
)method_functions
[method
].df_Func
;
429 ClassData
->MethodFunctions
[method
].Class
=cl
;
430 ClassData
->MethodFunctions
[method
].GlobalData
=ClassData
->ClassGlobalData
;
432 qsort(ClassData
->MethodFunctions
,ClassData
->MethodCount
,sizeof(*ClassData
->MethodFunctions
),CompareMethods
);
433 if(cl
->cl_Super
->cl_Dispatcher
.h_Entry
==__GCD
)
435 BGUIClassData
*super_class_data
;
438 super_class_data
=(((BGUIClassData
*)cl
->cl_Super
->cl_UserData
)-1);
439 for(new_methods
=ClassData
->MethodCount
,method
=0;method
<super_class_data
->MethodCount
;method
++)
441 if(LookupMethod(ClassData
,super_class_data
->MethodFunctions
[method
].MethodID
)==NULL
)
443 SortedMethod
*new_sorted_methods
;
445 if((new_sorted_methods
=BGUI_AllocPoolMem(sizeof(*new_sorted_methods
)*(new_methods
+1)))==NULL
)
447 cl
->cl_UserData
=NULL
;
452 memcpy(new_sorted_methods
,ClassData
->MethodFunctions
,sizeof(*new_sorted_methods
)*new_methods
);
453 BGUI_FreePoolMem(ClassData
->MethodFunctions
);
454 ClassData
->MethodFunctions
=new_sorted_methods
;
455 ClassData
->MethodFunctions
[new_methods
]=super_class_data
->MethodFunctions
[method
];
459 ClassData
->MethodCount
=new_methods
;
460 qsort(ClassData
->MethodFunctions
,ClassData
->MethodCount
,sizeof(*ClassData
->MethodFunctions
),CompareMethods
);
464 if((ClassData
->MethodHashTable
=BGUI_AllocPoolMem(sizeof(*ClassData
->MethodHashTable
)*METHOD_HASH_TABLE_SIZE
)))
468 memset(ClassData
->MethodHashTable
,'\0',sizeof(*ClassData
->MethodHashTable
)*METHOD_HASH_TABLE_SIZE
);
470 ClassData
->MethodColisions
=0;
472 for(method
=0;method
<ClassData
->MethodCount
;method
++)
474 SortedMethod
**method_hash
;
476 method_hash
= ClassData
->MethodHashTable
+MethodHashValue(ClassData
->MethodFunctions
[method
].MethodID
);
479 ClassData
->MethodColisions
++;
481 ClassData
->MethodFunctions
[method
].NextHashedMethod
= *method_hash
;
482 *method_hash
= &ClassData
->MethodFunctions
[method
];
485 ClassData
->MethodLookups
=ClassData
->MethodComparisions
=0;
490 cl
->cl_UserData
=NULL
;
498 cl
->cl_UserData
=NULL
;
505 ClassData
->MethodFunctions
=NULL
;
506 ClassData
->MethodHashTable
=NULL
;
509 && ClassData
->ClassDispatcher
)
514 msg
.ops_AttrList
=NULL
;
516 if(!ClassData
->ClassDispatcher(cl
,NULL
,(Msg
)&msg
,ClassData
->ClassGlobalData
))
518 cl
->cl_UserData
=NULL
;
526 if(ClassData
->MethodFunctions
)
527 BGUI_FreePoolMem(ClassData
->MethodFunctions
);
528 BGUI_FreePoolMem(ClassData
);
533 putreg(REG_A4
, (LONG
)old_a4
);
542 AROS_LH1(BOOL
, BGUI_FreeClass
,
543 AROS_LHA(Class
*, cl
, A0
),
544 struct Library
*, BGUIBase
, 25, BGUI
)
546 makeproto SAVEDS ASM BOOL
BGUI_FreeClass(REG(a0
) Class
*cl
)
555 BGUIClassData
*ClassData
;
557 ClassData
=((BGUIClassData
*)cl
->cl_UserData
) - 1;
558 if(ClassData
->ClassDispatcher
)
560 ULONG msg
=OM_DISPOSE
;
562 if(!ClassData
->ClassDispatcher(cl
,NULL
,(Msg
)&msg
,ClassData
->ClassGlobalData
))
565 if(ClassData
->MethodFunctions
)
567 D(bug("Methods %lu, Lookups %lu, Comparisions %lu, Misses %lu (%lu%%), Colisions %lu (%lu%%)\n",ClassData
->MethodCount
,ClassData
->MethodLookups
,ClassData
->MethodComparisions
,ClassData
->MethodComparisions
-ClassData
->MethodLookups
,ClassData
->MethodComparisions
? (ClassData
->MethodComparisions
-ClassData
->MethodLookups
)*100/ClassData
->MethodComparisions
: 0,ClassData
->MethodColisions
,ClassData
->MethodCount
? ClassData
->MethodColisions
*100/ClassData
->MethodCount
: 0));
568 BGUI_FreePoolMem(ClassData
->MethodFunctions
);
569 BGUI_FreePoolMem(ClassData
->MethodHashTable
);
571 BGUI_FreePoolMem(ClassData
);
572 cl
->cl_UserData
=NULL
;
585 //makeproto ULONG ASM BGUI_GetAttrChart(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct rmAttr *ra)
586 makeproto ASM
REGFUNC3(ULONG
, BGUI_GetAttrChart
,
587 REGPARAM(A0
, Class
*, cl
),
588 REGPARAM(A2
, Object
*, obj
),
589 REGPARAM(A1
, struct rmAttr
*, ra
))
591 ULONG flags
= ra
->ra_Flags
;
592 struct TagItem
*attr
= ra
->ra_Attr
;
597 if (rc
= AsmCoerceMethod(cl
, obj
, RM_GETATTRFLAGS
, attr
, flags
))
599 if (!(rc
& RAF_NOGET
))
601 dataspace
= (UBYTE
*)INST_DATA(cl
, obj
) + ((rc
>> 16) & 0x07FF);
605 data
= (*dataspace
>> ((rc
>> 27) & 0x07)) & 1;
606 if (rc
& RAF_SIGNED
) data
= !data
;
610 switch (rc
& (RAF_SIGNED
|RAF_BYTE
|RAF_WORD
|RAF_LONG
|RAF_ADDR
))
613 data
= (ULONG
)(*(UBYTE
*)dataspace
);
615 case RAF_BYTE
|RAF_SIGNED
:
616 data
= (LONG
)(*(BYTE
*)dataspace
);
619 data
= (ULONG
)(*(UWORD
*)dataspace
);
621 case RAF_WORD
|RAF_SIGNED
:
622 data
= (LONG
)(*(WORD
*)dataspace
);
625 data
= (ULONG
)(*(ULONG
*)dataspace
);
627 case RAF_LONG
|RAF_SIGNED
:
628 data
= (LONG
)(*(LONG
*)dataspace
);
631 data
= (ULONG
)dataspace
;
637 *((ULONG
*)(attr
->ti_Data
)) = data
;
642 AsmCoerceMethod(cl
, obj
, RM_GETCUSTOM
, attr
, flags
);
646 rc
|= AsmDoSuperMethod(cl
, obj
, RM_GET
, attr
, flags
);
648 rc
= (rc
& 0xFFFF) | RAF_UNDERSTOOD
;
653 * Let the superclass have a go at it.
655 rc
= AsmDoSuperMethodA(cl
, obj
, (Msg
)ra
);
661 //makeproto ULONG ASM BGUI_SetAttrChart(REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) struct rmAttr *ra)
662 makeproto ASM
REGFUNC3(ULONG
, BGUI_SetAttrChart
,
663 REGPARAM(A0
, Class
*, cl
),
664 REGPARAM(A2
, Object
*, obj
),
665 REGPARAM(A1
, struct rmAttr
*, ra
))
667 ULONG flags
= ra
->ra_Flags
;
668 struct TagItem
*attr
= ra
->ra_Attr
;
670 UBYTE
*dataspace
, flag
;
673 if (rc
= AsmCoerceMethod(cl
, obj
, RM_GETATTRFLAGS
, attr
, flags
))
675 if ((rc
& RAF_NOSET
) || ((rc
& RAF_NOUPDATE
) && (flags
& RAF_UPDATE
))
676 || ((rc
& RAF_NOINTERIM
) && (flags
& RAF_INTERIM
))
677 || ((rc
& RAF_INITIAL
) && !(flags
& RAF_INITIAL
)))
683 if (flags
& RAF_INITIAL
) rc
&= ~RAF_SUPER
;
685 dataspace
= (UBYTE
*)INST_DATA(cl
, obj
) + ((rc
>> 16) & 0x07FF);
686 data
= attr
->ti_Data
;
690 flag
= 1 << ((rc
>> 27) & 0x07);
691 if (rc
& RAF_SIGNED
) data
= !data
;
693 if (data
) *dataspace
|= flag
;
694 else *dataspace
&= ~flag
;
698 switch (rc
& (RAF_SIGNED
|RAF_BYTE
|RAF_WORD
|RAF_LONG
|RAF_ADDR
))
701 case RAF_BYTE
|RAF_SIGNED
:
702 *((UBYTE
*)dataspace
) = (UBYTE
)data
;
705 case RAF_WORD
|RAF_SIGNED
:
706 *((UWORD
*)dataspace
) = (UWORD
)data
;
709 case RAF_LONG
|RAF_SIGNED
:
710 *((ULONG
*)dataspace
) = (ULONG
)data
;
719 AsmCoerceMethod(cl
, obj
, RM_SETCUSTOM
, attr
, flags
);
723 rc
|= AsmDoSuperMethod(cl
, obj
, RM_SET
, attr
, flags
);
725 rc
= (rc
& 0xFFFF) | RAF_UNDERSTOOD
;
730 * Let the superclass have a go at it.
732 rc
= AsmDoSuperMethod(cl
, obj
, RM_SET
, attr
, flags
);
738 makeproto ULONG
BGUI_PackStructureTag(UBYTE
*dataspace
, ULONG
*pt
, ULONG tag
, ULONG data
)
742 struct TagItem tags
[2];
744 tags
[0].ti_Tag
= tag
;
745 tags
[0].ti_Data
= data
;
746 tags
[1].ti_Tag
= TAG_DONE
;
748 return (ULONG
)PackStructureTags((APTR
)dataspace
, pt
, tags
);
758 if (type
== 0xFFFFFFFF)
763 if (tag
== (base
+ ((type
>> 16) & 0x03FF) ))
765 if (type
& PKCTRL_UNPACKONLY
) return 0;
767 dataspace
+= (type
& 0x1FFF);
769 switch (type
& 0x18000000)
772 flag
= 1 << ((type
>> 13) & 0x0007);
773 if (type
& PSTF_SIGNED
) data
= !data
;
774 if (data
) *dataspace
|= flag
;
775 else *dataspace
&= ~flag
;
778 *((UBYTE
*)dataspace
) = (UBYTE
)data
;
781 *((UWORD
*)dataspace
) = (UWORD
)data
;
784 *((ULONG
*)dataspace
) = (ULONG
)data
;
795 makeproto ULONG
BGUI_UnpackStructureTag(UBYTE
*dataspace
, ULONG
*pt
, ULONG tag
, ULONG
*storage
)
799 struct TagItem tags
[2];
801 tags
[0].ti_Tag
= tag
;
802 tags
[0].ti_Data
= (ULONG
)storage
;
803 tags
[1].ti_Tag
= TAG_DONE
;
805 return (ULONG
)UnpackStructureTags((APTR
)dataspace
, pt
, tags
);
814 if (type
== 0xFFFFFFFF)
819 if (tag
== (base
+ ((type
>> 16) & 0x03FF) ))
821 if (type
& PKCTRL_PACKONLY
) return 0;
823 dataspace
+= (type
& 0x1FFF);
825 switch (type
& 0x98000000)
828 data
= (ULONG
)(*((UBYTE
*)dataspace
));
831 data
= (ULONG
)(*((UWORD
*)dataspace
));
834 data
= (ULONG
)(*((ULONG
*)dataspace
));
837 data
= (LONG
)(*((BYTE
*)dataspace
));
840 data
= (LONG
)(*((WORD
*)dataspace
));
843 data
= (LONG
)(*((LONG
*)dataspace
));
847 data
= (*dataspace
& (1 << ((type
>> 13) & 0x0007))) ? ~0 : 0;
848 if (type
& PSTF_SIGNED
) data
= ~data
;
862 AROS_LH3(ULONG
, BGUI_PackStructureTags
,
863 AROS_LHA(APTR
, pack
, A0
),
864 AROS_LHA(ULONG
*, packTable
, A1
),
865 AROS_LHA(struct TagItem
*, tagList
, A2
),
866 struct Library
*, BGUIBase
, 26, BGUI
)
868 makeproto SAVEDS ULONG ASM
BGUI_PackStructureTags(REG(a0
) APTR pack
, REG(a1
) ULONG
*packTable
, REG(a2
) struct TagItem
*tagList
)
875 return PackStructureTags(pack
, packTable
, tagList
);
879 struct TagItem
*tstate
= tagList
, *tag
;
882 while (tag
= NextTagItem(&tstate
))
884 rc
+= BGUI_PackStructureTag((UBYTE
*)pack
, packTable
, tag
->ti_Tag
, tag
->ti_Data
);
895 AROS_LH3(ULONG
, BGUI_UnpackStructureTags
,
896 AROS_LHA(APTR
, pack
, A0
),
897 AROS_LHA(ULONG
*, packTable
, A1
),
898 AROS_LHA(struct TagItem
*, tagList
, A2
),
899 struct Library
*, BGUIBase
, 27, BGUI
)
901 makeproto SAVEDS ULONG ASM
BGUI_UnpackStructureTags(REG(a0
) APTR pack
, REG(a1
) ULONG
*packTable
, REG(a2
) struct TagItem
*tagList
)
908 return UnpackStructureTags(pack
, packTable
, tagList
);
912 struct TagItem
*tstate
= tagList
, *tag
;
915 while (tag
= NextTagItem(&tstate
))
917 rc
+= BGUI_UnpackStructureTag((UBYTE
*)pack
, packTable
, tag
->ti_Tag
, (ULONG
*)tag
->ti_Data
);
929 //makeproto ASM ULONG Get_Attr(REG(a0) Object *obj, REG(d0) ULONG attr, REG(a1) void *storage)
930 makeproto ASM
REGFUNC3(ULONG
, Get_Attr
,
931 REGPARAM(A0
, Object
*, obj
),
932 REGPARAM(D0
, ULONG
, attr
),
933 REGPARAM(A1
, void *, storage
))
935 return AsmDoMethod(obj
, OM_GET
, attr
, storage
);
939 //makeproto ASM ULONG Get_SuperAttr(REG(a2) Class *cl, REG(a0) Object *obj, REG(d0) ULONG attr, REG(a1) void *storage)
940 makeproto ASM
REGFUNC4(ULONG
, Get_SuperAttr
,
941 REGPARAM(A2
, Class
*, cl
),
942 REGPARAM(A0
, Object
*, obj
),
943 REGPARAM(D0
, ULONG
, attr
),
944 REGPARAM(A1
, void *, storage
))
946 return AsmDoSuperMethod(cl
, obj
, OM_GET
, attr
, storage
);
950 makeproto ULONG
NewSuperObject(Class
*cl
, Object
*obj
, struct TagItem
*tags
)
952 return AsmDoSuperMethod(cl
, obj
, OM_NEW
, (ULONG
)tags
, NULL
);
958 makeproto ULONG
DoSetMethodNG(Object
*obj
, Tag tag1
, ...)
960 if (obj
) return AsmDoMethod(obj
, OM_SET
, (struct TagItem
*)&tag1
, NULL
);
967 makeproto ULONG
DoSuperSetMethodNG(Class
*cl
, Object
*obj
, Tag tag1
, ...)
969 if (obj
) return AsmDoSuperMethod(cl
, obj
, OM_SET
, (struct TagItem
*)&tag1
, NULL
);
974 * Call the OM_SET method.
976 makeproto ULONG
DoSetMethod(Object
*obj
, struct GadgetInfo
*ginfo
, Tag tag1
, ...)
978 if (obj
) return AsmDoMethod(obj
, OM_SET
, (struct TagItem
*)&tag1
, ginfo
);
983 * Call the OM_SET method of the superclass.
985 makeproto ULONG
DoSuperSetMethod(Class
*cl
, Object
*obj
, struct GadgetInfo
*ginfo
, Tag tag1
, ...)
987 if (obj
) return AsmDoSuperMethod(cl
, obj
, OM_SET
, (struct TagItem
*)&tag1
, ginfo
);
992 * Call the OM_UPDATE method.
994 makeproto ULONG
DoUpdateMethod(Object
*obj
, struct GadgetInfo
*ginfo
, ULONG flags
, Tag tag1
, ...)
996 if (obj
) return AsmDoMethod(obj
, OM_UPDATE
, (struct TagItem
*)&tag1
, ginfo
, flags
);
1001 * Call the OM_NOTIFY method.
1003 makeproto ULONG
DoNotifyMethod(Object
*obj
, struct GadgetInfo
*ginfo
, ULONG flags
, Tag tag1
, ...)
1005 if (obj
) return AsmDoMethod(obj
, OM_NOTIFY
, (struct TagItem
*)&tag1
, ginfo
, flags
);
1010 * Call the GM_RENDER method.
1013 //makeproto ASM ULONG DoRenderMethod(REG(a0) Object *obj, REG(a1) struct GadgetInfo *ginfo, REG(d0) ULONG redraw)
1014 makeproto ASM
REGFUNC3(ULONG
, DoRenderMethod
,
1015 REGPARAM(A0
, Object
*, obj
),
1016 REGPARAM(A1
, struct GadgetInfo
*, ginfo
),
1017 REGPARAM(D0
, ULONG
, redraw
))
1019 struct RastPort
*rp
;
1022 if (obj
&& (rp
= BGUI_ObtainGIRPort(ginfo
)))
1024 rc
= AsmDoMethod(obj
, GM_RENDER
, ginfo
, rp
, redraw
);
1032 * Forward certain types of messages with modifications.
1034 //makeproto ASM ULONG ForwardMsg(REG(a0) Object *s, REG(a1) Object *d, REG(a2) Msg msg)
1035 makeproto ASM
REGFUNC3(ULONG
, ForwardMsg
,
1036 REGPARAM(A0
, Object
*, s
),
1037 REGPARAM(A1
, Object
*, d
),
1038 REGPARAM(A2
, Msg
, msg
))
1041 #define MOUSEWORD STACKWORD
1043 #define MOUSEWORD WORD
1045 MOUSEWORD
*mousex
= NULL
, *mousey
= NULL
, old_mousex
, old_mousey
;
1047 struct IBox
*b1
= GADGETBOX(s
);
1048 struct IBox
*b2
= GADGETBOX(d
);
1051 * Get address of mouse coordinates in message.
1053 switch (msg
->MethodID
)
1057 mousex
= &((struct gpHitTest
*)msg
)->gpht_Mouse
.X
;
1058 mousey
= &((struct gpHitTest
*)msg
)->gpht_Mouse
.Y
;
1061 case GM_HANDLEINPUT
:
1062 mousex
= &((struct gpInput
*)msg
)->gpi_Mouse
.X
;
1063 mousey
= &((struct gpInput
*)msg
)->gpi_Mouse
.Y
;
1066 if (!mousex
) return 0;
1069 * Store the coordinates.
1071 old_mousex
= *mousex
;
1072 old_mousey
= *mousey
;
1074 Get_Attr(s
, BT_OuterBox
, (ULONG
*)&b1
);
1075 Get_Attr(d
, BT_OuterBox
, (ULONG
*)&b2
);
1078 * Adjust the coordinates to be relative to the destination object.
1080 *mousex
+= b1
->Left
- b2
->Left
;
1081 *mousey
+= b1
->Top
- b2
->Top
;
1084 * Send the message to the destination object.
1086 rc
= AsmDoMethodA(d
, msg
);
1089 * Put the coordinates back to what they were originally.
1091 *mousex
= old_mousex
;
1092 *mousey
= old_mousey
;
1098 #define BI_FREE_RP 1
1099 #define BI_FREE_DRI 2
1102 makeproto
struct BaseInfo
*AllocBaseInfoDebug(STRPTR file
, ULONG line
,ULONG tag1
, ...)
1104 return BGUI_AllocBaseInfoDebugA((struct TagItem
*)&tag1
,file
,line
);
1107 makeproto
struct BaseInfo
*AllocBaseInfo(ULONG tag1
, ...)
1109 return BGUI_AllocBaseInfoA((struct TagItem
*)&tag1
);
1114 //makeproto SAVEDS ASM struct BaseInfo *BGUI_AllocBaseInfoDebugA(REG(a0) struct TagItem *tags,REG(a1) STRPTR file, REG(d0) ULONG line)
1115 makeproto SAVEDS ASM
REGFUNC3(struct BaseInfo
*, BGUI_AllocBaseInfoDebugA
,
1116 REGPARAM(A0
, struct TagItem
*, tags
),
1117 REGPARAM(A1
, STRPTR
, file
),
1118 REGPARAM(D0
, ULONG
, line
))
1120 //makeproto SAVEDS ASM struct BaseInfo *BGUI_AllocBaseInfoA(REG(a0) struct TagItem *tags)
1121 makeproto SAVEDS ASM
REGFUNC1(struct BaseInfo
*, BGUI_AllocBaseInfoA
,
1122 REGPARAM(A0
, struct TagItem
*, tags
))
1125 struct BaseInfo
*bi
, *bi2
;
1126 struct GadgetInfo
*gi
= NULL
;
1130 if (bi
= BGUI_AllocPoolMemDebug(sizeof(struct BaseInfo
) + sizeof(ULONG
),file
,line
))
1132 if (bi
= BGUI_AllocPoolMem(sizeof(struct BaseInfo
) + sizeof(ULONG
)))
1135 flags
= (ULONG
*)(bi
+ 1);
1137 if (bi2
= (struct BaseInfo
*)GetTagData(BI_BaseInfo
, NULL
, tags
))
1142 memset(bi
,'\0',sizeof(*bi
));
1144 if (gi
= (struct GadgetInfo
*)GetTagData(BI_GadgetInfo
, (ULONG
)gi
, tags
))
1146 *((struct GadgetInfo
*)bi
) = *gi
;
1149 bi
->bi_DrInfo
= (struct DrawInfo
*)GetTagData(BI_DrawInfo
, (ULONG
)bi
->bi_DrInfo
, tags
);
1150 bi
->bi_RPort
= (struct RastPort
*)GetTagData(BI_RastPort
, (ULONG
)bi
->bi_RPort
, tags
);
1151 bi
->bi_IScreen
= (struct Screen
*) GetTagData(BI_Screen
, (ULONG
)bi
->bi_IScreen
, tags
);
1152 bi
->bi_Pens
= (UWORD
*) GetTagData(BI_Pens
, (ULONG
)bi
->bi_Pens
, tags
);
1154 if (gi
&& !bi
->bi_RPort
)
1156 if (bi
->bi_RPort
= ObtainGIRPort(gi
))
1158 *flags
|= BI_FREE_RP
;
1162 if (bi
->bi_IScreen
&& !bi
->bi_DrInfo
)
1164 if (bi
->bi_DrInfo
= GetScreenDrawInfo(bi
->bi_IScreen
))
1166 *flags
|= BI_FREE_DRI
;
1172 if (bi
->bi_DrInfo
) bi
->bi_Pens
= bi
->bi_DrInfo
->dri_Pens
;
1173 else bi
->bi_Pens
= DefDriPens
;
1181 makeproto
void FreeBaseInfoDebug(struct BaseInfo
*bi
, STRPTR file
, ULONG line
)
1184 makeproto
void FreeBaseInfo(struct BaseInfo
*bi
)
1187 ULONG
*flags
= (ULONG
*)(bi
+ 1);
1189 if (*flags
& BI_FREE_RP
) ReleaseGIRPort(bi
->bi_RPort
);
1190 if (*flags
& BI_FREE_DRI
) FreeScreenDrawInfo(bi
->bi_IScreen
, bi
->bi_DrInfo
);
1193 BGUI_FreePoolMemDebug(bi
,file
,line
);
1195 BGUI_FreePoolMem(bi
);