/* * ResetHandler.c V1.0 * * Main program * * (c) 1991 Stefan Becker * */ #include "ResetHandler.h" /* Data */ char Version[]="$VER: ResetHandler V1.0 (27.10.1991)"; char Name[]="ResetHandler V1.0, © 1991 Stefan Becker\n"; char Message[]="System shuts down in X second(s)!"; extern struct GfxBase *GfxBase; struct Process *MyTask; struct MsgPort *KeyPort; struct IOStdReq *kior; ULONG IntSignal,IntSigMask; struct Interrupt *MyInt; struct NewWindow nw={0,0,320,100,0,1,IDCMP_CLOSEWINDOW,WFLG_CLOSEGADGET,NULL, NULL,"Shutdown Requester"}; /* In-Reset routine */ void HandleReset(void) { struct timerequest *tior; struct Screen *pubsc; struct TextFont *f; struct Window *w; struct RastPort *rp; ULONG sigmask,brkmask; UWORD top,fwidth; int i; /* Create I/O request for the timer.device */ if (!(tior=CreateIORequest(KeyPort,sizeof(struct timerequest)))) goto hre1; /* Open timer.device */ if (OpenDevice("timer.device",UNIT_MICROHZ,(struct IORequest *) tior,0)) goto hre2; /* Lock default public screen and move it to front */ if (!(pubsc=LockPubScreen(NULL))) goto hre3; ScreenToFront(pubsc); /* Calculate window border height */ if (!(f=OpenFont(pubsc->Font))) goto hre4; top=pubsc->WBorTop+f->tf_YSize+2; CloseFont(f); /* Get system default font */ f=GfxBase->DefaultFont; top+=f->tf_Baseline+30; fwidth=f->tf_XSize; /* Open Window */ if (!(w=OpenWindowTags(&nw,WA_Left,pubsc->MouseX-5, WA_Top,pubsc->MouseY-5, WA_InnerHeight,f->tf_YSize+62, WA_InnerWidth,33*fwidth+62, WA_AutoAdjust,TRUE, WA_PubScreen,pubsc, TAG_DONE))) goto hre4; rp=w->RPort; brkmask=(1L<UserPort->mp_SigBit) | SIGBREAKF_CTRL_C; sigmask=brkmask | (1L<mp_SigBit); /* Set up rastport */ SetAPen(rp,1); SetDrMd(rp,JAM2); /* Shutdown counter loop */ for (i=9; i>=0; i--) { ULONG recvsigs; /* Send timer request */ tior->tr_node.io_Command=TR_ADDREQUEST; tior->tr_time.tv_secs=1; tior->tr_time.tv_micro=0; SendIO((struct IORequest *) tior); /* Write message */ Message[21]='0' + i; Move(rp,pubsc->WBorLeft+31,top); Text(rp,Message,33); /* Wait on signals */ recvsigs=Wait(sigmask); /* Received a user break? Yes, do reset */ if (recvsigs&brkmask) { /* Abort last timer request */ AbortIO((struct IORequest *) tior); WaitIO((struct IORequest *) tior); /* Break loop */ break; } /* Remove timer message from port */ GetMsg(KeyPort); } /* Free Resources */ CloseWindow(w); hre4: UnlockPubScreen(NULL,pubsc); hre3: CloseDevice((struct IORequest *) tior); hre2: DeleteIORequest(tior); hre1: return; } /* Cleanup procedure */ void cleanup(int i) { switch(i) { case 99: case 6:FreeMem(MyInt,sizeof(struct Interrupt)); case 5:CloseDevice((struct IORequest *) kior); case 4:FreeSignal(IntSignal); case 3:DeleteIORequest(kior); case 2:DeleteMsgPort(KeyPort); case 1: case 0:break; } if (i!=99) exit(i); exit(0); } /* Reset Handler code */ __geta4 void ResetHandler(void) { /* Send wake-up signal to main process */ Signal((struct Task *) MyTask,IntSigMask); } /* Main program */ void main(int argc, char *argv[]) { BPTR fh; struct MsgPort *oldct; ULONG recvsigs; /* Create message port for keyboard.device */ if (!(KeyPort=CreateMsgPort())) cleanup(1); /* Create I/O request for keyboard.device */ if (!(kior=CreateIORequest(KeyPort,sizeof(struct IOStdReq)))) cleanup(2); /* Get signal for reset handler */ if ((IntSignal=AllocSignal(-1))==-1) cleanup(3); /* Open keyboard.device */ if (OpenDevice("keyboard.device",0,(struct IORequest *) kior,0)) cleanup(4); /* Get memory for interrupt handler node */ if (!(MyInt=AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC|MEMF_CLEAR))) cleanup(5); /* Set up data for the reset handler */ MyTask=FindTask(NULL); IntSigMask=1L<is_Node.ln_Name=Name; MyInt->is_Node.ln_Pri=32; /* Highest priority */ MyInt->is_Code=ResetHandler; /* Add reset handler */ kior->io_Data=MyInt; kior->io_Command=KBD_ADDRESETHANDLER; DoIO((struct IORequest *) kior); /* Print banner and detach from console */ if (fh=Open("CONSOLE:",MODE_NEWFILE)) { FPuts(fh,Name); Close(fh); } fclose(stdout); fclose(stdin); fclose(stderr); oldct=MyTask->pr_ConsoleTask; MyTask->pr_ConsoleTask=NULL; /* Wait until a reset or a break signal occurs */ recvsigs=Wait(IntSigMask|SIGBREAKF_CTRL_C); /* Got a signal from the reset handler? */ if (recvsigs&IntSigMask) { /* Yes, handle reset */ HandleReset(); /* Reset handler has completed, system may shut down now */ kior->io_Data=MyInt; kior->io_Command=KBD_RESETHANDLERDONE; DoIO((struct IORequest *) kior); } /* Reinstall old console task */ MyTask->pr_ConsoleTask=oldct; /* Remove reset handler */ kior->io_Data=MyInt; kior->io_Command=KBD_REMRESETHANDLER; DoIO((struct IORequest *) kior); /* All OK */ cleanup(99); }