home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d572 / resethandler.lha / ResetHandler / ResetHandler.c < prev    next >
C/C++ Source or Header  |  1991-12-22  |  5KB  |  215 lines

  1. /*
  2.  * ResetHandler.c  V1.0
  3.  *
  4.  * Main program
  5.  *
  6.  * (c) 1991 Stefan Becker
  7.  *
  8.  */
  9. #include "ResetHandler.h"
  10.  
  11. /* Data */
  12. char Version[]="$VER: ResetHandler V1.0 (27.10.1991)";
  13. char Name[]="ResetHandler V1.0, © 1991 Stefan Becker\n";
  14. char Message[]="System shuts down in X second(s)!";
  15. extern struct GfxBase *GfxBase;
  16. struct Process *MyTask;
  17. struct MsgPort *KeyPort;
  18. struct IOStdReq *kior;
  19. ULONG IntSignal,IntSigMask;
  20. struct Interrupt *MyInt;
  21. struct NewWindow nw={0,0,320,100,0,1,IDCMP_CLOSEWINDOW,WFLG_CLOSEGADGET,NULL,
  22.                      NULL,"Shutdown Requester"};
  23.  
  24. /* In-Reset routine */
  25. void HandleReset(void)
  26. {
  27.  struct timerequest *tior;
  28.  struct Screen *pubsc;
  29.  struct TextFont *f;
  30.  struct Window *w;
  31.  struct RastPort *rp;
  32.  ULONG sigmask,brkmask;
  33.  UWORD top,fwidth;
  34.  int i;
  35.  
  36.  /* Create I/O request for the timer.device */
  37.  if (!(tior=CreateIORequest(KeyPort,sizeof(struct timerequest)))) goto hre1;
  38.  
  39.  /* Open timer.device */
  40.  if (OpenDevice("timer.device",UNIT_MICROHZ,(struct IORequest *) tior,0))
  41.   goto hre2;
  42.  
  43.  /* Lock default public screen and move it to front */
  44.  if (!(pubsc=LockPubScreen(NULL))) goto hre3;
  45.  ScreenToFront(pubsc);
  46.  
  47.  /* Calculate window border height */
  48.  if (!(f=OpenFont(pubsc->Font))) goto hre4;
  49.  top=pubsc->WBorTop+f->tf_YSize+2;
  50.  CloseFont(f);
  51.  
  52.  /* Get system default font */
  53.  f=GfxBase->DefaultFont;
  54.  top+=f->tf_Baseline+30;
  55.  fwidth=f->tf_XSize;
  56.  
  57.  /* Open Window */
  58.  if (!(w=OpenWindowTags(&nw,WA_Left,pubsc->MouseX-5,
  59.                             WA_Top,pubsc->MouseY-5,
  60.                             WA_InnerHeight,f->tf_YSize+62,
  61.                             WA_InnerWidth,33*fwidth+62,
  62.                             WA_AutoAdjust,TRUE,
  63.                             WA_PubScreen,pubsc,
  64.                             TAG_DONE)))
  65.   goto hre4;
  66.  rp=w->RPort;
  67.  brkmask=(1L<<w->UserPort->mp_SigBit) | SIGBREAKF_CTRL_C;
  68.  sigmask=brkmask | (1L<<KeyPort->mp_SigBit);
  69.  
  70.  /* Set up rastport */
  71.  SetAPen(rp,1);
  72.  SetDrMd(rp,JAM2);
  73.  
  74.  /* Shutdown counter loop */
  75.  for (i=9; i>=0; i--)
  76.   {
  77.    ULONG recvsigs;
  78.  
  79.    /* Send timer request */
  80.    tior->tr_node.io_Command=TR_ADDREQUEST;
  81.    tior->tr_time.tv_secs=1;
  82.    tior->tr_time.tv_micro=0;
  83.    SendIO((struct IORequest *) tior);
  84.  
  85.    /* Write message */
  86.    Message[21]='0' + i;
  87.    Move(rp,pubsc->WBorLeft+31,top);
  88.    Text(rp,Message,33);
  89.  
  90.    /* Wait on signals */
  91.    recvsigs=Wait(sigmask);
  92.  
  93.    /* Received a user break? Yes, do reset */
  94.    if (recvsigs&brkmask)
  95.     {
  96.      /* Abort last timer request */
  97.      AbortIO((struct IORequest *) tior);
  98.      WaitIO((struct IORequest *) tior);
  99.  
  100.      /* Break loop */
  101.      break;
  102.     }
  103.  
  104.    /* Remove timer message from port */
  105.    GetMsg(KeyPort);
  106.   }
  107.  
  108.  /* Free Resources */
  109.       CloseWindow(w);
  110. hre4: UnlockPubScreen(NULL,pubsc);
  111. hre3: CloseDevice((struct IORequest *) tior);
  112. hre2: DeleteIORequest(tior);
  113. hre1: return;
  114. }
  115.  
  116. /* Cleanup procedure */
  117. void cleanup(int i)
  118. {
  119.  switch(i)
  120.   {
  121.    case 99:
  122.    case  6:FreeMem(MyInt,sizeof(struct Interrupt));
  123.    case  5:CloseDevice((struct IORequest *) kior);
  124.    case  4:FreeSignal(IntSignal);
  125.    case  3:DeleteIORequest(kior);
  126.    case  2:DeleteMsgPort(KeyPort);
  127.    case  1:
  128.    case  0:break;
  129.   }
  130.  
  131.  if (i!=99) exit(i);
  132.  exit(0);
  133. }
  134.  
  135. /* Reset Handler code */
  136. __geta4 void ResetHandler(void)
  137. {
  138.  /* Send wake-up signal to main process */
  139.  Signal((struct Task *) MyTask,IntSigMask);
  140. }
  141.  
  142. /* Main program */
  143. void main(int argc, char *argv[])
  144. {
  145.  BPTR fh;
  146.  struct MsgPort *oldct;
  147.  ULONG recvsigs;
  148.  
  149.  /* Create message port for keyboard.device */
  150.  if (!(KeyPort=CreateMsgPort())) cleanup(1);
  151.  
  152.  /* Create I/O request for keyboard.device */
  153.  if (!(kior=CreateIORequest(KeyPort,sizeof(struct IOStdReq)))) cleanup(2);
  154.  
  155.  /* Get signal for reset handler */
  156.  if ((IntSignal=AllocSignal(-1))==-1) cleanup(3);
  157.  
  158.  /* Open keyboard.device */
  159.  if (OpenDevice("keyboard.device",0,(struct IORequest *) kior,0)) cleanup(4);
  160.  
  161.  /* Get memory for interrupt handler node */
  162.  if (!(MyInt=AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC|MEMF_CLEAR)))
  163.   cleanup(5);
  164.  
  165.  /* Set up data for the reset handler */
  166.  MyTask=FindTask(NULL);
  167.  IntSigMask=1L<<IntSignal;
  168.  MyInt->is_Node.ln_Name=Name;
  169.  MyInt->is_Node.ln_Pri=32;    /* Highest priority */
  170.  MyInt->is_Code=ResetHandler;
  171.  
  172.  /* Add reset handler */
  173.  kior->io_Data=MyInt;
  174.  kior->io_Command=KBD_ADDRESETHANDLER;
  175.  DoIO((struct IORequest *) kior);
  176.  
  177.  /* Print banner and detach from console */
  178.  if (fh=Open("CONSOLE:",MODE_NEWFILE))
  179.   {
  180.    FPuts(fh,Name);
  181.    Close(fh);
  182.   }
  183.  fclose(stdout);
  184.  fclose(stdin);
  185.  fclose(stderr);
  186.  oldct=MyTask->pr_ConsoleTask;
  187.  MyTask->pr_ConsoleTask=NULL;
  188.  
  189.  /* Wait until a reset or a break signal occurs */
  190.  recvsigs=Wait(IntSigMask|SIGBREAKF_CTRL_C);
  191.  
  192.  /* Got a signal from the reset handler? */
  193.  if (recvsigs&IntSigMask)
  194.   {
  195.    /* Yes, handle reset */
  196.    HandleReset();
  197.  
  198.    /* Reset handler has completed, system may shut down now */
  199.    kior->io_Data=MyInt;
  200.    kior->io_Command=KBD_RESETHANDLERDONE;
  201.    DoIO((struct IORequest *) kior);
  202.   }
  203.  
  204.  /* Reinstall old console task */
  205.  MyTask->pr_ConsoleTask=oldct;
  206.  
  207.  /* Remove reset handler */
  208.  kior->io_Data=MyInt;
  209.  kior->io_Command=KBD_REMRESETHANDLER;
  210.  DoIO((struct IORequest *) kior);
  211.  
  212.  /* All OK */
  213.  cleanup(99);
  214. }
  215.