Updated to latest source.
[AROS-Contrib.git] / bgui / rootclass.c
blob9fd39438f8cc34e6fe5889b089c5bcd1d07df25d
1 /*
2 * @(#) $Header$
4 * BGUI library
5 * rootclass.c
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.
13 * $Log$
14 * Revision 42.5 2004/06/16 20:16:48 verhaegs
15 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
17 * Revision 42.4 2003/01/18 19:10:00 chodorowski
18 * Instead of using the _AROS or __AROS preprocessor symbols, use __AROS__.
20 * Revision 42.3 2000/08/17 15:09:18 chodorowski
21 * Fixed compiler warnings.
23 * Revision 42.2 2000/05/29 00:40:24 bergers
24 * 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.
26 * Revision 42.1 2000/05/15 19:27:02 stegerg
27 * another hundreds of REG() macro replacements in func headers/protos.
29 * Revision 42.0 2000/05/09 22:10:06 mlemos
30 * Bumped to revision 42.0 before handing BGUI to AROS team
32 * Revision 41.11 2000/05/09 19:55:01 mlemos
33 * Merged with the branch Manuel_Lemos_fixes.
35 * Revision 41.10.2.7 1999/07/31 01:56:37 mlemos
36 * Added calls to the code that keeps track of the created objects.
38 * Revision 41.10.2.6 1999/07/03 15:17:45 mlemos
39 * Replaced the calls to CallHookPkt to BGUI_CallHookPkt.
41 * Revision 41.10.2.5 1998/11/21 00:27:15 mlemos
42 * Fixed erroneous code in OM_UPDATE.
44 * Revision 41.10.2.4 1998/11/19 01:23:33 mlemos
45 * Fixed the return value type of BASE_ADDMAP value.
47 * Revision 41.10.2.3 1998/09/19 01:54:21 mlemos
48 * Made BASE_ADDHOOK method return TRUE on success rather than the hook linet
49 * entry pointer.
51 * Revision 41.10.2.2 1998/03/02 23:49:04 mlemos
52 * Switched vector allocation functions calls to BGUI allocation functions.
54 * Revision 41.10.2.1 1998/03/01 15:39:19 mlemos
55 * Added support to track BaseInfo memory leaks.
57 * Revision 41.10 1998/02/25 21:13:01 mlemos
58 * Bumping to 41.10
60 * Revision 1.1 1998/02/25 17:09:41 mlemos
61 * Ian sources
66 #include "include/classdefs.h"
68 #define NOTIFY_MAP 1
69 #define NOTIFY_ATTR 2
70 #define NOTIFY_METHOD 3
71 #define NOTIFY_HOOK 4
73 typedef struct Notif {
74 struct Notif *n_Next;
75 struct Notif *n_Prev;
76 UBYTE n_Type;
77 BYTE n_Pri;
78 ULONG n_Flags;
79 struct TagItem n_Condition;
80 Object *n_Object;
81 } NOTIF;
84 * Structures to track notification
86 typedef struct {
87 NOTIF m_Node;
88 struct TagItem *m_MapList;
89 } MAP;
91 typedef struct {
92 NOTIF a_Node;
93 struct TagItem a_Attr;
94 } ATTR;
96 typedef struct {
97 NOTIF m_Node;
98 ULONG m_Method[1];
99 } METHOD;
101 typedef struct {
102 NOTIF h_Node;
103 struct Hook *h_Hook;
104 } HOOK;
108 * Object instance data.
110 typedef struct {
111 struct MinNode rd_Node; /* Node for adding to objects. */
112 WORD rd_NodeOffset; /* Offset of node from object. */
113 struct MinList rd_NotifyList; /* Notification list. */
114 UWORD rd_LoopCount; /* To prevent infinite notification. */
115 } RD;
117 /// OM_NEW
119 * Create a shiny new object.
121 METHOD(RootClassNew, struct opSet *, ops)
123 RD *rd;
124 ULONG rc;
127 * We let the superclass setup an object
128 * for us.
130 if (rc = AsmDoSuperMethodA(cl, obj, (Msg)ops))
133 * Get the instance data.
135 rd = INST_DATA(cl, rc);
137 rd->rd_NodeOffset = (BYTE *)rc - (BYTE *)rd;
140 * Initialize the notification lists.
142 NewList((struct List *)&rd->rd_NotifyList);
143 #ifdef DEBUG_BGUI
144 TrackNewObject((Object *)rc,ops->ops_AttrList);
145 #endif
147 return rc;
149 METHOD_END
151 /// OM_NOTIFY
153 * We need to update our targets.
155 METHOD(RootClassNotify, struct opUpdate *, opu)
157 RD *rd = INST_DATA(cl, obj);
158 NOTIF *n = (NOTIF *)rd->rd_NotifyList.mlh_Head;
159 struct TagItem *clones;
160 Object *target;
161 struct TagItem *tag;
162 ULONG *msg;
163 ULONG rc;
164 BOOL cond;
165 int type;
168 * Make sure that the ICA_xxx
169 * attributes will function.
171 rc = AsmDoSuperMethodA(cl, obj, (Msg)opu);
174 * Broadcast the message to all
175 * targets mapping the attributes
176 * when necessary.
178 while (n->n_Next)
180 type = n->n_Type;
181 target = n->n_Object;
184 * Object counter not 0? Do not update.
186 if (target)
189 * Peng...
191 if (AsmDoMethod(target, RM_SETLOOP))
193 * Break the loop...we are done.
195 return rc;
199 * Check condition, if we have one.
201 if (n->n_Flags & (RAF_FALSE|RAF_TRUE))
203 cond = FALSE;
205 * Conditional tag present in
206 * the notification tags?
208 if (tag = FindTagItem(n->n_Condition.ti_Tag, opu->opu_AttrList))
210 cond = (n->n_Condition.ti_Data == tag->ti_Data);
211 if (n->n_Flags & RAF_FALSE) cond = !cond;
213 if (!cond) type = 0;
217 * Skip interim messages?
219 if (n->n_Flags & RAF_NO_INTERIM)
221 if (opu->opu_Flags & OPUF_INTERIM) type = 0;
224 switch (type)
226 case NOTIFY_MAP:
228 * When the object has a maplist
229 * we map the clones.
231 if (((MAP *)n)->m_MapList)
234 * Clone the original attribute list.
236 if (clones = CloneTagItems(opu->opu_AttrList))
238 MapTags(clones, ((MAP *)n)->m_MapList, MAP_KEEP_NOT_FOUND);
240 AsmDoMethod(target, OM_UPDATE, clones, (n->n_Flags & RAF_NO_GINFO) ? NULL : opu->opu_GInfo, opu->opu_Flags);
243 * Free the clones.
245 FreeTagItems(clones);
248 else
250 AsmDoMethodA(n->n_Object, (Msg)opu);
252 break;
254 case NOTIFY_ATTR:
256 * Set tag.
258 DoSetMethod(target, (n->n_Flags & RAF_NO_GINFO) ? NULL : opu->opu_GInfo,
259 ((ATTR *)n)->a_Attr.ti_Tag, ((ATTR *)n)->a_Attr.ti_Data, TAG_DONE);
260 break;
262 case NOTIFY_METHOD:
263 msg = ((METHOD *)n)->m_Method;
266 * Set GadgetInfo?
268 if (!(n->n_Flags & RAF_NO_GINFO))
270 switch (msg[0])
272 case OM_NEW:
273 case OM_SET:
274 case OM_UPDATE:
275 case OM_NOTIFY:
277 * These methods get the GadgetInfo in the third long-word.
279 msg[2] = (ULONG)opu->opu_GInfo;
280 break;
282 default:
284 * All others in the second long-word.
286 msg[1] = (ULONG)opu->opu_GInfo;
287 break;
290 AsmDoMethodA(target, (Msg)msg);
291 break;
293 case NOTIFY_HOOK:
294 if (!BGUI_CallHookPkt(((HOOK *)n)->h_Hook, (void *)obj, (void *)opu))
295 return rc;
296 break;
299 if (target) AsmDoMethod(target, RM_CLEARLOOP);
301 n = n->n_Next;
303 return rc;
305 METHOD_END
307 /// OM_DISPOSE
309 STATIC VOID FreeNotif(NOTIF *n)
311 switch (n->n_Type)
313 case NOTIFY_MAP:
314 FreeTagItems(((MAP *)n)->m_MapList);
315 break;
317 BGUI_FreePoolMem(n);
321 * They do not need us anymore.
323 METHOD(RootClassDispose, Msg, msg)
325 RD *rd = INST_DATA(cl, obj);
326 NOTIF *n;
329 * Remove all targets and deallocate all resources.
331 while (n = (NOTIF *)RemHead((struct List *)&rd->rd_NotifyList))
332 FreeNotif(n);
335 * Remove us from any list we may be in.
337 AsmDoMethod(obj, RM_REMOVE);
340 * Let the superclass dispose of us.
342 #ifdef DEBUG_BGUI
343 TrackDisposedObject(obj);
344 #endif
345 return AsmDoSuperMethodA(cl, obj, msg);
347 METHOD_END
349 /// OM_UPDATE
351 * Emulate OM_UPDATE with new methods.
353 METHOD(RootClassUpdateX, struct opUpdate *, opu)
355 ULONG rc = AsmCoerceMethod(cl,obj, RM_SETM, opu->opu_AttrList, (opu->opu_Flags & OPUF_INTERIM) ? RAF_INTERIM|RAF_UPDATE : RAF_UPDATE);
357 if (opu->opu_GInfo
358 && !(opu->opu_Flags & OPUF_INTERIM))
359 AsmDoMethod(obj, RM_REFRESH, opu->opu_GInfo, rc);
361 return rc;
363 METHOD_END
365 /// OM_SET
367 * Emulate OM_SET with new methods.
369 METHOD(RootClassSetX, struct opSet *, ops)
371 ULONG rc = AsmDoMethod(obj, RM_SETM, ops->ops_AttrList, 0);
373 if (ops->ops_GInfo) AsmDoMethod(obj, RM_REFRESH, ops->ops_GInfo, rc);
375 return rc;
377 METHOD_END
379 /// OM_GET
381 * Emulate OM_GET with new methods.
383 METHOD(RootClassGetX, struct opGet *, opg)
385 return AsmDoMethod(obj, RM_GET, &opg->opg_AttrID, 0);
387 METHOD_END
389 /// RM_SET
391 * Emulate RM_SET for any superclass.
393 METHOD(RootClassSet, struct rmAttr *, ra)
395 struct TagItem tags[2];
396 ULONG rc;
398 tags[0].ti_Tag = ra->ra_Attr->ti_Tag;
399 tags[0].ti_Data = ra->ra_Attr->ti_Data;
400 tags[1].ti_Tag = TAG_DONE;
402 rc = AsmDoSuperMethod(cl, obj, (ra->ra_Flags & RAF_UPDATE) ? OM_UPDATE : OM_SET, tags, NULL,
403 (ra->ra_Flags & RAF_INTERIM) ? OPUF_INTERIM : 0);
405 return (ULONG)0;//((rc > 0) ? (RAF_UNDERSTOOD|RAF_REDRAW) : 0);
407 METHOD_END
409 /// RM_GET
411 * Emulate RM_GET for any superclass.
413 METHOD(RootClassGet, struct rmAttr *, ra)
415 AsmDoSuperMethod(cl, obj, OM_GET, ra->ra_Attr->ti_Tag, ra->ra_Attr->ti_Data);
417 return 0;
419 METHOD_END
421 /// RM_SETM
423 METHOD(RootClassSetM, struct rmAttr *, ra1)
425 struct rmAttr ra;
426 struct TagItem *tstate = ra1->ra_Attr;
427 ULONG rc = 0;
429 ra.MethodID = RM_SET;
430 ra.ra_Flags = ra1->ra_Flags;
432 while (ra.ra_Attr = BGUI_NextTagItem(&tstate))
433 rc |= AsmDoMethodA(obj, (Msg)&ra);
435 return rc;
437 METHOD_END
439 /// RM_GETM
441 METHOD(RootClassGetM, struct rmAttr *, ra1)
443 struct rmAttr ra;
444 struct TagItem *tstate = ra1->ra_Attr;
445 ULONG rc = 0;
447 ra.MethodID = RM_GET;
448 ra.ra_Flags = ra1->ra_Flags;
450 while (ra.ra_Attr = BGUI_NextTagItem(&tstate))
451 rc |= AsmDoMethodA(obj, (Msg)&ra);
453 return rc;
455 METHOD_END
458 /// AddNotify
460 void AddNotify(RD *rd, NOTIF *n, Msg msg, int type)
463 * Set notify object.
465 n->n_Type = type;
466 n->n_Pri = ((struct rmAddAttr *)msg)->raa_Priority;
467 n->n_Flags = ((struct rmAddAttr *)msg)->raa_Flags;
468 n->n_Condition = ((struct rmAddAttr *)msg)->raa_Condition;
469 n->n_Object = ((struct rmAddAttr *)msg)->raa_Object;
472 * Add the target to the list.
474 Enqueue((struct List *)&rd->rd_NotifyList, (struct Node *)n);
477 /// RM_ADDMAP
479 * Add a map object to the list.
481 METHOD(RootClassAddMap, struct rmAddMap *, ram)
483 RD *rd = INST_DATA(cl, obj);
484 MAP *am = NULL;
487 * Check if the object is valid.
489 if (ram->ram_Object && (ram->ram_Object != obj))
492 * Allocate and initialize a MAP structure.
494 if (am = (MAP *)BGUI_AllocPoolMem(sizeof(MAP)))
497 * Check if we need to make a map list.
499 if (ram->ram_MapList)
502 * Clone the maplist.
504 if (!(am->m_MapList = CloneTagItems(ram->ram_MapList)))
506 BGUI_FreePoolMem(am);
507 return NULL;
512 * Add notification.
514 AddNotify(rd, (NOTIF *)am, (Msg)ram, NOTIFY_MAP);
517 return (ULONG)am;
519 METHOD_END
521 /// RM_ADDATTR
523 * Add an attribute conditional object to the list.
525 METHOD(RootClassAddAttr, struct rmAddAttr *, raa)
527 RD *rd = INST_DATA(cl, obj);
528 ATTR *aa = NULL;
531 * Check if the object is valid.
533 if (raa->raa_Object && (raa->raa_Object != obj))
536 * Allocate and initialize an ATTR structure.
538 if (aa = (ATTR *)BGUI_AllocPoolMem(sizeof(ATTR)))
541 * Copy the attribute.
543 aa->a_Attr = raa->raa_Attr;
546 * Add notification.
548 AddNotify(rd, (NOTIF *)aa, (Msg)raa, NOTIFY_ATTR);
551 return (ULONG)aa;
553 METHOD_END
555 /// RM_ADDMETHOD
557 * Add a method object to the list.
559 METHOD(RootClassAddMethod, struct rmAddMethod *, ram)
561 RD *rd = INST_DATA(cl, obj);
562 METHOD *am = NULL;
565 * Check if the object is valid.
567 if (ram->ram_Size && ram->ram_Object && (ram->ram_Object != obj))
570 * Allocate and initialize a METHOD structure.
572 if (am = (METHOD *)BGUI_AllocPoolMem(sizeof(METHOD) + ram->ram_Size - sizeof(ULONG)))
575 * Copy the method.
577 CopyMem((void *)&ram->ram_MethodID, (void *)am->m_Method, ram->ram_Size);
580 * Add notification.
582 AddNotify(rd, (NOTIF *)am, (Msg)ram, NOTIFY_METHOD);
585 return (ULONG)am;
587 METHOD_END
589 /// RM_ADDHOOK
591 * Add a hook to the list.
593 METHOD(RootClassAddHook, struct rmAddHook *, rah)
595 RD *rd = INST_DATA(cl, obj);
596 HOOK *ah = NULL;
599 * Check if the hook is valid.
601 if (rah->rah_Hook)
604 * Allocate and initialize a HOOK structure.
606 if (ah = (HOOK *)BGUI_AllocPoolMem(sizeof(HOOK)))
609 * Copy the hook.
611 ah->h_Hook = rah->rah_Hook;
614 * Add notification.
616 AddNotify(rd, (NOTIF *)ah, (Msg)rah, NOTIFY_HOOK);
618 ah->h_Node.n_Object = NULL;
621 return (ULONG)ah;
623 METHOD_END
627 * Remove an object from a list.
629 METHOD(NotifyClassRemove, struct bmRemove *, brt)
631 RD *rd = INST_DATA(cl, obj);
632 NOTIF *n = (NOTIF *)rd->rd_NotifyList.mlh_Head;
633 ULONG type;
635 #ifdef __AROS__
636 #warning A comment within a comment makes gcc puke...
637 #if 0
639 switch (brt->MethodID)
641 case BASE_REMMAP:
642 type = NOTIFY_TARGET;
643 break;
644 case BASE_REMCONDITIONAL:
645 type = NOTIFY_CONDITIONAL;
646 break;
647 case BASE_REMMETHOD:
648 type = NOTIFY_METHOD;
649 break;
650 case BASE_REMHOOK:
651 type = NOTIFY_HOOK;
652 break;
656 * Find an object in the target list.
658 while (n->n_Next)
660 if ((n->n_Type == type) && ((n->n_Object == brt->bar_Object) || (!n->n_Object)))
663 * Remove it from the list.
665 Remove((struct Node *)n);
668 * Deallocate the structure.
670 FreeNotif(n);
672 return 1;
674 n = n->n_Next;
677 #endif
678 #endif
679 return 0;
681 METHOD_END
683 /// RM_SETLOOP
685 * Set infinite loop counter.
687 METHOD(RootClassSetLoop, Msg, msg)
689 RD *rd = INST_DATA(cl, obj);
691 if (rd->rd_LoopCount)
692 return TRUE;
694 rd->rd_LoopCount++;
696 return FALSE;
698 METHOD_END
700 /// RM_CLEARLOOP
702 * Clear infinite loop counter.
704 METHOD(RootClassClearLoop, Msg, msg)
706 RD *rd = INST_DATA(cl, obj);
708 rd->rd_LoopCount--;
710 return FALSE;
712 METHOD_END
715 /// RM_REMOVE
717 METHOD(RootClassRemove, Msg, msg)
719 RD *rd = INST_DATA(cl, obj);
720 struct MinNode *mln = &rd->rd_Node;
722 if (mln->mln_Succ && mln->mln_Pred)
724 Remove((struct Node *)mln);
725 mln->mln_Succ = mln->mln_Pred = NULL;
726 return 1;
728 return 0;
730 METHOD_END
732 /// RM_ADDHEAD
734 METHOD(RootClassAddHead, struct rmAdd *, ra)
736 RD *rd = INST_DATA(cl, obj);
738 AddHead(ra->ra_List, (struct Node *)&rd->rd_Node);
740 return 1;
742 METHOD_END
744 /// RM_ADDTAIL
746 METHOD(RootClassAddTail, struct rmAdd *, ra)
748 RD *rd = INST_DATA(cl, obj);
750 AddTail(ra->ra_List, (struct Node *)&rd->rd_Node);
752 return 1;
754 METHOD_END
756 /// RM_INSERT
758 METHOD(RootClassInsert, struct rmInsert *, ri)
760 RD *rd = INST_DATA(cl, obj), *rd2;
762 if (ri->ri_Previous)
764 rd2 = INST_DATA(cl, ri->ri_Previous);
765 Insert(ri->ri_List, (struct Node *)&rd->rd_Node, (struct Node *)&rd2->rd_Node);
767 else
769 AddHead(ri->ri_List, (struct Node *)&rd->rd_Node);
771 return 1;
773 METHOD_END
775 /// RM_PREV
777 METHOD(RootClassPrev, Msg, msg)
779 RD *rd = INST_DATA(cl, obj);
780 struct MinNode *mn = rd->rd_Node.mln_Pred;
782 if (mn && mn->mln_Pred)
783 return (ULONG)((UBYTE *)mn + rd->rd_NodeOffset);
785 return NULL;
787 METHOD_END
789 /// RM_NEXT
791 METHOD(RootClassNext, Msg, msg)
793 RD *rd = INST_DATA(cl, obj);
794 struct MinNode *mn = rd->rd_Node.mln_Succ;
796 if (mn && mn->mln_Succ)
797 return (ULONG)((UBYTE *)mn + rd->rd_NodeOffset);
799 return NULL;
801 METHOD_END
804 makeproto Object *ListHeadObject(struct List *lh)
806 RD *rd = (RD *)(lh->lh_Head);
808 if (rd->rd_Node.mln_Succ) return (Object *)(((UBYTE *)rd) + rd->rd_NodeOffset);
809 else return NULL;
811 makeproto Object *ListTailObject(struct List *lh)
813 RD *rd = (RD *)(lh->lh_TailPred);
815 if (rd->rd_Node.mln_Pred) return (Object *)(((UBYTE *)rd) + rd->rd_NodeOffset);
816 else return NULL;
819 /// BASE_ADDMAP
821 METHOD(BaseClassAddMap, struct bmAddMap *, bam)
823 return((ULONG)(AsmDoMethod(obj, RM_ADDMAP, 0, 0, 0, 0, bam->bam_Object, bam->bam_MapList)!=NULL));
825 METHOD_END
827 /// BASE_ADDMETHOD
829 METHOD(BaseClassAddMethod, struct bmAddMethod *, bam)
831 struct rmAddMethod *ram;
833 int size = bam->bam_Size * sizeof(ULONG);
834 ULONG nh = 0;
836 if (ram = BGUI_AllocPoolMem(sizeof(struct bmAddMethod) + size))
838 ram->MethodID = RM_ADDMETHOD;
839 ram->ram_Object = bam->bam_Object;
840 ram->ram_Flags = bam->bam_Flags;
841 ram->ram_Size = size;
843 CopyMem((void *)&bam->bam_MethodID, (void *)&ram->ram_MethodID, size);
845 nh = AsmDoMethodA(obj, (Msg)ram);
847 BGUI_FreePoolMem(ram);
849 return nh;
851 METHOD_END
853 /// BASE_ADDCONDITIONAL
855 METHOD(BaseClassAddConditional, struct bmAddConditional *, bac)
857 ULONG nh;
859 if (nh = AsmDoMethod(obj, RM_ADDATTR, 0, RAF_FALSE, bac->bac_Condition.ti_Tag, bac->bac_Condition.ti_Data,
860 bac->bac_Object, bac->bac_FALSE.ti_Tag, bac->bac_FALSE.ti_Data))
862 if (AsmDoMethod(obj, RM_ADDATTR, 0, RAF_TRUE, bac->bac_Condition.ti_Tag, bac->bac_Condition.ti_Data,
863 bac->bac_Object, bac->bac_TRUE.ti_Tag, bac->bac_TRUE.ti_Data))
864 return TRUE;
866 AsmDoMethod(obj, RM_REMNOTIFY, 0, nh);
868 return FALSE;
870 METHOD_END
872 /// BASE_ADDHOOK
874 METHOD(BaseClassAddHook, struct bmAddHook *, bah)
876 return((ULONG)(AsmDoMethod(obj, RM_ADDHOOK, 0, 0, 0, 0, bah->bah_Hook)!=NULL));
878 METHOD_END
881 /// IM_DRAW
883 METHOD(ImageClassDraw, struct impDraw *, imp)
885 int x = imp->imp_Offset.X;
886 int y = imp->imp_Offset.Y;
887 ULONG rc;
888 struct BaseInfo *bi;
890 #ifdef DEBUG_BGUI
891 if (bi = AllocBaseInfoDebug(__FILE__,__LINE__,BI_RastPort, imp->imp_RPort, BI_DrawInfo, imp->imp_DrInfo, TAG_DONE))
892 #else
893 if (bi = AllocBaseInfo(BI_RastPort, imp->imp_RPort, BI_DrawInfo, imp->imp_DrInfo, TAG_DONE))
894 #endif
896 if (x) IMAGE(obj)->LeftEdge += x;
897 if (y) IMAGE(obj)->TopEdge += y;
899 rc = AsmDoMethod(obj, BASE_RENDER, bi, imp->imp_State);
901 if (x) IMAGE(obj)->LeftEdge -= x;
902 if (y) IMAGE(obj)->TopEdge -= y;
904 FreeBaseInfo(bi);
906 return rc;
908 METHOD_END
911 /// Class initialization.
913 * Class function array.
915 STATIC DPFUNC ClassFunc[] =
917 RM_SET, (FUNCPTR)RootClassSet,
918 RM_GET, (FUNCPTR)RootClassGet,
919 RM_SETM, (FUNCPTR)RootClassSetM,
920 RM_GETM, (FUNCPTR)RootClassGetM,
921 OM_SET, (FUNCPTR)RootClassSetX,
922 OM_GET, (FUNCPTR)RootClassGetX,
923 OM_UPDATE, (FUNCPTR)RootClassUpdateX,
924 OM_NEW, (FUNCPTR)RootClassNew,
925 OM_DISPOSE, (FUNCPTR)RootClassDispose,
926 OM_NOTIFY, (FUNCPTR)RootClassNotify,
927 RM_SETLOOP, (FUNCPTR)RootClassSetLoop,
928 RM_CLEARLOOP, (FUNCPTR)RootClassClearLoop,
930 RM_REMOVE, (FUNCPTR)RootClassRemove,
931 RM_ADDHEAD, (FUNCPTR)RootClassAddHead,
932 RM_ADDTAIL, (FUNCPTR)RootClassAddTail,
933 RM_INSERT, (FUNCPTR)RootClassInsert,
934 RM_NEXT, (FUNCPTR)RootClassNext,
935 RM_PREV, (FUNCPTR)RootClassPrev,
937 RM_ADDMAP, (FUNCPTR)RootClassAddMap,
938 RM_ADDATTR, (FUNCPTR)RootClassAddAttr,
939 RM_ADDMETHOD, (FUNCPTR)RootClassAddMethod,
940 RM_ADDHOOK, (FUNCPTR)RootClassAddHook,
942 BASE_ADDMAP, (FUNCPTR)BaseClassAddMap,
943 BASE_ADDCONDITIONAL, (FUNCPTR)BaseClassAddConditional,
944 BASE_ADDMETHOD, (FUNCPTR)BaseClassAddMethod,
945 BASE_ADDHOOK, (FUNCPTR)BaseClassAddHook,
946 BASE_REMMAP, (FUNCPTR)NotifyClassRemove,
947 BASE_REMCONDITIONAL, (FUNCPTR)NotifyClassRemove,
948 BASE_REMMETHOD, (FUNCPTR)NotifyClassRemove,
949 BASE_REMHOOK, (FUNCPTR)NotifyClassRemove,
951 IM_DRAW, (FUNCPTR)ImageClassDraw,
953 DF_END
956 Class *InitRootSubClass(char *superclass)
958 return BGUI_MakeClass(CLASS_SuperClassID, superclass,
959 CLASS_ObjectSize, sizeof(RD),
960 CLASS_DFTable, ClassFunc,
961 TAG_DONE);
965 * Simple class initialization.
967 makeproto Class *InitRootClass(void)
969 return InitRootSubClass("rootclass");
972 makeproto Class *InitGadgetClass(void)
974 return InitRootSubClass("gadgetclass");
977 makeproto Class *InitImageClass(void)
979 return InitRootSubClass("imageclass");