home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / Timing / VLTimer.lha / VLTimer / Source / VLTimer.c < prev   
Encoding:
C/C++ Source or Header  |  1993-12-01  |  8.8 KB  |  316 lines

  1. /*----------------------------------------------------*
  2.  | File: VLTIMER.c - Small clock/timer for the Amiga. |
  3.  | Version: 2.00 (no version string to save space :-) |
  4.  | Last modified: MLO 30 Nov 1993 20:21:09            |
  5.  +----------------------------------------------------+-----------*
  6.  | This code is free software, that you can distribute and modify |
  7.  | under the terms of the GNU General Public License (included in |
  8.  | the file LICENSE.TXT of the distribution) -- see also the file |
  9.  | DISCLAIMER.TXT, about the (lack of) warranties and the author. |
  10.  *----------------------------------------------------------------*/
  11.  
  12. /**
  13.  | VLTimer opens a small window with a digital clock/timer in the
  14.  | VLT custom screen (or in the default Public Screen).  The timer
  15.  | can be reset selecting the window and hitting the '0' key; the
  16.  | 'TAB' key switches between clock and timer.
  17. **/
  18.  
  19. /**
  20.  | #include's
  21. **/
  22.  
  23. #include <stdio.h>                      /* Standard library */
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <time.h>
  27. #include <exec/types.h>                 /* Amiga stuff */
  28. #include <exec/memory.h>
  29. #include <workbench/startup.h>
  30. #include <proto/exec.h>
  31. #include <proto/dos.h>
  32. #include <proto/icon.h>
  33. #include <proto/intuition.h>
  34.  
  35. /**
  36.  | Global variables to detach from CLI
  37. **/
  38.  
  39. long  __stack        = 4000;
  40. char *__procname     = "VLTimer";
  41. long  __priority     = 0;
  42. long  __BackGroundIO = 0;
  43.  
  44. /**
  45.  | Global variables to be addressed by Cleanup()
  46. **/
  47.  
  48. struct IntuitionBase *IntuitionBase = 0;
  49. struct Screen        *pScreen       = 0;
  50. struct Window        *Window        = 0;
  51. struct IntuiMessage  *pIM           = 0;
  52. struct Library       *IconBase      = 0;
  53. struct RDArgs        *pRDArgs       = 0;
  54.  
  55. /**
  56.  | #define's:
  57.  | - miscellaneous parameters;
  58.  | - flags and IDCMP's for the VLTimer window;
  59. **/
  60.  
  61. #define REVISION        37              /* Library revision (AmigaDOS 2.04) */
  62. #define W_WIDTH         58              /* Window width (text excluded)     */
  63. #define NO_TIME         ((ULONG) ~0)    /* Flag 'no time on screen'         */
  64. #define DELTA           10              /* Sleep time (DELTA/50 seconds)    */
  65. #define ZERO            '0'             /* ASCII zero                       */
  66. #define TAB             '\t'            /* ASCII TAB                        */
  67.  
  68. #define W_IDCMP IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY
  69. #define W_FLAG1 WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET
  70. #define W_FLAG2 WFLG_SIMPLE_REFRESH
  71. #define W_FLAGS (W_FLAG1 | W_FLAG2)
  72.  
  73. /**
  74.  | CLI command line template, and constants for ReadArgs
  75. **/
  76.  
  77. #define TEMPLATE "PUBSCREEN/K,CLOCK/S"
  78.  
  79. enum eOptions {
  80.   OPTION_SCREEN = 0,
  81.   OPTION_CLOCK,
  82.   N_OPTIONS                              /* This must be last */
  83. };
  84.  
  85. /**
  86.  | ANSI procedures prototypes
  87. **/
  88.  
  89. void Cleanup(int ReturnCode);
  90. void NtoA(char *buf, int h, int m, int s);
  91.  
  92. /**
  93.  | The main program.
  94.  | If something goes wrong, VLTimer exits silently setting the
  95.  | return code for the CLI to 20 (EXIT_FAILURE).
  96. **/
  97.  
  98. int main(
  99.   int argc,
  100.   char *argv[]
  101. ){
  102.   unsigned int Start[2];                /* When the timer was started */
  103.   int dispClock;                        /* Clock/Timer flag           */
  104.  
  105.   ULONG Last             = NO_TIME;     /* Last printed time          */
  106.   char slate[]           = "hh:mm:ss";  /* Print buffer               */
  107.   char *pScreenName      = 0;           /* Public Screen name         */
  108.  
  109.   struct NewWindow NWind = {            /* VLTimer window parameters  */
  110.     0, 0, W_WIDTH, 0,
  111.     0, 1,
  112.     W_IDCMP,
  113.     W_FLAGS,
  114.     0, 0,
  115.     (UBYTE *) "",
  116.     0, 0,
  117.     0, 0, 0, 0,
  118.     PUBLICSCREEN
  119.   };
  120.  
  121. /**
  122.  | Opens the intuition library
  123. **/
  124.  
  125.   if ((IntuitionBase = (struct IntuitionBase *)
  126.         OpenLibrary("intuition.library", REVISION)) == 0) {
  127.     exit(EXIT_FAILURE);
  128.   }
  129.  
  130. /**
  131.  | Allocates an IntuiMessage buffer
  132. **/
  133.  
  134.   if ((pIM = AllocMem(sizeof(struct IntuiMessage), MEMF_ANY)) == 0) {
  135.     Cleanup(EXIT_FAILURE);
  136.   }
  137.  
  138. /**
  139.  | If called from the CLI, parses the command line; if started from
  140.  | the workbench, gets the tool types.  In both cases, looks for:
  141.  | - 'PUBSCREEN=<name>', to define the screen where the VLTimer
  142.  |   window will be opened, if different from the default public
  143.  |   screen);
  144.  | - 'CLOCK', to start in the clock mode (the default is the timer
  145.  |   mode).
  146.  | If an error is detected parsing the tool types or the command
  147.  | line, the default values are used for the public screen and the
  148.  | starting mode.
  149. **/
  150.  
  151.   if (argc) {
  152.     long options[(int) N_OPTIONS];
  153.  
  154.     memset(options, 0, sizeof(options));
  155.  
  156.     if ((pRDArgs = ReadArgs(TEMPLATE, options, 0)) != 0) {
  157.       pScreenName = (char *) options[(int) OPTION_SCREEN];
  158.       dispClock   = options[(int) OPTION_CLOCK];
  159.     }
  160.   } else {
  161.     struct WBArg      *pWBA;
  162.     struct DiskObject *pDO;
  163.  
  164.     if ((IconBase = OpenLibrary("icon.library", REVISION)) == 0) {
  165.       Cleanup(EXIT_FAILURE);
  166.     }
  167.  
  168.     pWBA=((struct WBStartup *) argv)->sm_ArgList;
  169.  
  170.     if (pWBA->wa_Name != 0  && (pDO = GetDiskObject(pWBA->wa_Name)) != 0) {
  171.       pScreenName = (char *)
  172.           FindToolType((char **) pDO->do_ToolTypes, "PUBSCREEN");
  173.       dispClock =
  174.           (FindToolType((char **) pDO->do_ToolTypes, "CLOCK") != 0);
  175.       FreeDiskObject(pDO);
  176.     }
  177.   }
  178.  
  179. /**
  180.  | Locks the target screen, and opens the window (after having
  181.  | adjusted the NewWindow parameters, considering the screen font,
  182.  | to open the window in its lower right corner).  Yes, I know, YOU
  183.  | don't like that position---but I do...
  184. **/
  185.  
  186.   if ((pScreen = LockPubScreen(pScreenName)) == 0) {
  187.     Cleanup(EXIT_FAILURE);
  188.   }
  189.  
  190.   NWind.Screen = pScreen;
  191.   NWind.LeftEdge = pScreen->Width -
  192.     (NWind.Width += pScreen->RastPort.TxWidth * 8);
  193.   NWind.TopEdge = pScreen->Height -
  194.     (NWind.Height = pScreen->WBorTop + pScreen->RastPort.TxHeight + 1);
  195.  
  196.   if ((Window = OpenWindow(&NWind)) == 0) {
  197.     Cleanup(EXIT_FAILURE);
  198.   }
  199.  
  200. /**
  201.  | Starts the timer; then begins an infinite loop (exit closing the
  202.  | window).  Checks for Intuition event (window closed, or key hit),
  203.  | and performs the appropriate action: resets the timer if the '0'
  204.  | key has been hit, or switches between timer and clock if the 'TAB'
  205.  | key has been hit).  Then asks for the current time and, if the
  206.  | display should has changed, updates it; then suspends itself for
  207.  | a short time.
  208. **/
  209.  
  210.   for ((void) timer(Start); ; Delay(DELTA)) {
  211.     struct IntuiMessage *IMsg;          /* Intuition message pointer   */
  212.     int hour, mins, secs;               /* Elapsed time                */
  213.     int oldSec;                         /* Last time clock was updated */
  214.  
  215.     while ((IMsg = (struct IntuiMessage *) GetMsg(Window->UserPort)) != 0) {
  216.       memcpy(pIM, IMsg, sizeof(struct IntuiMessage));
  217.       ReplyMsg((struct Message *) IMsg);
  218.  
  219.       switch (pIM->Class) {
  220.         case IDCMP_CLOSEWINDOW:
  221.           Cleanup(EXIT_SUCCESS);
  222.           break;
  223.  
  224.         case IDCMP_VANILLAKEY:
  225.           switch (pIM->Code) {
  226.             case TAB:
  227.               if ((dispClock = !dispClock) != 0) {
  228.                 oldSec = -1;
  229.               }
  230.               break;
  231.  
  232.             case ZERO:
  233.               (void) timer(Start);
  234.               break;
  235.  
  236.           }
  237.           break;
  238.  
  239.       }
  240.     }
  241.  
  242.     if (dispClock) {
  243.       struct DateStamp ds;
  244.  
  245.       (void) DateStamp(&ds);
  246.       secs = ds.ds_Tick / TICKS_PER_SECOND;
  247.       if (secs != oldSec) {
  248.         hour   = ds.ds_Minute / 60;
  249.         mins   = ds.ds_Minute % 60;
  250.         oldSec = secs;
  251.         NtoA(slate, hour, mins, secs);
  252.         SetWindowTitles(Window, slate, (UBYTE *) -1);
  253.       }
  254.     } else {
  255.       unsigned int SysSecs[2];
  256.  
  257.       (void) timer(SysSecs);
  258.       *SysSecs -= *Start;
  259.       if (SysSecs[1] < Start[1]) (*SysSecs)--;
  260.       if (*SysSecs != Last) {
  261.         secs = (Last = *SysSecs) % 60;
  262.         mins = (Last / 60) % 60;
  263.         hour = (Last / 3600) % 24;
  264.         NtoA(slate, hour, mins, secs);
  265.         SetWindowTitles(Window, slate, (UBYTE *) -1);
  266.       }
  267.     }
  268.   }
  269. }
  270.  
  271. void Cleanup(
  272.   int ReturnCode                        /* Exit code */
  273. ){
  274.  
  275. /**
  276.  | Releases all system resources, then exits.
  277. **/
  278.  
  279.   if (Window != 0) {
  280.     void *IMsg;
  281.  
  282.     while ((IMsg = GetMsg(Window->UserPort)) != 0) {
  283.       ReplyMsg(IMsg);
  284.     }
  285.     CloseWindow(Window);
  286.   }
  287.  
  288.   if (pScreen       != 0) UnlockPubScreen(0, pScreen);
  289.   if (pRDArgs       != 0) FreeArgs(pRDArgs);
  290.   if (pIM           != 0) FreeMem(pIM, sizeof(struct IntuiMessage));
  291.   if (IconBase      != 0) CloseLibrary(IconBase);
  292.   if (IntuitionBase != 0) CloseLibrary((struct Library *) IntuitionBase);
  293.  
  294.   exit(ReturnCode);
  295. }
  296.  
  297. void NtoA(
  298.   char *buf,                            /* Output buffer */
  299.   int h,                                /* Hours */
  300.   int m,                                /* Minutes */
  301.   int s                                 /* Seconds */
  302. ){
  303. /**
  304.  | Instead of sprintf(... "%02d:%02d:%02d" ...); to save memory.
  305. **/
  306.  
  307.   *buf++ = ZERO + ((h / 10) % 10);
  308.   *buf++ = ZERO + (h % 10);
  309.    buf++;
  310.   *buf++ = ZERO + (m / 10);
  311.   *buf++ = ZERO + (m % 10);
  312.    buf++;
  313.   *buf++ = ZERO + (s / 10);
  314.   *buf   = ZERO + (s % 10);
  315. }
  316.