Tabs to spaces, more consistent formatting.
[AROS.git] / workbench / libs / muimaster / classes / notify.c
blob6efbd745f0119258c68fec008da5878ec31b5cd8
1 /*
2 Copyright © 2002-2006, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <stdlib.h>
7 #include <string.h>
9 #include <exec/types.h>
10 #include <clib/alib_protos.h>
11 #include <libraries/commodities.h>
12 #include <proto/commodities.h>
13 #include <proto/exec.h>
14 #include <proto/intuition.h>
15 #include <proto/utility.h>
16 #include <proto/muimaster.h>
18 #include "muimaster_intern.h"
19 #include "mui.h"
20 #include "support.h"
22 #include "notify.h"
24 #define MYDEBUG
25 #include "debug.h"
27 extern struct Library *MUIMasterBase;
29 AROS_UFH2S(void, cpy_func,
30 AROS_UFHA(UBYTE, chr, D0),
31 AROS_UFHA(STRPTR *, strPtrPtr, A3))
33 AROS_USERFUNC_INIT
35 *(*strPtrPtr)++ = chr;
37 AROS_USERFUNC_EXIT
40 AROS_UFH2S(void, len_func,
41 AROS_UFHA(UBYTE, chr, D0),
42 AROS_UFHA(LONG *, lenPtr, A3))
44 AROS_USERFUNC_INIT
46 (*lenPtr)++;
48 AROS_USERFUNC_EXIT
53 * Notify class is superclass of all other MUI classes.
57 MUIA_ApplicationObject [..G] done
58 MUIA_AppMessage [..G] dummy, no struct AppMessage
59 MUIA_HelpLine [ISG] done
60 MUIA_HelpNode [ISG] done
61 MUIA_NoNotify [.S.] done
62 MUIA_ObjectID [ISG] done
63 MUIA_Parent [..G] done
64 MUIA_Revision [..G] done
65 MUIA_UserData [ISG] done
66 MUIA_Version [..G] done
68 MUIM_CallHook done
69 MUIM_Export dummy & redefine in subclasses w/ childs
70 MUIM_FindUData redefine in subclasses w/ childs
71 MUIM_GetConfigItem
72 MUIM_GetUData redefine in subclasses w/ childs
73 MUIM_Import dummy & redefine in subclasses w/ childs
74 MUIM_KillNotify done
75 MUIM_KillNotifyObj done (semantic ?)
76 MUIM_MultiSet done
77 MUIM_NoNotifySet done
78 MUIM_Notify done
79 MUIM_Set done
80 MUIM_SetAsString done
81 MUIM_SetUData redefine in subclasses w/ childs
82 MUIM_SetUDataOnce redefine in subclasses w/ childs
83 MUIM_WriteLong done
84 MUIM_WriteString done
87 static const int __version = 1;
88 static const int __revision = 1;
91 * Notification handler
93 typedef struct NotifyNode
95 struct MinNode nn_Node;
96 BOOL nn_Active; /* TRUE if notification is currently being handled */
97 /* It's used to prevent loops */
98 ULONG nn_TrigAttr;
99 IPTR nn_TrigVal;
100 APTR nn_DestObj;
101 ULONG nn_NumParams;
102 IPTR *nn_Params; /* FIXME: use nn_Params[1] and tweak stuff below */
103 IPTR *nn_NewParams; /* For MUIV_EveryTime */
104 } *NNode;
106 typedef struct NotifyNodeIX
108 struct NotifyNode nn;
109 IX ix;
110 } *NNodeIX;
112 static struct NotifyNode *CreateNNode(struct MUI_NotifyData *data,
113 struct MUIP_Notify *msg)
115 ULONG i, paramsize;
117 struct NotifyNode *nnode;
119 if ((msg->TrigAttr == MUIA_Window_InputEvent)
120 && (msg->TrigVal != MUIV_EveryTime))
122 IX ix = { IX_VERSION };
124 if (ParseIX((CONST_STRPTR) msg->TrigVal, &ix) != 0)
125 return NULL;
127 if ((nnode =
128 (struct NotifyNode *)mui_alloc_struct(struct NotifyNodeIX)))
130 ((struct NotifyNodeIX *)nnode)->ix = ix;
133 else
135 nnode = mui_alloc_struct(struct NotifyNode);
138 if (!nnode)
139 return NULL;
141 nnode->nn_Active = FALSE;
142 nnode->nn_TrigAttr = msg->TrigAttr;
143 nnode->nn_TrigVal = msg->TrigVal;
144 nnode->nn_DestObj = msg->DestObj;
145 nnode->nn_NumParams = msg->FollowParams;
147 /* Allocate one more IPTR (FollowParams + 1) as some ext apps/classes
148 forget trailing NULLs in methods like MUIM_MultiSet and MUI seems
149 like it can live with that (without crashing) */
151 paramsize = (msg->FollowParams + 1);
152 if (msg->TrigVal == MUIV_EveryTime)
154 paramsize *= 2;
157 if ((nnode->nn_Params = (IPTR *) mui_alloc(paramsize * sizeof(IPTR))))
159 IPTR *par = (IPTR *) & msg->FollowParams;
161 for (i = 0; i < msg->FollowParams; i++)
163 nnode->nn_Params[i] = *(par + i + 1);
166 if (msg->TrigVal == MUIV_EveryTime)
168 nnode->nn_NewParams = nnode->nn_Params + msg->FollowParams + 1;
169 for (i = 0; i < msg->FollowParams; i++)
171 nnode->nn_NewParams[i] = *(par + i + 1);
175 return nnode;
178 mui_free(nnode);
180 return NULL;
183 static void DeleteNNode(struct MUI_NotifyData *data,
184 struct NotifyNode *nnode)
186 mui_free(nnode->nn_Params);
187 mui_free(nnode);
191 IPTR Notify__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg);
194 * OM_NEW
196 IPTR Notify__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
198 struct MUI_NotifyData *data;
199 struct TagItem *tags = msg->ops_AttrList;
200 struct TagItem *tag;
202 obj = (Object *) DoSuperMethodA(cl, obj, (Msg) msg);
203 if (!obj)
204 return FALSE;
206 data = INST_DATA(cl, obj);
208 while ((tag = NextTagItem(&tags)) != NULL)
210 switch (tag->ti_Tag)
212 case MUIA_HelpLine:
213 data->mnd_HelpLine = (LONG) tag->ti_Data;
214 break;
216 case MUIA_HelpNode:
217 data->mnd_HelpNode = (STRPTR) tag->ti_Data;
218 break;
220 case MUIA_ObjectID:
221 data->mnd_ObjectID = (ULONG) tag->ti_Data;
222 break;
224 case MUIA_UserData:
225 data->mnd_UserData = (IPTR) tag->ti_Data;
226 break;
230 return (IPTR) obj;
235 * OM_DISPOSE
237 IPTR Notify__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
239 struct MinNode *node, *tmp;
240 struct MUI_NotifyData *data = INST_DATA(cl, obj);
242 if (data->mnd_NotifyList)
244 for (node = data->mnd_NotifyList->mlh_Head; node->mln_Succ;
245 node = tmp)
247 tmp = node->mln_Succ;
248 DeleteNNode(data, (struct NotifyNode *)node);
250 mui_free(data->mnd_NotifyList);
253 return DoSuperMethodA(cl, obj, msg);
256 static void check_notify(NNode nnode, Object *obj, struct TagItem *tag)
258 IPTR *params;
259 APTR destobj;
260 int i;
261 BOOL donotify = FALSE;
263 /* is it the good attribute ? */
264 if (tag->ti_Tag != nnode->nn_TrigAttr)
265 return;
267 /* Is the notification already being performed? */
268 if (nnode->nn_Active)
270 #if DEBUG
271 static int counter;
273 D(bug("Notifyloop detected! (#%d)\n", counter++));
274 D(bug(" Source object: 0x%x", obj));
276 switch ((IPTR) nnode->nn_DestObj)
278 case MUIV_Notify_Application:
279 D(bug(" Dest object: 0x%x (MUIV_Notify_Application)\n",
280 _app(obj)));
281 break;
282 case MUIV_Notify_Self:
283 D(bug(" Dest object: 0x%x (MUIV_Notify_Self)\n", obj));
284 destobj = obj;
285 break;
286 case MUIV_Notify_Window:
287 if (muiRenderInfo(obj)) /* otherwise _win(obj) does NULL access! */
289 D(bug(" Dest object: 0x%x (MUIV_Notify_Window)\n",
290 _win(obj)));
292 else
294 D(bug(" Dest object: INVALID "
295 "(MUIV_Notify_Window, but no muiRenderInfo)\n"));
297 break;
298 default:
299 D(bug(" Dest object: 0x%x\n", nnode->nn_DestObj));
300 break;
302 D(bug(" Attribute: 0x%x Value: 0x%x\n", tag->ti_Tag,
303 tag->ti_Data));
305 #endif
306 return;
309 if (nnode->nn_TrigVal == MUIV_EveryTime)
311 donotify = TRUE;
313 else if (nnode->nn_TrigAttr == MUIA_Window_InputEvent)
315 if (MatchIX((struct InputEvent *)tag->ti_Data,
316 &((struct NotifyNodeIX *)nnode)->ix))
318 donotify = TRUE;
321 else if (nnode->nn_TrigVal == tag->ti_Data)
323 donotify = TRUE;
326 if (donotify)
328 switch ((IPTR) nnode->nn_DestObj)
330 case MUIV_Notify_Application:
331 destobj = _app(obj);
332 break;
333 case MUIV_Notify_Self:
334 destobj = obj;
335 break;
336 case MUIV_Notify_Window:
337 if (muiRenderInfo(obj)) /* otherwise _win(obj) does NULL access! */
339 destobj = _win(obj);
341 else
343 return;
345 break;
346 default:
347 destobj = nnode->nn_DestObj;
350 params = nnode->nn_Params;
351 if (nnode->nn_TrigVal == MUIV_EveryTime)
353 params = nnode->nn_NewParams;
355 for (i = 1; i < nnode->nn_NumParams; i++)
357 switch (nnode->nn_Params[i])
359 case MUIV_TriggerValue:
360 params[i] = tag->ti_Data;
361 break;
363 case MUIV_NotTriggerValue:
364 params[i] = !tag->ti_Data;
365 break;
370 nnode->nn_Active = TRUE;
372 /* call method */
373 DoMethodA(destobj, (Msg) params);
375 nnode->nn_Active = FALSE;
380 * OM_SET
382 IPTR Notify__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
384 struct MUI_NotifyData *data = INST_DATA(cl, obj);
385 struct TagItem *tags = msg->ops_AttrList;
386 BOOL no_notify = FALSE;
387 struct TagItem *tag;
388 struct MinNode *node;
390 /* There are many ways to find out what tag items provided by set()
391 ** we do know. The best way should be using NextTagItem() and simply
392 ** browsing through the list.
394 while ((tag = NextTagItem(&tags)) != NULL)
396 switch (tag->ti_Tag)
398 case MUIA_HelpLine:
399 data->mnd_HelpLine = (LONG) tag->ti_Data;
400 break;
402 case MUIA_HelpNode:
403 data->mnd_HelpNode = (STRPTR) tag->ti_Data;
404 break;
406 case MUIA_NoNotify:
407 if (tag->ti_Data == TRUE)
408 no_notify = TRUE;
409 break;
411 case MUIA_ObjectID:
412 data->mnd_ObjectID = (ULONG) tag->ti_Data;
413 break;
415 case MUIA_UserData:
416 data->mnd_UserData = tag->ti_Data;
417 break;
422 * check for notifications
424 if (!data->mnd_NotifyList || no_notify)
425 return 0;
427 tags = msg->ops_AttrList;
428 while ((tag = NextTagItem(&tags)))
430 for (node = data->mnd_NotifyList->mlh_Head;
431 node->mln_Succ; node = node->mln_Succ)
433 check_notify((NNode) node, obj, tag);
437 return 0;
442 * OM_GET
444 IPTR Notify__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
446 /* small macro to simplify return value storage */
447 #define STORE *(msg->opg_Storage)
449 struct MUI_NotifyData *data = INST_DATA(cl, obj);
451 //kprintf("*** Notify->GET\n");
452 switch (msg->opg_AttrID)
454 case MUIA_ApplicationObject:
455 if (data->mnd_GlobalInfo)
456 STORE = (IPTR) data->mnd_GlobalInfo->mgi_ApplicationObject;
457 else
458 STORE = 0;
459 return TRUE;
461 case MUIA_AppMessage: /* struct AppMessage ? */
462 STORE = 0;
463 return TRUE;
465 case MUIA_HelpLine:
466 STORE = (IPTR) data->mnd_HelpLine;
467 return TRUE;
469 case MUIA_HelpNode:
470 STORE = (IPTR) data->mnd_HelpNode;
471 return TRUE;
473 case MUIA_ObjectID:
474 STORE = (IPTR) data->mnd_ObjectID;
475 return TRUE;
477 case MUIA_Parent:
478 STORE = (IPTR) data->mnd_ParentObject;
479 return TRUE;
481 case MUIA_Revision:
482 STORE = __revision;
483 return TRUE;
485 case MUIA_UserData:
486 STORE = data->mnd_UserData;
487 return TRUE;
489 case MUIA_Version:
490 STORE = __version;
491 return TRUE;
494 return DoSuperMethodA(cl, obj, (Msg) msg);
499 * MUIM_CallHook : Call a standard amiga callback hook, defined by a Hook
500 * structure.
502 IPTR Notify__MUIM_CallHook(struct IClass *cl, Object *obj,
503 struct MUIP_CallHook *msg)
505 if (msg->Hook->h_Entry)
506 return CallHookPkt(msg->Hook, obj, &msg->param1);
507 else
508 return FALSE;
513 * MUIM_Export : to export an objects "contents" to a dataspace object.
515 /* nothing to export */
518 * MUIM_FindUData : tests if the MUIA_UserData of the object
519 * contains the given <udata> and returns the object pointer in this case.
521 IPTR Notify__MUIM_FindUData(struct IClass *cl, Object *obj,
522 struct MUIP_FindUData *msg)
524 struct MUI_NotifyData *data = INST_DATA(cl, obj);
526 if (data->mnd_UserData == msg->udata)
528 return (IPTR) obj;
530 return 0L;
535 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
536 * contains the given <udata> and gets <attr> to <storage> for itself
537 * in this case.
539 IPTR Notify__MUIM_GetUData(struct IClass *cl, Object *obj,
540 struct MUIP_GetUData *msg)
542 struct MUI_NotifyData *data = INST_DATA(cl, obj);
544 if (data->mnd_UserData == msg->udata)
546 get(obj, msg->attr, msg->storage);
547 return TRUE;
549 return FALSE;
554 * MUIM_Import : to import an objects "contents" from a dataspace object.
556 /* nothing to import */
559 * MUIM_KillNotify : kills previously given notifications on specific attributes.
561 IPTR Notify__MUIM_KillNotify(struct IClass *cl, Object *obj,
562 struct MUIP_KillNotify *msg)
564 struct MUI_NotifyData *data = INST_DATA(cl, obj);
565 struct MinNode *node;
566 struct NotifyNode *nnode;
568 if (!data->mnd_NotifyList)
569 return 0;
571 for (node = data->mnd_NotifyList->mlh_Head; node->mln_Succ;
572 node = node->mln_Succ)
574 nnode = (NNode) node;
575 if (msg->TrigAttr == nnode->nn_TrigAttr)
577 Remove((struct Node *)node);
578 DeleteNNode(data, nnode);
579 return 1;
582 return 0;
587 * MUIM_KillNotifyObj : originally undocumented !
588 * Supposed to kill a notification with a given attr and a given dest.
590 IPTR Notify__MUIM_KillNotifyObj(struct IClass *cl, Object *obj,
591 struct MUIP_KillNotifyObj *msg)
593 struct MUI_NotifyData *data = INST_DATA(cl, obj);
594 struct MinNode *node;
595 struct NotifyNode *nnode;
597 if (!data->mnd_NotifyList)
598 return 0;
600 for (node = data->mnd_NotifyList->mlh_Head; node->mln_Succ;
601 node = node->mln_Succ)
603 nnode = (NNode) node;
604 if ((msg->TrigAttr == nnode->nn_TrigAttr)
605 && (msg->dest == nnode->nn_DestObj))
607 Remove((struct Node *)node);
608 DeleteNNode(data, nnode);
609 return 1;
612 return 0;
617 * MUIM_MultiSet : Set an attribute for multiple objects.
619 IPTR Notify__MUIM_MultiSet(struct IClass *cl, Object *obj,
620 struct MUIP_MultiSet *msg)
622 IPTR *destobj_p;
623 for (destobj_p = (IPTR *) & msg->obj; (*destobj_p) != 0; destobj_p++)
625 set((APTR) *destobj_p, msg->attr, msg->val);
627 return TRUE;
632 * MUIM_NoNotifySet : Acts like MUIM_Set but doesn't trigger any notification.
634 IPTR Notify__MUIM_NoNotifySet(struct IClass *cl, Object *obj,
635 struct MUIP_NoNotifySet *msg)
637 return SetAttrs(obj, MUIA_NoNotify, TRUE, msg->attr, msg->val,
638 TAG_DONE);
643 * MUIM_Notify : Add a notification event handler to an object.
645 IPTR Notify__MUIM_Notify(struct IClass *cl, Object *obj,
646 struct MUIP_Notify *msg)
648 struct MUI_NotifyData *data = INST_DATA(cl, obj);
649 struct NotifyNode *nnode;
651 if (msg->FollowParams < 1)
652 return FALSE;
654 if (data->mnd_NotifyList == NULL)
656 if (!(data->mnd_NotifyList = mui_alloc_struct(struct MinList)))
657 return FALSE;
658 NewList((struct List *)data->mnd_NotifyList);
661 nnode = CreateNNode(data, msg);
662 if (NULL == nnode)
663 return FALSE;
665 AddTail((struct List *)data->mnd_NotifyList, (struct Node *)nnode);
666 return TRUE;
671 * MUIM_Set : Set an attribute to a value, useful within a MUIM_Notify method.
673 IPTR Notify__MUIM_Set(struct IClass *cl, Object *obj,
674 struct MUIP_Set *msg)
676 return set(obj, msg->attr, msg->val);
680 * MUIM_SetAsString : Set a (text kind) attribute to a string.
682 IPTR Notify__MUIM_SetAsString(struct IClass *cl, Object *obj,
683 struct MUIP_SetAsString *msg)
685 STRPTR txt;
686 LONG txt_len;
688 txt_len = 0;
689 RawDoFmt(msg->format, (ULONG *) & msg->val,
690 (VOID_FUNC) AROS_ASMSYMNAME(len_func), &txt_len);
692 /* D(bug("Notify_SetAsString: fmt=%s, txtlen=%d\n", msg->format, txt_len)); */
693 txt = AllocVec(txt_len + 1, 0);
694 if (NULL == txt)
695 return FALSE;
698 STRPTR txtptr = txt;
699 RawDoFmt(msg->format, (ULONG *) & msg->val,
700 (VOID_FUNC) AROS_ASMSYMNAME(cpy_func), &txtptr);
703 set(obj, msg->attr, (IPTR) txt);
704 FreeVec(txt);
706 return TRUE;
711 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
712 * contains the given <udata> and sets <attr> to <val> for itself in this case.
714 IPTR Notify__MUIM_SetUData(struct IClass *cl, Object *obj,
715 struct MUIP_SetUData *msg)
717 struct MUI_NotifyData *data = INST_DATA(cl, obj);
719 if (data->mnd_UserData == msg->udata)
721 set(obj, msg->attr, msg->val);
722 return TRUE;
724 return FALSE;
729 * MUIM_WriteLong : This method simply writes a longword somewhere to memory.
731 IPTR Notify__MUIM_WriteLong(struct IClass *cl, Object *obj,
732 struct MUIP_WriteLong *msg)
734 *(msg->memory) = msg->val;
735 return TRUE;
740 * MUIM_WriteString : This method simply copies a string somewhere to memory.
742 IPTR Notify__MUIM_WriteString(struct IClass *cl, Object *obj,
743 struct MUIP_WriteString *msg)
745 strcpy(msg->memory, msg->str);
746 return TRUE;
749 /**************************************************************************
750 MUIM_ConnectParent
751 **************************************************************************/
752 IPTR Notify__MUIM_ConnectParent(struct IClass *cl, Object *obj,
753 struct MUIP_ConnectParent *msg)
755 //struct MUI_NotifyData *data = INST_DATA(cl, obj);
757 /* Objects only have parents if they are inside a group or family object;
758 ** no idea why MUIA_Parent belongs to the notify class then
760 /* data->mnd_ParentObject = msg->parent;*/
761 muiGlobalInfo(obj) = muiGlobalInfo(msg->parent);
762 return TRUE;
765 /**************************************************************************
766 MUIM_DisconnectParent
767 **************************************************************************/
768 IPTR Notify__MUIM_DisconnectParent(struct IClass *cl, Object *obj,
769 struct MUIP_DisconnectParent *msg)
771 //struct MUI_NotifyData *data = INST_DATA(cl, obj);
772 /* data->mnd_ParentObject = NULL;*/
773 #if 0
774 /* Some apps (YAM) seem to access this even after disconnection */
775 muiGlobalInfo(obj) = NULL;
776 #endif
777 return 0;
780 /**************************************************************************
781 MUIM_GetConfigItem
782 **************************************************************************/
783 IPTR Notify__MUIM_GetConfigItem(struct IClass *cl, Object *obj,
784 struct MUIP_GetConfigItem *msg)
786 IPTR found =
787 DoMethod(muiGlobalInfo(obj)->mgi_Configdata, MUIM_Dataspace_Find,
788 msg->id);
790 if (found)
792 *msg->storage = found;
793 return TRUE;
795 else
797 return FALSE;
802 BOOPSI_DISPATCHER(IPTR, Notify_Dispatcher, cl, obj, msg)
804 switch (msg->MethodID)
806 case OM_NEW:
807 return Notify__OM_NEW(cl, obj, (struct opSet *)msg);
808 case OM_DISPOSE:
809 return Notify__OM_DISPOSE(cl, obj, msg);
810 case OM_SET:
811 return Notify__OM_SET(cl, obj, (struct opSet *)msg);
812 case OM_GET:
813 return Notify__OM_GET(cl, obj, (struct opGet *)msg);
814 case MUIM_CallHook:
815 return Notify__MUIM_CallHook(cl, obj, (APTR) msg);
816 case MUIM_Export:
817 return TRUE;
818 case MUIM_FindUData:
819 return Notify__MUIM_FindUData(cl, obj, (APTR) msg);
820 case MUIM_GetUData:
821 return Notify__MUIM_GetUData(cl, obj, (APTR) msg);
822 case MUIM_Import:
823 return TRUE;
824 case MUIM_KillNotify:
825 return Notify__MUIM_KillNotify(cl, obj, (APTR) msg);
826 case MUIM_KillNotifyObj:
827 return Notify__MUIM_KillNotifyObj(cl, obj, (APTR) msg);
828 case MUIM_MultiSet:
829 return Notify__MUIM_MultiSet(cl, obj, (APTR) msg);
830 case MUIM_NoNotifySet:
831 return Notify__MUIM_NoNotifySet(cl, obj, (APTR) msg);
832 case MUIM_Notify:
833 return Notify__MUIM_Notify(cl, obj, (APTR) msg);
834 case MUIM_Set:
835 return Notify__MUIM_Set(cl, obj, (APTR) msg);
836 case MUIM_SetAsString:
837 return Notify__MUIM_SetAsString(cl, obj, (APTR) msg);
838 case MUIM_SetUData:
839 return Notify__MUIM_SetUData(cl, obj, (APTR) msg);
840 case MUIM_SetUDataOnce:
841 return Notify__MUIM_SetUData(cl, obj, (APTR) msg);
842 /* use Notify_SetUData */
843 case MUIM_WriteLong:
844 return Notify__MUIM_WriteLong(cl, obj, (APTR) msg);
845 case MUIM_WriteString:
846 return Notify__MUIM_WriteString(cl, obj, (APTR) msg);
847 case MUIM_ConnectParent:
848 return Notify__MUIM_ConnectParent(cl, obj, (APTR) msg);
849 case MUIM_DisconnectParent:
850 return Notify__MUIM_DisconnectParent(cl, obj, (APTR) msg);
851 case MUIM_GetConfigItem:
852 return Notify__MUIM_GetConfigItem(cl, obj, (APTR) msg);
855 return DoSuperMethodA(cl, obj, msg);
857 BOOPSI_DISPATCHER_END
860 * Class descriptor.
862 const struct __MUIBuiltinClass _MUI_Notify_desc =
864 MUIC_Notify, /* Class name */
865 ROOTCLASS, /* super class name */
866 sizeof(struct MUI_NotifyData), /* size of class own datas */
867 (void *) Notify_Dispatcher /* class dispatcher */