#include "demo.h" #include /* Instance Data */ struct MyData { struct MsgPort *port; struct timerequest *req; struct MUI_InputHandlerNode ihnode; LONG index; }; /* Attributes and methods for the custom class */ #define MUISERIALNR_STUNTZI 1 #define TAGBASE_STUNTZI (TAG_USER | ( MUISERIALNR_STUNTZI << 16)) #define MUIM_Class5_Trigger (TAGBASE_STUNTZI | 0x0001) /* IO macros */ #define IO_SIGBIT(req) ((LONG)(((struct IORequest *)req)->io_Message.mn_ReplyPort->mp_SigBit)) #define IO_SIGMASK(req) ((LONG)(1L<port = AllocSysObjectTags(ASOT_PORT, TAG_DONE)) != NULL) { if ((data->req = (struct timerequest *)AllocSysObjectTags(ASOT_IOREQUEST, ASOIOR_Size, sizeof(*data->req), ASOIOR_ReplyPort, data->port, TAG_DONE)) != NULL) { #else if ((data->port = CreateMsgPort())) { if ((data->req = (struct timerequest *)CreateIORequest(data->port,sizeof(struct timerequest)))) { #endif if (!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)data->req,0)) { /* data->ihnode.ihn_Object = obj; data->ihnode.ihn_Signals = IO_SIGMASK(data->req); data->ihnode.ihn_Method = MUIM_Class5_Trigger; data->ihnode.ihn_Flags = 0; */ data->ihnode.ihn_Object = obj; data->ihnode.ihn_Millis = 1000; data->ihnode.ihn_Method = MUIM_Class5_Trigger; data->ihnode.ihn_Flags = MUIIHNF_TIMER; data->index = 0; return (ULONG)obj; } } } CoerceMethod(cl,obj,OM_DISPOSE); return 0; } ULONG mDispose(struct IClass *cl,Object *obj,Msg msg) { struct MyData *data = INST_DATA(cl, obj); if (data->req) { if (data->req->tr_node.io_Device) { CloseDevice((struct IORequest *)data->req); } #if defined(__amigaos4__) FreeSysObject(ASOT_IOREQUEST, data->req); #else DeleteIORequest((struct IORequest *)data->req); #endif } if (data->port) { #if defined(__amigaos4__) FreeSysObject(ASOT_PORT, data->port); #else DeleteMsgPort(data->port); #endif } return DoSuperMethodA(cl, obj, msg); } ULONG mSetup(struct IClass *cl,Object *obj,Msg msg) { struct MyData *data = INST_DATA(cl, obj); if (!DoSuperMethodA(cl,obj,msg)) return FALSE; data->req->tr_node.io_Command = TR_ADDREQUEST; data->req->tr_time.tv_secs = 1; data->req->tr_time.tv_micro = 0; SendIO((struct IORequest *)data->req); DoMethod(_app(obj),MUIM_Application_AddInputHandler,&data->ihnode); return TRUE; } ULONG mCleanup(struct IClass *cl,Object *obj,Msg msg) { struct MyData *data = INST_DATA(cl, obj); DoMethod(_app(obj),MUIM_Application_RemInputHandler,&data->ihnode); if (!CheckIO((struct IORequest *)data->req)) AbortIO((struct IORequest *)data->req); WaitIO((struct IORequest *)data->req); return DoSuperMethodA(cl, obj, msg); } ULONG mTrigger(struct IClass *cl,Object *obj,UNUSED Msg msg) { struct MyData *data = INST_DATA(cl, obj); /* if (CheckIO(data->req)) { WaitIO(data->req); data->req->tr_node.io_Command = TR_ADDREQUEST; data->req->tr_time.tv_secs = 3; data->req->tr_time.tv_micro = 0; SendIO((struct IORequest *)data->req); set(obj,MUIA_Text_Contents,LifeOfBrian[data->index]); if (!LifeOfBrian[++data->index]) data->index = 0; return TRUE; } */ set(obj,MUIA_Text_Contents,LifeOfBrian[data->index]); if (!LifeOfBrian[++data->index]) data->index = 0; return FALSE; } /* ** Here comes the dispatcher for our custom class. */ DISPATCHER(MyDispatcher) { switch(msg->MethodID) { case OM_NEW : return(mNew (cl, obj, (APTR)msg)); case OM_DISPOSE : return(mDispose(cl, obj, (APTR)msg)); case MUIM_Setup : return(mSetup (cl, obj, (APTR)msg)); case MUIM_Cleanup : return(mCleanup(cl, obj, (APTR)msg)); case MUIM_Class5_Trigger: return(mTrigger(cl, obj, (APTR)msg)); } return DoSuperMethodA(cl, obj, msg); } /***************************************************************************/ /* Thats all there is about it. Now lets see how things are used... */ /***************************************************************************/ int main(UNUSED int argc, UNUSED char *argv[]) { Object *app,*window,*MyObj; struct MUI_CustomClass *mcc; init(); /* Create the new custom class with a call to MUI_CreateCustomClass(). */ /* Caution: This function returns not a struct IClass, but a */ /* struct MUI_CustomClass which contains a struct IClass to be */ /* used with NewObject() calls. */ /* Note well: MUI creates the dispatcher hook for you, you may */ /* *not* use its h_Data field! If you need custom data, use the */ /* cl_UserData of the IClass structure! */ if (!(mcc = MUI_CreateCustomClass(NULL,MUIC_Text,NULL,sizeof(struct MyData),ENTRY(MyDispatcher)))) fail(NULL,"Could not create custom class."); // set up a specific name for our class mcc->mcc_Class->cl_ID = (ClassID)"InputHandler"; app = ApplicationObject, MUIA_Application_Title , "InputHandler", MUIA_Application_Version , "$VER: InputHandler 21.2 (24.01.2017)", MUIA_Application_Copyright , "(C) 1992-2006 Stefan Stuntz, (C) 2006-2020 Thore Boeckelmann, Jens Maus", MUIA_Application_Author , "Stefan Stuntz, Thore Boeckelmann, Jens Maus", MUIA_Application_Description, "Demonstrate the use of custom classes.", MUIA_Application_Base , "InputHandler", SubWindow, window = WindowObject, MUIA_Window_Title, "Input Handler Class", MUIA_Window_ID , MAKE_ID('C','L','S','5'), WindowContents, VGroup, Child, TextObject, TextFrame, MUIA_Background, MUII_TextBack, MUIA_Text_Contents, "\33cDemonstration of a class that reacts on\nevents (here: timer signals) automatically.", End, Child, MyObj = NewObject(mcc->mcc_Class,NULL, TextFrame, MUIA_Background, MUII_BACKGROUND, MUIA_Text_PreParse, "\33c", TAG_DONE), End, End, End; if (!app) { MUI_DeleteCustomClass(mcc); /* delete the custom class. */ fail(app,"Failed to create Application."); } DoMethod(window,MUIM_Notify,MUIA_Window_CloseRequest,TRUE, app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit); /* ** This is the ideal input loop for an object oriented MUI application. ** Everything is encapsulated in classes, no return ids need to be used, ** we just check if the program shall terminate. ** Note that MUIM_Application_NewInput expects sigs to contain the result ** from Wait() (or 0). This makes the input loop significantly faster. */ set(window,MUIA_Window_Open,TRUE); { ULONG sigs = 0; while ((LONG)DoMethod(app,MUIM_Application_NewInput,&sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } } set(window,MUIA_Window_Open,FALSE); /* ** Shut down... */ MUI_DisposeObject(app); /* dispose all objects. */ MUI_DeleteCustomClass(mcc); /* delete the custom class. */ fail(NULL,NULL); /* exit, app is already disposed. */ // just to please the compiler return 0; }