home *** CD-ROM | disk | FTP | other *** search
/ Really Useful CD 1 / ReallyUsefulCD1.iso / extras / utilities / _tim / c / tim
Encoding:
Text File  |  1992-04-25  |  9.2 KB  |  369 lines

  1. /* Title:   tim.c
  2.  *
  3.  * Author:  Tim Browse
  4.  *
  5.  * Purpose: A program to provide a desktop speaking clock.
  6.  *
  7.  * When started it sets up an icon on the icon bar. Clicking on the icon
  8.  * results in the current time being spoken aloud.
  9.  */
  10.  
  11. #include "wimp.h"
  12. #include "wimpt.h"
  13. #include "win.h"
  14. #include "event.h"
  15. #include "baricon.h"
  16. #include "res.h"
  17. #include "resspr.h"
  18. #include "menu.h"
  19. #include "template.h"
  20. #include "dbox.h"
  21.  
  22. #include "os.h"
  23. #include "swis.h"
  24.  
  25. #include <stdlib.h>
  26. #include <string.h>
  27.  
  28. /********************************* CONSTANTS ********************************/
  29.  
  30. /* Menu items */
  31. #define Tim_menu_info     1
  32. #define Tim_menu_quit     2
  33.  
  34. /* Info box field for the version string */
  35. #define Tim_info_field    4
  36.  
  37. /******************************** GLOBAL DATA *******************************/
  38.  
  39. /* Application version */
  40. static char *tim_Version_String = "1.01 (25 April 1992)";
  41.  
  42. /* The top of the menu tree */
  43. static menu main_menu;
  44.  
  45.  
  46. /******************************** TIME STUFF ********************************/
  47.  
  48.  
  49. typedef union
  50. {
  51.   char time_str[30];
  52.   int reason_code;
  53. } TIME_BLK;
  54.  
  55. static BOOL get_time(int *hours, int *minutes)
  56. {
  57.   TIME_BLK blk;
  58.   os_error *err;
  59.  
  60.   blk.reason_code = 0;
  61.   err = os_swi2(XOS_Bit | OS_Word, 14, (int) &blk);
  62.  
  63.   if (err != (os_error *) 0)
  64.   {
  65.     wimpt_reporterror(err, wimp_EOK);
  66.     return FALSE;
  67.   }              
  68.   else
  69.   {
  70.     /* Extract time from string */
  71.     /* Null terminate the hours & minutes parts */
  72.     blk.time_str[18] = '\0';
  73.     blk.time_str[21] = '\0';                          
  74.  
  75.     *hours   = atoi(blk.time_str+16);
  76.     *minutes = atoi(blk.time_str+19);
  77.     return TRUE;
  78.   }
  79. }      
  80.                                  
  81. char *str_create(char *src)
  82. {                        
  83.   char *ptr;
  84.  
  85.   ptr = (char *) malloc(strlen(src)+1);
  86.   if (ptr != (char *) 0)
  87.     strcpy(ptr, src);
  88.  
  89.   return ptr;
  90. }
  91.  
  92. static char *prefix,   *mintext, *relative, 
  93.             *hourtext, *postfix, *timeofday;
  94.  
  95. void get_module_names(int hours, int minutes)
  96. {           
  97.   int alter; /* Used to round to nearest 5 minute mark */
  98.  
  99.   /* Add o'clock to message if minutes are 58, 59, 0, 1, or 2 */
  100.   if ((minutes >= 58) || (minutes <= 2))
  101.     postfix = str_create("oclock");
  102.   else
  103.     postfix = (char *) 0;
  104.  
  105.   /* Refer to next hour if in second half of hour */
  106.   if (minutes >= 33)
  107.     hours = (hours + 1) % 24;
  108.  
  109.   /* Get time of day:
  110.      11.33pm to 12.32am - midnight
  111.      12.33am to  4.32am - at night
  112.       4.33am to 11.32am - morning
  113.      11.33am to 12.32pm - midday
  114.      12.33pm to  4.32pm - in the afternoon
  115.       4.33pm to 10.32pm - in the evening
  116.      10.33pm to 11.32pm - at night
  117.   */
  118.   if (hours == 23)
  119.     timeofday = str_create("atnight");
  120.   else if (hours == 0)
  121.     timeofday = str_create("midnight");
  122.   else if ((hours >= 1) && (hours <= 4))
  123.     timeofday = str_create("atnight");
  124.   else if ((hours >= 5) && (hours <= 11))
  125.     timeofday = str_create("morning");
  126.   else if (hours == 12)
  127.     timeofday = str_create("midday");
  128.   else if ((hours >= 13) && (hours <= 16))
  129.     timeofday = str_create("afternoon");
  130.   else
  131.     timeofday = str_create("evening");
  132.  
  133.   /* Convert to 12 hour clock */
  134.   if (hours >= 13)
  135.     hours -= 12;
  136.  
  137.   /* Find the nearest 5 minute mark */
  138.   mintext = (char *) 0;
  139.   alter = 0;
  140.  
  141.   while (mintext == (char *) 0)
  142.   {                     
  143.     switch (minutes)
  144.     {
  145.       case  0: mintext  = str_create("");
  146.                relative = str_create("");
  147.                break;
  148.       case  5: mintext  = str_create("five");
  149.                relative = str_create("past");
  150.                break;
  151.       case 10: mintext  = str_create("ten");
  152.                relative = str_create("past");
  153.                break;
  154.       case 15: mintext  = str_create("quarter");
  155.                relative = str_create("past");
  156.                break;
  157.       case 20: mintext  = str_create("20");
  158.                relative = str_create("past");
  159.                break;
  160.       case 25: mintext  = str_create("25");
  161.                relative = str_create("past");
  162.                break;
  163.       case 30: mintext  = str_create("half");
  164.                relative = str_create("past");
  165.                break;
  166.       case 35: mintext  = str_create("25");
  167.                relative = str_create("to");
  168.                break;
  169.       case 40: mintext  = str_create("20");
  170.                relative = str_create("to");
  171.                break;
  172.       case 45: mintext  = str_create("quarter");
  173.                relative = str_create("to");
  174.                break;
  175.       case 50: mintext  = str_create("ten");
  176.                relative = str_create("to");
  177.                break;
  178.       case 55: mintext  = str_create("five");
  179.                relative = str_create("to");
  180.                break;
  181.       case 60: mintext  = str_create("");
  182.                relative = str_create("");
  183.                break;                  
  184.     }
  185.     switch (alter)
  186.     {
  187.       case  0: minutes += 1;   alter =  1;
  188.                break;
  189.       case  1: minutes += 1;   alter =  2;
  190.                break;
  191.       case  2: minutes -= 3;   alter = -1;
  192.                break;
  193.       case -1: minutes -= 1;   alter = -2;
  194.                break;
  195.     }
  196.   }
  197.  
  198.   if (mintext[0] == '\0')
  199.   {
  200.     free((void *) mintext);
  201.     free((void *) relative);
  202.     mintext  = (char *) 0;
  203.     relative = (char *) 0;
  204.   }
  205.  
  206.   /* If nearest 5 minute mark was ahead then "nearly"
  207.      if nearest 5 minute mark was back  then "justgone"
  208.   */
  209.   if (alter == 1)
  210.     prefix = (char *) 0;
  211.   else if ((alter == 2) || (alter == -1))
  212.     prefix = str_create("nearly");
  213.   else
  214.     prefix = str_create("justgone");
  215.  
  216.   /* Convert hour to text string */
  217.   switch (hours)
  218.   {
  219.     case  0:
  220.     case 12: hourtext = str_create("twelve");
  221.              break;
  222.     case  1: hourtext = str_create("one");
  223.              break;
  224.     case  2: hourtext = str_create("two");
  225.              break;
  226.     case  3: hourtext = str_create("three");
  227.              break;
  228.     case  4: hourtext = str_create("four");
  229.              break;
  230.     case  5: hourtext = str_create("five");
  231.              break;
  232.     case  6: hourtext = str_create("six");
  233.              break;
  234.     case  7: hourtext = str_create("seven");
  235.              break;
  236.     case  8: hourtext = str_create("eight");
  237.              break;
  238.     case  9: hourtext = str_create("nine");
  239.              break;
  240.     case 10: hourtext = str_create("ten");
  241.              break;
  242.     case 11: hourtext = str_create("eleven");
  243.              break;
  244.   }
  245. }                                
  246.              
  247. void add_str(char *str, char *suffix)
  248. {
  249.   if (suffix != (char *) 0)
  250.   {
  251.     strcat(str," ");
  252.     strcat(str,suffix);
  253.   }
  254. }
  255.  
  256. void play_samples(void)
  257. {
  258.   char str[200];
  259.  
  260.   strcpy(str, "WimpTask <Tim$Dir>.Play 16000 Its");
  261.  
  262.   add_str(str, prefix);
  263.   add_str(str, mintext);
  264.   add_str(str, relative);
  265.   add_str(str, hourtext);
  266.   add_str(str, postfix);
  267.   add_str(str, timeofday);
  268.  
  269.   system(str);
  270. }
  271.  
  272. /****************************** EVENT HANDLERS ******************************/
  273.  
  274. /*--- Event handler called on a left click on the icon. ---*/
  275. static void tim_iconclick(wimp_i icon)
  276.   int hours, minutes;
  277.  
  278.   icon = icon; /* We don't need the handle: this stops compiler warning */
  279.  
  280.   /* Code to play samples... */
  281.   if (get_time(&hours, &minutes))
  282.   {
  283.     get_module_names(hours, minutes);
  284.     play_samples();
  285.   }
  286.  
  287. }
  288.  
  289. /*--- Display the program info box - called from the menu processor. ---*/
  290. static void tim_info_about_program(void)
  291. {
  292.   dbox  d;  /* Dialogue box handle */
  293.  
  294.   /* Create the dialogue box */
  295.   if (d = dbox_new("ProgInfo"), d != NULL)
  296.   {
  297.     /* Fill in the version number */
  298.     dbox_setfield(d, Tim_info_field, tim_Version_String);
  299.  
  300.     /* Show the dialogue box */
  301.     dbox_show(d);
  302.  
  303.     /* Keep it on the screen as long as needed */
  304.     dbox_fillin(d);
  305.  
  306.     /* Dispose of the dialogue box */
  307.     dbox_dispose(&d);
  308.   }
  309. }
  310.  
  311. /*--- Event handler for the menu. ---*/
  312. static void main_menuproc(void *handle, char *hit)
  313. {
  314.   handle = handle; /* We don't need handle: this stops compiler warning */
  315.  
  316.   /* Find which menu item was hit and take action as appropriate */
  317.   switch (hit[0])
  318.   {
  319.     case Tim_menu_info:
  320.       tim_info_about_program();
  321.       break;
  322.  
  323.     case Tim_menu_quit:
  324.       /* Exit from the program. The wimp gets rid of the window and icon */
  325.       exit(0);
  326.   }
  327. }
  328.  
  329. /****************************** INITIALISATION ******************************/
  330.  
  331. /*--- Initialise the program, returning TRUE if it was all OK. ---*/
  332. static BOOL tim_initialise(void)
  333. {
  334.   /* RISC_OSlib initialisation */
  335.   wimpt_init("Speaking Clock");/* Main Wimp initialisation */
  336.   res_init("Tim");                 /* Resources */
  337.   resspr_init();                   /* Application sprites */
  338.   template_init();                 /* Templates */
  339.   dbox_init();                     /* Dialogue boxes */
  340.  
  341.   /* Create the menu tree */
  342.   if (main_menu = menu_new("Tim", ">Info,Quit"), main_menu == NULL)
  343.     return FALSE; /* Menu create failed */
  344.  
  345.   /* Set up the icon on the icon bar, and declare its event handlers */
  346.   baricon("!tim", (int)resspr_area(), tim_iconclick);
  347.   if (!event_attachmenu(win_ICONBAR, main_menu, main_menuproc, 0))
  348.     return FALSE; /* Unable to attach menu */
  349.  
  350.   /* All went ok */
  351.   return TRUE;
  352. }
  353.  
  354. /******************************* MAIN PROGRAM ********************************/
  355.  
  356. /*--- Main entry point. ---*/
  357. int main()
  358. {
  359.   if (tim_initialise())
  360.   {
  361.     /* The main event loop */
  362.     while (TRUE)
  363.       event_process();
  364.   }
  365.  
  366.   return 0;
  367. }
  368.