home *** CD-ROM | disk | FTP | other *** search
- /* Title: tim.c
- *
- * Author: Tim Browse
- *
- * Purpose: A program to provide a desktop speaking clock.
- *
- * When started it sets up an icon on the icon bar. Clicking on the icon
- * results in the current time being spoken aloud.
- */
-
- #include "wimp.h"
- #include "wimpt.h"
- #include "win.h"
- #include "event.h"
- #include "baricon.h"
- #include "res.h"
- #include "resspr.h"
- #include "menu.h"
- #include "template.h"
- #include "dbox.h"
-
- #include "os.h"
- #include "swis.h"
-
- #include <stdlib.h>
- #include <string.h>
-
- /********************************* CONSTANTS ********************************/
-
- /* Menu items */
- #define Tim_menu_info 1
- #define Tim_menu_quit 2
-
- /* Info box field for the version string */
- #define Tim_info_field 4
-
- /******************************** GLOBAL DATA *******************************/
-
- /* Application version */
- static char *tim_Version_String = "1.01 (25 April 1992)";
-
- /* The top of the menu tree */
- static menu main_menu;
-
-
- /******************************** TIME STUFF ********************************/
-
-
- typedef union
- {
- char time_str[30];
- int reason_code;
- } TIME_BLK;
-
- static BOOL get_time(int *hours, int *minutes)
- {
- TIME_BLK blk;
- os_error *err;
-
- blk.reason_code = 0;
- err = os_swi2(XOS_Bit | OS_Word, 14, (int) &blk);
-
- if (err != (os_error *) 0)
- {
- wimpt_reporterror(err, wimp_EOK);
- return FALSE;
- }
- else
- {
- /* Extract time from string */
- /* Null terminate the hours & minutes parts */
- blk.time_str[18] = '\0';
- blk.time_str[21] = '\0';
-
- *hours = atoi(blk.time_str+16);
- *minutes = atoi(blk.time_str+19);
- return TRUE;
- }
- }
-
- char *str_create(char *src)
- {
- char *ptr;
-
- ptr = (char *) malloc(strlen(src)+1);
- if (ptr != (char *) 0)
- strcpy(ptr, src);
-
- return ptr;
- }
-
- static char *prefix, *mintext, *relative,
- *hourtext, *postfix, *timeofday;
-
- void get_module_names(int hours, int minutes)
- {
- int alter; /* Used to round to nearest 5 minute mark */
-
- /* Add o'clock to message if minutes are 58, 59, 0, 1, or 2 */
- if ((minutes >= 58) || (minutes <= 2))
- postfix = str_create("oclock");
- else
- postfix = (char *) 0;
-
- /* Refer to next hour if in second half of hour */
- if (minutes >= 33)
- hours = (hours + 1) % 24;
-
- /* Get time of day:
- 11.33pm to 12.32am - midnight
- 12.33am to 4.32am - at night
- 4.33am to 11.32am - morning
- 11.33am to 12.32pm - midday
- 12.33pm to 4.32pm - in the afternoon
- 4.33pm to 10.32pm - in the evening
- 10.33pm to 11.32pm - at night
- */
- if (hours == 23)
- timeofday = str_create("atnight");
- else if (hours == 0)
- timeofday = str_create("midnight");
- else if ((hours >= 1) && (hours <= 4))
- timeofday = str_create("atnight");
- else if ((hours >= 5) && (hours <= 11))
- timeofday = str_create("morning");
- else if (hours == 12)
- timeofday = str_create("midday");
- else if ((hours >= 13) && (hours <= 16))
- timeofday = str_create("afternoon");
- else
- timeofday = str_create("evening");
-
- /* Convert to 12 hour clock */
- if (hours >= 13)
- hours -= 12;
-
- /* Find the nearest 5 minute mark */
- mintext = (char *) 0;
- alter = 0;
-
- while (mintext == (char *) 0)
- {
- switch (minutes)
- {
- case 0: mintext = str_create("");
- relative = str_create("");
- break;
- case 5: mintext = str_create("five");
- relative = str_create("past");
- break;
- case 10: mintext = str_create("ten");
- relative = str_create("past");
- break;
- case 15: mintext = str_create("quarter");
- relative = str_create("past");
- break;
- case 20: mintext = str_create("20");
- relative = str_create("past");
- break;
- case 25: mintext = str_create("25");
- relative = str_create("past");
- break;
- case 30: mintext = str_create("half");
- relative = str_create("past");
- break;
- case 35: mintext = str_create("25");
- relative = str_create("to");
- break;
- case 40: mintext = str_create("20");
- relative = str_create("to");
- break;
- case 45: mintext = str_create("quarter");
- relative = str_create("to");
- break;
- case 50: mintext = str_create("ten");
- relative = str_create("to");
- break;
- case 55: mintext = str_create("five");
- relative = str_create("to");
- break;
- case 60: mintext = str_create("");
- relative = str_create("");
- break;
- }
- switch (alter)
- {
- case 0: minutes += 1; alter = 1;
- break;
- case 1: minutes += 1; alter = 2;
- break;
- case 2: minutes -= 3; alter = -1;
- break;
- case -1: minutes -= 1; alter = -2;
- break;
- }
- }
-
- if (mintext[0] == '\0')
- {
- free((void *) mintext);
- free((void *) relative);
- mintext = (char *) 0;
- relative = (char *) 0;
- }
-
- /* If nearest 5 minute mark was ahead then "nearly"
- if nearest 5 minute mark was back then "justgone"
- */
- if (alter == 1)
- prefix = (char *) 0;
- else if ((alter == 2) || (alter == -1))
- prefix = str_create("nearly");
- else
- prefix = str_create("justgone");
-
- /* Convert hour to text string */
- switch (hours)
- {
- case 0:
- case 12: hourtext = str_create("twelve");
- break;
- case 1: hourtext = str_create("one");
- break;
- case 2: hourtext = str_create("two");
- break;
- case 3: hourtext = str_create("three");
- break;
- case 4: hourtext = str_create("four");
- break;
- case 5: hourtext = str_create("five");
- break;
- case 6: hourtext = str_create("six");
- break;
- case 7: hourtext = str_create("seven");
- break;
- case 8: hourtext = str_create("eight");
- break;
- case 9: hourtext = str_create("nine");
- break;
- case 10: hourtext = str_create("ten");
- break;
- case 11: hourtext = str_create("eleven");
- break;
- }
- }
-
- void add_str(char *str, char *suffix)
- {
- if (suffix != (char *) 0)
- {
- strcat(str," ");
- strcat(str,suffix);
- }
- }
-
- void play_samples(void)
- {
- char str[200];
-
- strcpy(str, "WimpTask <Tim$Dir>.Play 16000 Its");
-
- add_str(str, prefix);
- add_str(str, mintext);
- add_str(str, relative);
- add_str(str, hourtext);
- add_str(str, postfix);
- add_str(str, timeofday);
-
- system(str);
- }
-
- /****************************** EVENT HANDLERS ******************************/
-
- /*--- Event handler called on a left click on the icon. ---*/
- static void tim_iconclick(wimp_i icon)
- {
- int hours, minutes;
-
- icon = icon; /* We don't need the handle: this stops compiler warning */
-
- /* Code to play samples... */
- if (get_time(&hours, &minutes))
- {
- get_module_names(hours, minutes);
- play_samples();
- }
-
- }
-
- /*--- Display the program info box - called from the menu processor. ---*/
- static void tim_info_about_program(void)
- {
- dbox d; /* Dialogue box handle */
-
- /* Create the dialogue box */
- if (d = dbox_new("ProgInfo"), d != NULL)
- {
- /* Fill in the version number */
- dbox_setfield(d, Tim_info_field, tim_Version_String);
-
- /* Show the dialogue box */
- dbox_show(d);
-
- /* Keep it on the screen as long as needed */
- dbox_fillin(d);
-
- /* Dispose of the dialogue box */
- dbox_dispose(&d);
- }
- }
-
- /*--- Event handler for the menu. ---*/
- static void main_menuproc(void *handle, char *hit)
- {
- handle = handle; /* We don't need handle: this stops compiler warning */
-
- /* Find which menu item was hit and take action as appropriate */
- switch (hit[0])
- {
- case Tim_menu_info:
- tim_info_about_program();
- break;
-
- case Tim_menu_quit:
- /* Exit from the program. The wimp gets rid of the window and icon */
- exit(0);
- }
- }
-
- /****************************** INITIALISATION ******************************/
-
- /*--- Initialise the program, returning TRUE if it was all OK. ---*/
- static BOOL tim_initialise(void)
- {
- /* RISC_OSlib initialisation */
- wimpt_init("Speaking Clock");/* Main Wimp initialisation */
- res_init("Tim"); /* Resources */
- resspr_init(); /* Application sprites */
- template_init(); /* Templates */
- dbox_init(); /* Dialogue boxes */
-
- /* Create the menu tree */
- if (main_menu = menu_new("Tim", ">Info,Quit"), main_menu == NULL)
- return FALSE; /* Menu create failed */
-
- /* Set up the icon on the icon bar, and declare its event handlers */
- baricon("!tim", (int)resspr_area(), tim_iconclick);
- if (!event_attachmenu(win_ICONBAR, main_menu, main_menuproc, 0))
- return FALSE; /* Unable to attach menu */
-
- /* All went ok */
- return TRUE;
- }
-
- /******************************* MAIN PROGRAM ********************************/
-
- /*--- Main entry point. ---*/
- int main()
- {
- if (tim_initialise())
- {
- /* The main event loop */
- while (TRUE)
- event_process();
- }
-
- return 0;
- }
-