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"
120 typedef FUNCPTR ClassMethodDispatcher
;
122 typedef struct SortedMethod
125 ClassMethodDispatcher DispatcherFunction
;
128 struct SortedMethod
*NextHashedMethod
;
135 DPFUNC
*ClassMethodFunctions
;
136 ClassMethodDispatcher ClassDispatcher
;
138 APTR ClassGlobalData
;
139 SortedMethod
*MethodFunctions
;
141 SortedMethod
**MethodHashTable
;
144 ULONG MethodComparisions
;
145 ULONG MethodColisions
;
153 #define METHOD_HASH_TABLE_SIZE 256
154 #define MethodHashValue(method) ((UBYTE)(method))
156 makeproto UBYTE
*RootClass
= "rootclass";
157 makeproto UBYTE
*ImageClass
= "imageclass";
158 makeproto UBYTE
*GadgetClass
= "gadgetclass";
159 makeproto UBYTE
*PropGClass
= "propgclass";
160 makeproto UBYTE
*StrGClass
= "strgclass";
162 makeproto Class
*BGUI_MakeClass(Tag tag
, ...)
164 AROS_SLOWSTACKTAGS_PRE_AS(tag
, Class
*)
165 retval
= BGUI_MakeClassA(AROS_SLOWSTACKTAGS_ARG(tag
));
166 AROS_SLOWSTACKTAGS_POST
169 STATIC
METHOD(ClassCallDispatcher
, Msg
, msg
)
171 BGUIClassData
*class_data
;
172 DPFUNC
*class_methods
;
175 && (class_data
=(BGUIClassData
*)cl
->cl_UserData
)
176 && (class_methods
=class_data
[-1].ClassMethodFunctions
))
178 for(;class_methods
->df_MethodID
!=DF_END
;class_methods
++)
179 if(class_methods
->df_MethodID
==msg
->MethodID
)
180 return METHOD_CALL(class_methods
->df_Func
, cl
, obj
, msg
, _global
);
182 switch(msg
->MethodID
)
194 ClassMethodDispatcher dispatcher
;
201 static IPTR ASM
CallMethod(REG(a3
) struct CallData
*call_data
)
204 register IPTR result
;
207 result
=METHOD_CALL(call_data
->dispatcher
,call_data
->cl
,call_data
->obj
,call_data
->msg
,call_data
->global_data
);
212 static int CompareMethods(const void *method_1
, const void *method_2
)
214 return(((SortedMethod
*)method_1
)->MethodID
==((SortedMethod
*)method_2
)->MethodID
? 0 : (((SortedMethod
*)method_1
)->MethodID
>((SortedMethod
*)method_2
)->MethodID
? 1 : -1));
217 static SortedMethod
*LookupMethod(BGUIClassData
*class_data
,ULONG method
)
219 SortedMethod
*method_found
;
220 size_t lower
,upper
,index
;
223 class_data
->MethodLookups
++;
225 for(lower
=0,upper
=class_data
->MethodCount
;lower
<upper
;)
228 class_data
->MethodComparisions
++;
230 index
=(lower
+upper
)/2;
231 method_found
=class_data
->MethodFunctions
+index
;
232 if(method
==method_found
->MethodID
)
233 return(method_found
);
234 if(method
>method_found
->MethodID
)
240 class_data
->MethodComparisions
++;
245 //makeproto SAVEDS ASM ULONG __GCD( REG(a0) Class *cl, REG(a2) Object *obj, REG(a1) Msg msg)
246 makeproto SAVEDS ASM
REGFUNC3(IPTR
, __GCD
,
247 REGPARAM(A0
, Class
*, cl
),
248 REGPARAM(A2
, Object
*, obj
),
249 REGPARAM(A1
, Msg
, msg
))
251 struct CallData call_data
;
252 BGUIClassData
*class_data
;
253 SortedMethod
*method_found
;
256 || (class_data
=((BGUIClassData
*)cl
->cl_UserData
))==NULL
257 || ((--class_data
)->MethodFunctions
)==NULL
)
259 D(bug("BGUI method dispatcher was called to handle an invalid class!!\n"));
263 class_data
->MethodLookups
++;
265 for(method_found
=class_data
->MethodHashTable
[MethodHashValue(msg
->MethodID
)];method_found
&& method_found
->MethodID
!=msg
->MethodID
;method_found
=method_found
->NextHashedMethod
)
268 class_data
->MethodComparisions
++;
272 class_data
->MethodComparisions
++;
276 call_data
.cl
=method_found
->Class
;
277 call_data
.dispatcher
=(ClassMethodDispatcher
)method_found
->DispatcherFunction
;
278 call_data
.global_data
=method_found
->GlobalData
;
282 call_data
.dispatcher
=(ClassMethodDispatcher
)(call_data
.cl
=cl
->cl_Super
)->cl_Dispatcher
.h_Entry
;
283 call_data
.global_data
=class_data
->BGUIGlobalData
;
287 return(CallMethod(&call_data
));
296 AROS_LH1(Class
*, BGUI_MakeClassA
,
297 AROS_LHA(struct TagItem
*, tags
, A0
),
298 struct Library
*, BGUIBase
, 24, BGUI
)
300 makeproto ASM Class
*BGUI_MakeClassA(REG(a0
) struct TagItem
*tags
)
305 IPTR old_a4
= (IPTR
)getreg(REG_A4
);
306 IPTR SuperClass
, SuperClass_ID
, Class_ID
;
307 ULONG Flags
, ClassSize
, ObjectSize
;
308 BGUIClassData
*ClassData
;
313 if ((SuperClass
= GetTagData(CLASS_SuperClassBGUI
, (IPTR
)~0, tags
)) == (IPTR
)~0)
314 SuperClass
= GetTagData(CLASS_SuperClass
, (IPTR
)NULL
, tags
);
316 SuperClass
= (IPTR
)BGUI_GetClassPtr(SuperClass
);
321 SuperClass_ID
= GetTagData(CLASS_SuperClassID
, (IPTR
)"rootclass", tags
);
323 Class_ID
= GetTagData(CLASS_ClassID
, (IPTR
)NULL
, tags
);
324 Flags
= (ULONG
)GetTagData(CLASS_Flags
, 0, tags
);
325 ClassSize
= (ULONG
)GetTagData(CLASS_ClassSize
, 0, tags
);
326 ObjectSize
= (ULONG
)GetTagData(CLASS_ObjectSize
, 0, tags
);
328 if ((ClassData
= BGUI_AllocPoolMem(ClassSize
+ sizeof(BGUIClassData
))))
330 if ((cl
= MakeClass((UBYTE
*)Class_ID
, (UBYTE
*)SuperClass_ID
, (Class
*)SuperClass
, ObjectSize
, Flags
)))
332 DPFUNC
*method_functions
;
334 cl
->cl_UserData
= (IPTR
)(&ClassData
[1]);
335 cl
->cl_Dispatcher
.h_Entry
= (HOOKFUNC
)GetTagData(CLASS_Dispatcher
, (IPTR
)__GCD
, tags
);
336 ClassData
->ClassMethodFunctions
= (DPFUNC
*)GetTagData(CLASS_ClassDFTable
, (IPTR
)NULL
, tags
);
337 ClassData
->ClassDispatcher
= (ClassMethodDispatcher
)GetTagData(CLASS_ClassDispatcher
, (IPTR
)ClassCallDispatcher
, tags
);
339 ClassData
->BGUIGlobalData
= (APTR
)getreg(REG_A4
);
340 ClassData
->ClassGlobalData
= (APTR
)old_a4
;
342 if((method_functions
=(DPFUNC
*)GetTagData(CLASS_DFTable
, 0, tags
)))
347 for(ClassData
->MethodCount
=0,methods
=method_functions
;methods
->df_MethodID
!=DF_END
;ClassData
->MethodCount
++,methods
++);
349 if((ClassData
->MethodFunctions
=BGUI_AllocPoolMem(sizeof(*ClassData
->MethodFunctions
)*ClassData
->MethodCount
)))
353 for(method
=0;method
<ClassData
->MethodCount
;method
++)
355 ClassData
->MethodFunctions
[method
].MethodID
=method_functions
[method
].df_MethodID
;
356 ClassData
->MethodFunctions
[method
].DispatcherFunction
=(ClassMethodDispatcher
)method_functions
[method
].df_Func
;
357 ClassData
->MethodFunctions
[method
].Class
=cl
;
358 ClassData
->MethodFunctions
[method
].GlobalData
=ClassData
->ClassGlobalData
;
360 qsort(ClassData
->MethodFunctions
,ClassData
->MethodCount
,sizeof(*ClassData
->MethodFunctions
),CompareMethods
);
361 if(cl
->cl_Super
->cl_Dispatcher
.h_Entry
==(APTR
)__GCD
)
363 BGUIClassData
*super_class_data
;
366 super_class_data
=(((BGUIClassData
*)cl
->cl_Super
->cl_UserData
)-1);
367 for(new_methods
=ClassData
->MethodCount
,method
=0;method
<super_class_data
->MethodCount
;method
++)
369 if(LookupMethod(ClassData
,super_class_data
->MethodFunctions
[method
].MethodID
)==NULL
)
371 SortedMethod
*new_sorted_methods
;
373 if((new_sorted_methods
=BGUI_AllocPoolMem(sizeof(*new_sorted_methods
)*(new_methods
+1)))==NULL
)
380 memcpy(new_sorted_methods
,ClassData
->MethodFunctions
,sizeof(*new_sorted_methods
)*new_methods
);
381 BGUI_FreePoolMem(ClassData
->MethodFunctions
);
382 ClassData
->MethodFunctions
=new_sorted_methods
;
383 ClassData
->MethodFunctions
[new_methods
]=super_class_data
->MethodFunctions
[method
];
387 ClassData
->MethodCount
=new_methods
;
388 qsort(ClassData
->MethodFunctions
,ClassData
->MethodCount
,sizeof(*ClassData
->MethodFunctions
),CompareMethods
);
392 if((ClassData
->MethodHashTable
=BGUI_AllocPoolMem(sizeof(*ClassData
->MethodHashTable
)*METHOD_HASH_TABLE_SIZE
)))
396 memset(ClassData
->MethodHashTable
,'\0',sizeof(*ClassData
->MethodHashTable
)*METHOD_HASH_TABLE_SIZE
);
398 ClassData
->MethodColisions
=0;
400 for(method
=0;method
<ClassData
->MethodCount
;method
++)
402 SortedMethod
**method_hash
;
404 method_hash
= ClassData
->MethodHashTable
+MethodHashValue(ClassData
->MethodFunctions
[method
].MethodID
);
407 ClassData
->MethodColisions
++;
409 ClassData
->MethodFunctions
[method
].NextHashedMethod
= *method_hash
;
410 *method_hash
= &ClassData
->MethodFunctions
[method
];
413 ClassData
->MethodLookups
=ClassData
->MethodComparisions
=0;
433 ClassData
->MethodFunctions
=NULL
;
434 ClassData
->MethodHashTable
=NULL
;
437 && ClassData
->ClassDispatcher
)
442 msg
.ops_AttrList
=NULL
;
444 if(!METHOD_CALL(ClassData
->ClassDispatcher
,cl
,NULL
,(Msg
)&msg
,ClassData
->ClassGlobalData
))
454 if(ClassData
->MethodFunctions
)
455 BGUI_FreePoolMem(ClassData
->MethodFunctions
);
456 BGUI_FreePoolMem(ClassData
);
459 putreg(REG_A4
, (IPTR
)old_a4
);
467 AROS_LH1(BOOL
, BGUI_FreeClass
,
468 AROS_LHA(Class
*, cl
, A0
),
469 struct Library
*, BGUIBase
, 25, BGUI
)
471 makeproto SAVEDS ASM BOOL
BGUI_FreeClass(REG(a0
) Class
*cl
)
480 BGUIClassData
*ClassData
;
482 ClassData
=((BGUIClassData
*)cl
->cl_UserData
) - 1;
483 if(ClassData
->ClassDispatcher
)
485 ULONG msg
=OM_DISPOSE
;
487 if(!METHOD_CALL(ClassData
->ClassDispatcher
,cl
,NULL
,(Msg
)&msg
,ClassData
->ClassGlobalData
))
490 if(ClassData
->MethodFunctions
)
492 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));
493 BGUI_FreePoolMem(ClassData
->MethodFunctions
);
494 BGUI_FreePoolMem(ClassData
->MethodHashTable
);
496 BGUI_FreePoolMem(ClassData
);
510 makeproto ULONG ASM
BGUI_GetAttrChart(REG(a0
) Class
*cl
, REG(a2
) Object
*obj
, REG(a1
) struct rmAttr
*ra
)
512 ULONG flags
= ra
->ra_Flags
;
513 struct TagItem
*attr
= ra
->ra_Attr
;
518 if ((rc
= (ULONG
)AsmCoerceMethod(cl
, obj
, RM_GETATTRFLAGS
, attr
, flags
)))
520 if (!(rc
& RAF_NOGET
))
522 dataspace
= (UBYTE
*)INST_DATA(cl
, obj
) + ((rc
>> 16) & 0x07FF);
526 data
= (*dataspace
>> ((rc
>> 27) & 0x07)) & 1;
527 if (rc
& RAF_SIGNED
) data
= !data
;
531 switch (rc
& (RAF_SIGNED
|RAF_BYTE
|RAF_WORD
|RAF_LONG
|RAF_IPTR
|RAF_ADDR
))
534 data
= (IPTR
)(*(UBYTE
*)dataspace
);
536 case RAF_BYTE
|RAF_SIGNED
:
537 data
= (IPTR
)(*(BYTE
*)dataspace
);
540 data
= (IPTR
)(*(UWORD
*)dataspace
);
542 case RAF_WORD
|RAF_SIGNED
:
543 data
= (IPTR
)(*(WORD
*)dataspace
);
546 data
= (IPTR
)(*(ULONG
*)dataspace
);
548 case RAF_LONG
|RAF_SIGNED
:
549 data
= (IPTR
)(*(LONG
*)dataspace
);
552 data
= *(IPTR
*)dataspace
;
555 case RAF_ADDR
|RAF_IPTR
:
556 data
= (IPTR
)dataspace
;
562 *((IPTR
*)(attr
->ti_Data
)) = data
;
567 AsmCoerceMethod(cl
, obj
, RM_GETCUSTOM
, attr
, flags
);
571 rc
|= (ULONG
)AsmDoSuperMethod(cl
, obj
, RM_GET
, attr
, flags
);
573 rc
= (rc
& 0xFFFF) | RAF_UNDERSTOOD
;
578 * Let the superclass have a go at it.
580 rc
= (ULONG
)AsmDoSuperMethodA(cl
, obj
, (Msg
)ra
);
585 makeproto ULONG ASM
BGUI_SetAttrChart(REG(a0
) Class
*cl
, REG(a2
) Object
*obj
, REG(a1
) struct rmAttr
*ra
)
587 ULONG flags
= ra
->ra_Flags
;
588 struct TagItem
*attr
= ra
->ra_Attr
;
590 UBYTE
*dataspace
, flag
;
593 if ((rc
= (ULONG
)AsmCoerceMethod(cl
, obj
, RM_GETATTRFLAGS
, attr
, flags
)))
595 if ((rc
& RAF_NOSET
) || ((rc
& RAF_NOUPDATE
) && (flags
& RAF_UPDATE
))
596 || ((rc
& RAF_NOINTERIM
) && (flags
& RAF_INTERIM
))
597 || ((rc
& RAF_INITIAL
) && !(flags
& RAF_INITIAL
)))
603 if (flags
& RAF_INITIAL
) rc
&= ~RAF_SUPER
;
605 dataspace
= (UBYTE
*)INST_DATA(cl
, obj
) + ((rc
>> 16) & 0x07FF);
606 data
= attr
->ti_Data
;
610 flag
= 1 << ((rc
>> 27) & 0x07);
611 if (rc
& RAF_SIGNED
) data
= !data
;
613 if (data
) *dataspace
|= flag
;
614 else *dataspace
&= ~flag
;
618 switch (rc
& (RAF_SIGNED
|RAF_BYTE
|RAF_WORD
|RAF_LONG
|RAF_IPTR
|RAF_ADDR
))
621 case RAF_BYTE
|RAF_SIGNED
:
622 *((UBYTE
*)dataspace
) = (UBYTE
)data
;
625 case RAF_WORD
|RAF_SIGNED
:
626 *((UWORD
*)dataspace
) = (UWORD
)data
;
629 case RAF_LONG
|RAF_SIGNED
:
630 *((ULONG
*)dataspace
) = (ULONG
)data
;
633 *(IPTR
*)dataspace
= data
;
641 AsmCoerceMethod(cl
, obj
, RM_SETCUSTOM
, attr
, flags
);
645 rc
|= (ULONG
)AsmDoSuperMethod(cl
, obj
, RM_SET
, attr
, flags
);
647 rc
= (rc
& 0xFFFF) | RAF_UNDERSTOOD
;
652 * Let the superclass have a go at it.
654 rc
= (ULONG
)AsmDoSuperMethod(cl
, obj
, RM_SET
, attr
, flags
);
659 makeproto ULONG
BGUI_PackStructureTag(UBYTE
*dataspace
, ULONG
*pt
, Tag tag
, IPTR data
)
663 struct TagItem tags
[2];
665 tags
[0].ti_Tag
= tag
;
666 tags
[0].ti_Data
= (ULONG
)data
; // FIXME
667 tags
[1].ti_Tag
= TAG_DONE
;
669 return PackStructureTags(dataspace
, pt
, tags
);
679 if (type
== 0xFFFFFFFF)
684 if (tag
== (base
+ ((type
>> 16) & 0x03FF) ))
686 if (type
& PKCTRL_UNPACKONLY
) return 0;
688 dataspace
+= (type
& 0x1FFF);
690 switch (type
& 0x18000000)
693 flag
= 1 << ((type
>> 13) & 0x0007);
694 if (type
& PSTF_SIGNED
) data
= !data
;
695 if (data
) *dataspace
|= flag
;
696 else *dataspace
&= ~flag
;
699 *((UBYTE
*)dataspace
) = (UBYTE
)data
;
702 *((UWORD
*)dataspace
) = (UWORD
)data
;
705 *((ULONG
*)dataspace
) = (ULONG
)data
;
716 makeproto ULONG
BGUI_UnpackStructureTag(UBYTE
*dataspace
, ULONG
*pt
, Tag tag
, IPTR
*storage
)
720 struct TagItem tags
[2];
722 tags
[0].ti_Tag
= tag
;
723 tags
[0].ti_Data
= (ULONG
)(IPTR
)storage
;/* FIXME */
724 tags
[1].ti_Tag
= TAG_DONE
;
726 return UnpackStructureTags(dataspace
, pt
, tags
);
735 if (type
== 0xFFFFFFFF)
740 if (tag
== (base
+ ((type
>> 16) & 0x03FF) ))
742 if (type
& PKCTRL_PACKONLY
) return 0;
744 dataspace
+= (type
& 0x1FFF);
746 switch (type
& 0x98000000)
749 data
= (ULONG
)(*((UBYTE
*)dataspace
));
752 data
= (ULONG
)(*((UWORD
*)dataspace
));
755 data
= (ULONG
)(*((ULONG
*)dataspace
));
758 data
= (LONG
)(*((BYTE
*)dataspace
));
761 data
= (LONG
)(*((WORD
*)dataspace
));
764 data
= (LONG
)(*((LONG
*)dataspace
));
768 data
= (*dataspace
& (1 << ((type
>> 13) & 0x0007))) ? ~0 : 0;
769 if (type
& PSTF_SIGNED
) data
= ~data
;
783 AROS_LH3(ULONG
, BGUI_PackStructureTags
,
784 AROS_LHA(APTR
, pack
, A0
),
785 AROS_LHA(ULONG
*, packTable
, A1
),
786 AROS_LHA(struct TagItem
*, tagList
, A2
),
787 struct Library
*, BGUIBase
, 26, BGUI
)
789 makeproto SAVEDS ULONG ASM
BGUI_PackStructureTags(REG(a0
) APTR pack
, REG(a1
) ULONG
*packTable
, REG(a2
) struct TagItem
*tagList
)
796 return PackStructureTags(pack
, packTable
, tagList
);
800 struct TagItem
*tstate
= tagList
, *tag
;
803 while (tag
= NextTagItem(&tstate
))
805 rc
+= BGUI_PackStructureTag((UBYTE
*)pack
, packTable
, tag
->ti_Tag
, tag
->ti_Data
);
816 AROS_LH3(ULONG
, BGUI_UnpackStructureTags
,
817 AROS_LHA(APTR
, pack
, A0
),
818 AROS_LHA(ULONG
*, packTable
, A1
),
819 AROS_LHA(struct TagItem
*, tagList
, A2
),
820 struct Library
*, BGUIBase
, 27, BGUI
)
822 makeproto SAVEDS ULONG ASM
BGUI_UnpackStructureTags(REG(a0
) APTR pack
, REG(a1
) ULONG
*packTable
, REG(a2
) struct TagItem
*tagList
)
829 return UnpackStructureTags(pack
, packTable
, tagList
);
833 struct TagItem
*tstate
= tagList
, *tag
;
836 while ((tag
= NextTagItem(&tstate
)))
838 rc
+= BGUI_UnpackStructureTag((UBYTE
*)pack
, packTable
, tag
->ti_Tag
, (ULONG
*)tag
->ti_Data
);
850 makeproto ASM ULONG
Get_Attr(REG(a0
) Object
*obj
, REG(d0
) ULONG attr
, REG(a1
) IPTR
*storage
)
852 return (ULONG
)AsmDoMethod(obj
, OM_GET
, attr
, storage
);
855 makeproto ASM ULONG
Get_SuperAttr(REG(a2
) Class
*cl
, REG(a0
) Object
*obj
, REG(d0
) ULONG attr
, REG(a1
) IPTR
*storage
)
857 return (ULONG
)AsmDoSuperMethod(cl
, obj
, OM_GET
, attr
, storage
);
860 makeproto IPTR
NewSuperObject(Class
*cl
, Object
*obj
, struct TagItem
*tags
)
862 return AsmDoSuperMethod(cl
, obj
, OM_NEW
, (IPTR
)tags
, NULL
);
868 makeproto ULONG
DoSetMethodNG(Object
*obj
, Tag tag1
, ...)
870 AROS_SLOWSTACKTAGS_PRE_AS(tag1
, ULONG
)
871 if (obj
) retval
= (ULONG
)AsmDoMethod(obj
, OM_SET
, AROS_SLOWSTACKTAGS_ARG(tag1
), NULL
);
873 AROS_SLOWSTACKTAGS_POST
879 makeproto ULONG
DoSuperSetMethodNG(Class
*cl
, Object
*obj
, Tag tag1
, ...)
881 AROS_SLOWSTACKTAGS_PRE_AS(tag1
, ULONG
)
882 if (obj
) retval
= (ULONG
)AsmDoSuperMethod(cl
, obj
, OM_SET
, AROS_SLOWSTACKTAGS_ARG(tag1
), NULL
);
884 AROS_SLOWSTACKTAGS_POST
888 * Call the OM_SET method.
890 makeproto ULONG
DoSetMethod(Object
*obj
, struct GadgetInfo
*ginfo
, Tag tag1
, ...)
892 AROS_SLOWSTACKTAGS_PRE_AS(tag1
, ULONG
)
893 if (obj
) retval
= (ULONG
)AsmDoMethod(obj
, OM_SET
, AROS_SLOWSTACKTAGS_ARG(tag1
), ginfo
);
895 AROS_SLOWSTACKTAGS_POST
899 * Call the OM_SET method of the superclass.
901 makeproto ULONG
DoSuperSetMethod(Class
*cl
, Object
*obj
, struct GadgetInfo
*ginfo
, Tag tag1
, ...)
903 AROS_SLOWSTACKTAGS_PRE_AS(tag1
, ULONG
)
904 if (obj
) retval
= (ULONG
)AsmDoSuperMethod(cl
, obj
, OM_SET
, AROS_SLOWSTACKTAGS_ARG(tag1
), ginfo
);
906 AROS_SLOWSTACKTAGS_POST
910 * Call the OM_UPDATE method.
912 makeproto ULONG
DoUpdateMethod(Object
*obj
, struct GadgetInfo
*ginfo
, ULONG flags
, Tag tag1
, ...)
914 AROS_SLOWSTACKTAGS_PRE_AS(tag1
, ULONG
)
915 if (obj
) retval
= (ULONG
)AsmDoMethod(obj
, OM_UPDATE
, AROS_SLOWSTACKTAGS_ARG(tag1
), ginfo
, flags
);
917 AROS_SLOWSTACKTAGS_POST
921 * Call the OM_NOTIFY method.
923 makeproto ULONG
DoNotifyMethod(Object
*obj
, struct GadgetInfo
*ginfo
, ULONG flags
, Tag tag1
, ...)
925 AROS_SLOWSTACKTAGS_PRE_AS(tag1
, ULONG
)
926 if (obj
) retval
= (ULONG
)AsmDoMethod(obj
, OM_NOTIFY
, AROS_SLOWSTACKTAGS_ARG(tag1
), ginfo
, flags
);
928 AROS_SLOWSTACKTAGS_POST
932 * Call the GM_RENDER method.
935 makeproto ASM IPTR
DoRenderMethod(REG(a0
) Object
*obj
, REG(a1
) struct GadgetInfo
*ginfo
, REG(d0
) ULONG redraw
)
940 if (obj
&& (rp
= BGUI_ObtainGIRPort(ginfo
)))
942 rc
= AsmDoMethod(obj
, GM_RENDER
, ginfo
, rp
, redraw
);
949 * Forward certain types of messages with modifications.
951 makeproto ASM IPTR
ForwardMsg(REG(a0
) Object
*s
, REG(a1
) Object
*d
, REG(a2
) Msg msg
)
954 #define MOUSEWORD STACKED WORD
956 #define MOUSEWORD WORD
958 MOUSEWORD
*mousex
= NULL
, *mousey
= NULL
, old_mousex
, old_mousey
;
960 struct IBox
*b1
= GADGETBOX(s
);
961 struct IBox
*b2
= GADGETBOX(d
);
964 * Get address of mouse coordinates in message.
966 switch (msg
->MethodID
)
970 mousex
= &((struct gpHitTest
*)msg
)->gpht_Mouse
.X
;
971 mousey
= &((struct gpHitTest
*)msg
)->gpht_Mouse
.Y
;
975 mousex
= &((struct gpInput
*)msg
)->gpi_Mouse
.X
;
976 mousey
= &((struct gpInput
*)msg
)->gpi_Mouse
.Y
;
979 if (!mousex
) return 0;
982 * Store the coordinates.
984 old_mousex
= *mousex
;
985 old_mousey
= *mousey
;
987 Get_Attr(s
, BT_OuterBox
, (IPTR
*)&b1
);
988 Get_Attr(d
, BT_OuterBox
, (IPTR
*)&b2
);
991 * Adjust the coordinates to be relative to the destination object.
993 *mousex
+= b1
->Left
- b2
->Left
;
994 *mousey
+= b1
->Top
- b2
->Top
;
997 * Send the message to the destination object.
999 rc
= AsmDoMethodA(d
, msg
);
1002 * Put the coordinates back to what they were originally.
1004 *mousex
= old_mousex
;
1005 *mousey
= old_mousey
;
1010 #define BI_FREE_RP 1
1011 #define BI_FREE_DRI 2
1014 makeproto
struct BaseInfo
*AllocBaseInfoDebug(STRPTR file
, ULONG line
,Tag tag1
, ...)
1016 AROS_SLOWSTACKTAGS_PRE_AS(tag1
, struct BaseInfo
*)
1017 retval
= BGUI_AllocBaseInfoDebugA(AROS_SLOWSTACKTAGS_ARG(tag1
),file
,line
);
1018 AROS_SLOWSTACKTAGS_POST
1021 makeproto
struct BaseInfo
*AllocBaseInfo(Tag tag1
, ...)
1023 AROS_SLOWSTACKTAGS_PRE_AS(tag1
, struct BaseInfo
*)
1024 retval
= BGUI_AllocBaseInfoA(AROS_SLOWSTACKTAGS_ARG(tag1
));
1025 AROS_SLOWSTACKTAGS_POST
1030 makeproto SAVEDS ASM
struct BaseInfo
*BGUI_AllocBaseInfoDebugA(REG(a0
) struct TagItem
*tags
,REG(a1
) STRPTR file
, REG(d0
) ULONG line
)
1032 makeproto SAVEDS ASM
struct BaseInfo
*BGUI_AllocBaseInfoA(REG(a0
) struct TagItem
*tags
)
1035 struct BaseInfo
*bi
, *bi2
;
1036 struct GadgetInfo
*gi
= NULL
;
1040 if ((bi
= BGUI_AllocPoolMemDebug(sizeof(struct BaseInfo
) + sizeof(ULONG
),file
,line
)))
1042 if ((bi
= BGUI_AllocPoolMem(sizeof(struct BaseInfo
) + sizeof(ULONG
))))
1045 flags
= (ULONG
*)(bi
+ 1);
1047 if ((bi2
= (struct BaseInfo
*)GetTagData(BI_BaseInfo
, 0, tags
)))
1052 memset(bi
,'\0',sizeof(*bi
));
1054 if ((gi
= (struct GadgetInfo
*)GetTagData(BI_GadgetInfo
, (IPTR
)gi
, tags
)))
1056 *((struct GadgetInfo
*)bi
) = *gi
;
1059 bi
->bi_DrInfo
= (struct DrawInfo
*)GetTagData(BI_DrawInfo
, (IPTR
)bi
->bi_DrInfo
, tags
);
1060 bi
->bi_RPort
= (struct RastPort
*)GetTagData(BI_RastPort
, (IPTR
)bi
->bi_RPort
, tags
);
1061 bi
->bi_IScreen
= (struct Screen
*) GetTagData(BI_Screen
, (IPTR
)bi
->bi_IScreen
, tags
);
1062 bi
->bi_Pens
= (UWORD
*) GetTagData(BI_Pens
, (IPTR
)bi
->bi_Pens
, tags
);
1064 if (gi
&& !bi
->bi_RPort
)
1066 if ((bi
->bi_RPort
= ObtainGIRPort(gi
)))
1068 *flags
|= BI_FREE_RP
;
1072 if (bi
->bi_IScreen
&& !bi
->bi_DrInfo
)
1074 if ((bi
->bi_DrInfo
= GetScreenDrawInfo(bi
->bi_IScreen
)))
1076 *flags
|= BI_FREE_DRI
;
1082 if (bi
->bi_DrInfo
) bi
->bi_Pens
= bi
->bi_DrInfo
->dri_Pens
;
1083 else bi
->bi_Pens
= DefDriPens
;
1090 makeproto
void FreeBaseInfoDebug(struct BaseInfo
*bi
, STRPTR file
, ULONG line
)
1093 makeproto
void FreeBaseInfo(struct BaseInfo
*bi
)
1096 ULONG
*flags
= (ULONG
*)(bi
+ 1);
1098 if (*flags
& BI_FREE_RP
) ReleaseGIRPort(bi
->bi_RPort
);
1099 if (*flags
& BI_FREE_DRI
) FreeScreenDrawInfo(bi
->bi_IScreen
, bi
->bi_DrInfo
);
1102 BGUI_FreePoolMemDebug(bi
,file
,line
);
1104 BGUI_FreePoolMem(bi
);