home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
563.lha
/
ResetHandler_v1.0
/
ResetHandler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-28
|
5KB
|
215 lines
/*
* 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<<w->UserPort->mp_SigBit) | SIGBREAKF_CTRL_C;
sigmask=brkmask | (1L<<KeyPort->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<<IntSignal;
MyInt->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);
}