home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / comm / misc / timer / timer.c < prev    next >
C/C++ Source or Header  |  1993-08-12  |  10KB  |  378 lines

  1. /***********************************************************************
  2.   Timer.c (c) HooverSoft 1993. Freely distributable for non-commercial
  3.   purposes.
  4.  
  5.   It started as another test program, now it's actually turned into
  6.   something useful. :-)
  7.  
  8.   Before I say anything else: The timer.device routines were completely
  9.   ripped off from Mike Meyer's "mclk.c". Mike, I'm definitely not going
  10.   to make money out of this, but thanks very much for mclk.c :-)
  11.  
  12.   Contact me at hoover@mathematik.uni-bielefeld.de if you have questions
  13.   or suggestions for improvements.
  14. ***********************************************************************/
  15.  
  16.  /* Includes that we need */
  17. #include <exec/types.h>
  18. #include <intuition/intuition.h>
  19. #include <intuition/intuitionbase.h>
  20. #include <devices/timer.h>
  21. #include <stdio.h>
  22.  
  23.  
  24. char *_procname = "Timer";
  25.  
  26. #define WINX 253        /* STD window size */
  27. #define WINY 27
  28. #define STARTGAD 10        /* Gadget ID's */
  29. #define STOPGAD 11
  30. #define BLACK 1            /* Color definitions */
  31. #define WHITE 2
  32. #define GREY 0
  33. #define PURPLE 3
  34. #define GADWIDTH 45        /* Gadget Dims */
  35. #define GADHEIGHT 10
  36. #define LOGNAME "S:Timer.log"    /* Log file name */
  37. static struct timerequest Time_Req;
  38. static struct MsgPort *Timer_Port = NULL, *CreatePort ();
  39.  
  40. /******************************************************************
  41.   Command line Options and their respective default values
  42.   autostart: NO
  43.   interval:  8 mins
  44.   activescreen: NO
  45.   logging: NO
  46.   x = 10
  47.   y = 10
  48. ******************************************************************/
  49.  
  50. ULONG AUTOSTART = 0, INTERVAL = 8, ACTIVE_SCREEN = 0, LOGGING = 0;
  51. UWORD x = 10, y = 10;
  52.  
  53. ULONG seconds = 0;        /* total time elapsed */
  54. struct NewWindow nw =
  55. {00, 11,
  56.  /* start LeftEdge, TopEdge */
  57.  WINX, WINY,            /* start Width, Height */
  58.  AUTOFRONTPEN, AUTOBACKPEN,    /* DetailPen, BlockPen */
  59.  GADGETUP | CLOSEWINDOW,    /* IDCMP FLAGS */
  60.  WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE,
  61.  /* Flags (can be NULL) */
  62.  NULL,                /* Pointer to FirstGadget */
  63.  NULL,                /* no pointer to first CheckMark */
  64.  (UBYTE *) "Timer V1.04 © HooverSoft",      /* Title (can be NULL) */
  65.  NULL,                /* no Pointer to Screen */
  66.  NULL,                /* no Pointer to BitMap */
  67.  -1, -1,
  68.  -1, -1,
  69.  WBENCHSCREEN            /* Type of screen window appears in */
  70. };
  71.  
  72.  /* Signal masks for our ports */
  73. #define WINMASK 1L << window -> UserPort -> mp_SigBit
  74. #define TMASK 1L << Timer_Port -> mp_SigBit
  75.  /* Global variables */
  76. struct Window *window = NULL;
  77. struct IntuitionBase *IntuitionBase = NULL;
  78. SHORT WHITEvecs[] =
  79. {0, 0, GADWIDTH, 0, 0, 0, 0, GADHEIGHT, 0, 0};
  80. SHORT BLACKvecs[] =
  81. {1, GADHEIGHT, GADWIDTH, GADHEIGHT,
  82.  GADWIDTH, 1, GADWIDTH, GADHEIGHT, 1, GADHEIGHT};
  83. /*
  84.   Borders to achieve 3d lighting effect
  85.   I know this can be done with Gadtools.library, but I still haven't
  86.   got the RKM's
  87.   downside to this method: Font independency becomes a bit harder to
  88.   implement (when it will be done :).
  89. */
  90. struct Border wb =
  91. {-1, -1, WHITE, BLACK, JAM1, 5, WHITEvecs, NULL};
  92. struct Border bb =
  93. {-1, -1, BLACK, BLACK, JAM1, 5, BLACKvecs, &wb};
  94. struct IntuiText start_t =
  95. {BLACK, WHITE, JAM1, 1, 1, NULL, "Start", NULL};
  96. struct IntuiText stop_t =
  97. {BLACK, WHITE, JAM1, 6, 1, NULL, "Stop", NULL};
  98. struct IntuiText total_t =
  99. {BLACK, GREY, JAM2, 0, 0, NULL, NULL, NULL};
  100.  /* Gadgets */
  101. struct Gadget startg =
  102. {NULL, 6, WINY - 14, GADWIDTH - 1,
  103.  GADHEIGHT, GADGHCOMP, RELVERIFY, BOOLGADGET, (APTR) & bb, NULL, &start_t,
  104.  NULL, NULL, STARTGAD, 0};
  105. struct Gadget stopg =
  106. {(struct Gadget *) &startg, WINX - GADWIDTH - 6,
  107.  WINY - 14, GADWIDTH - 1, GADHEIGHT, GADGHCOMP, RELVERIFY, BOOLGADGET, (APTR)
  108.  & bb, NULL, (struct IntuiText *) &stop_t, NULL, NULL, STOPGAD, NULL};
  109.  
  110. /***********************************************************************
  111.   close everything and exit
  112. ***********************************************************************/
  113. void
  114. clean_exit (int status)
  115. {
  116.   FILE *logfp;        /* Log file pointer */
  117.  
  118.   if (LOGGING)
  119.     {
  120.       if (!(logfp = fopen (LOGNAME, "a+")))
  121.     {
  122.       puts ("could not open log file!\n");
  123.       goto error;
  124.     }
  125.       else
  126.     {
  127.       static long date = 0, store;
  128.  
  129.       date = time (&store);
  130.       if (seconds > 0)
  131.         fprintf (logfp, "%4ld mins = %ld unit(s) on %s", (seconds / 60) ? (seconds / 60) : 1, 1 + ((seconds / 60) / INTERVAL), ctime (&date));
  132.     }
  133.  
  134.       fclose (logfp);
  135.     }                /* end if(LOGGING) */
  136.  
  137. error:
  138. /*
  139.   Killing the timer device might be done in a more system friendly
  140.   way, but this code is courtesy of Mike Meyer, not me. 8-P
  141.   Main thing is we get "Total used: 0" on "mem -r" in Csh.
  142. */
  143.   AbortIO ((char *) &Time_Req.tr_node);
  144.   if (Time_Req.tr_node.io_Message.mn_ReplyPort)
  145.     CloseDevice (&Time_Req);
  146.   if (Timer_Port)
  147.     DeletePort (Timer_Port);
  148.   if (window)
  149.     CloseWindow (window);
  150.   if (IntuitionBase)
  151.     CloseLibrary (IntuitionBase);
  152.   exit (status);
  153. }
  154. /***********************************************************************
  155.   Parse command line arguments
  156. ***********************************************************************/
  157. void
  158. parse_options (int count, char *args[])
  159. {
  160.   register int i;
  161.   for (i = 1; i < count; i++)
  162.     {
  163.       if (*args[i] == '-')    /* check for option introducer */
  164.     {
  165.       args[i]++;
  166.       if (!(strcmp (args[i], "autostart")))
  167.         {
  168.           AUTOSTART = 1;
  169.           total_t.FrontPen = PURPLE;
  170.           continue;
  171.         }
  172.       if (!(strcmp (args[i], "firstscreen")))
  173.         {
  174.           ACTIVE_SCREEN = 1;
  175.           continue;
  176.         }
  177.  
  178.       if (!(strcmp (args[i], "interval")))
  179.         {
  180.           INTERVAL = atoi (args[i + 1]);
  181.           INTERVAL = (INTERVAL == 0) ? 12L : INTERVAL;
  182.           i++;
  183.           continue;
  184.         }
  185.  
  186.       if (!(strcmp (args[i], "log")))
  187.         {
  188.           LOGGING = 1;
  189.           continue;
  190.         }
  191.  
  192.       if (!(strcmp (args[i], "x")))
  193.         {
  194.           x = atoi (args[i + 1]);
  195.           i++;
  196.           continue;
  197.         }
  198.  
  199.       if (!(strcmp (args[i], "y")))
  200.         {
  201.           y = atoi (args[i + 1]);
  202.           i++;
  203.           continue;
  204.         }
  205.  
  206.       
  207.       exit (RETURN_WARN);
  208.     }            /* end if(option_introducer) */
  209.     }                /* end for */
  210.   return;
  211. }
  212. /***********************************************************************
  213.   Print current data
  214. **********************************************************************/
  215. void
  216. show_data (long time)        /* Passed: seconds */
  217. {
  218.   static char string[80];    /* Time string */
  219.   register char secs[3], mins[3], hours[3];    /* place to hold components */
  220.   register ULONG s, m, h;
  221.   /* Calculate current time */
  222.   s = time % 60;
  223.   m = (time / 60) % 60;
  224.   h = time / 3600;
  225.   /* convert to string  */
  226.   sprintf (secs, (s < 10) ? "0%1ld" : "%2ld", s);
  227.   sprintf (mins, (m < 10) ? "0%1ld" : "%2ld", m);
  228.   sprintf (hours, (h < 10) ? "0%1ld" : "%2ld", h);
  229.   sprintf (string, "%2ld/%2ld  %2s:%2s:%2s", INTERVAL,
  230.        1 + ((time / 60) / INTERVAL), hours, mins, secs);
  231.   total_t.IText = string;
  232.   PrintIText (window->RPort, &total_t, 6 + GADWIDTH + 12, 14);
  233.   return;
  234. }
  235. /***********************************************************************
  236.  Init timerequest structure
  237. ***********************************************************************/
  238. void
  239. start_timer ()
  240. {
  241.   if ((Timer_Port = CreatePort ("Timer Port", 0)) == NULL)
  242.     {
  243.       puts ("Can't create timer port\n");
  244.       clean_exit (50);
  245.     }
  246.  
  247.   if (OpenDevice (TIMERNAME, UNIT_VBLANK, (char *) &Time_Req, 0) != NULL)
  248.     {
  249.       puts ("Can't open timer device!");
  250.       clean_exit (20);
  251.     }
  252.  
  253.  
  254.   Time_Req.tr_node.io_Message.mn_ReplyPort = Timer_Port;
  255.   Time_Req.tr_node.io_Command = TR_ADDREQUEST;
  256.   Time_Req.tr_node.io_Flags = 0;
  257.   Time_Req.tr_node.io_Error = 0;
  258.   return;
  259. }
  260. /***********************************************************************
  261.   Set up a new timer request
  262. ***********************************************************************/
  263. void
  264. restart_timer ()
  265. {
  266.   Time_Req.tr_time.tv_secs = 1;
  267.   Time_Req.tr_time.tv_micro = 0;
  268.   SendIO ((char *) &Time_Req.tr_node);
  269.   return;
  270. }
  271. /***********************************************************************
  272.   main program
  273. ***********************************************************************/
  274. void
  275. main (int argc, char **argv)
  276. {
  277.   int class;
  278.   struct IntuiMessage *msg, *GetMsg (struct MsgPort *);
  279.   long RUNNING = 0;
  280.  
  281.   if (argc > 1)            /* did we get additional parameters? */
  282.     parse_options (argc, argv);
  283.   /* Open libs */
  284.   if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 0L)))
  285.     {
  286.       puts ("Can't open intuition.library!\n");
  287.       clean_exit (10);
  288.     }
  289.  
  290.   if (ACTIVE_SCREEN)
  291.     {
  292.       seconds = LockIBase (0);    /* Lock out all access to IntuitionBase */
  293.       nw.Screen = IntuitionBase->FirstScreen;
  294.       UnlockIBase (seconds);    /* and unlock again */
  295.       seconds = 0;        /* set seconds back to zero */
  296.       nw.Type = CUSTOMSCREEN;
  297.     }
  298.  
  299.   if (AUTOSTART)
  300.     RUNNING = 1;
  301.   /* init gadgets  */
  302.   nw.FirstGadget = &stopg;
  303.   nw.LeftEdge = x;
  304.   nw.TopEdge = y;
  305.  
  306.   start_timer ();
  307.  
  308.   if (!(window = (struct Window *) OpenWindow ((struct NewWindow *) &nw)))
  309.     {
  310.       puts ("Can't open window!\n");
  311.       clean_exit (20);
  312.     }
  313.  
  314.   for (;;)
  315.     {
  316.       long signals;
  317.       static struct Gadget *gad = NULL;
  318.  
  319.       if (RUNNING)
  320.     restart_timer ();
  321.  
  322.       signals = Wait (WINMASK | TMASK);
  323.  
  324.       if (signals & WINMASK)
  325.     {
  326.       while ((msg = GetMsg (window->UserPort)))
  327.         {
  328.           class = msg->Class;
  329.           gad = (struct Gadget *) (msg->IAddress);
  330.           ReplyMsg (msg);
  331.  
  332.           switch (class)
  333.         {
  334.         case CLOSEWINDOW:
  335.           clean_exit (0);
  336.           break;
  337.  
  338.         case GADGETUP:
  339.           if (gad->GadgetID == STARTGAD && RUNNING)
  340.             break;
  341.  
  342.           if (gad->GadgetID == STOPGAD && !RUNNING)
  343.             {
  344.               seconds = 0;
  345.               show_data (seconds);
  346.             }
  347.  
  348.           if (gad->GadgetID == STOPGAD && !RUNNING)
  349.             {
  350.               seconds = 0;
  351.               show_data (seconds);
  352.             }
  353.  
  354.           if (gad->GadgetID == STARTGAD)
  355.             {
  356.               RUNNING = 1;
  357.               total_t.FrontPen = PURPLE;
  358.             }
  359.           if (gad->GadgetID == STOPGAD)
  360.             {
  361.               RUNNING = 0;
  362.               total_t.FrontPen = BLACK;
  363.             }
  364.  
  365.         default:
  366.           break;
  367.         }        /* end switch */
  368.         }
  369.     }
  370.       else if (signals & TMASK)    /* We got a message from timer.device */
  371.     {
  372.       GetMsg (Timer_Port);
  373.       seconds++;
  374.       show_data (seconds);
  375.     }
  376.     }                /* end for(;;) */
  377. }                /* end main() */
  378.