home *** CD-ROM | disk | FTP | other *** search
- /*
- * SpeakTime_Cx.c - Commodity version 1.2 of SpeakTime.c
- *
- * Copyright (c) 1994 Gary Walker.
- *
- * This program sends a string of phonetic text to the narrator
- * device to tell the local system time.
- *
- * Requires Kickstart V37 or greater.
- */
-
- #include <exec/types.h>
- #include <exec/exec.h>
- #include <exec/libraries.h>
- #include <dos/dos.h>
- #include <devices/narrator.h>
- #include <libraries/commodities.h>
- #include "clib/translator_protos.h"
- #include <clib/exec_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/alib_stdio_protos.h>
- #include <clib/commodities_protos.h>
- #include <string.h>
- #include "stdlib.h"
- #include <time.h>
- #include "SpeakTime_Cx_protos.h"
-
- #ifdef LATTICE
- int CXBRK(void) { return(0); } /* Disable SAS CTRL/C handling */
- int chkabort(void) { return(0); } /* really */
- #endif
-
- extern struct Library *SysBase; /* Used to check the OS version number */
-
- #define EVT_HOTKEY 1L
- #define BUFLEN 500
- UBYTE PhonBuffer[BUFLEN];
- STRPTR hourmin;
- char sentence[100];
- char numbers[7];
-
- void main(int, char **);
- void ProcessMsg(void);
-
- struct Library *CxBase, *IconBase, *TranslatorBase;
- struct MsgPort *broker_mp;
- CxObj *broker, *filter, *sender, *translate;
-
- struct NewBroker newbroker = {
- NB_VERSION,
- "SpeakTime HotKey", /* string to identify this broker */
- "A Simple HotKey",
- "A simple hot key commodity",
- NBU_UNIQUE | NBU_NOTIFY, /* Don't want any new commodities starting with this name. */
- 0, 0, 0, 0 /* If someone tries it, let me know */
- };
-
- ULONG cxsigflag;
-
- void main(int argc, char **argv)
- {
- UBYTE *hotkey, **ttypes;
- CxMsg *msg;
-
- /* Check the version number of the operating system */
- if(SysBase->lib_Version>=36)
- {
- if (CxBase = OpenLibrary("commodities.library", 37L))
- {
- /* open the icon.library for the support library */
- /* functions, ArgArrayInit() and ArgArrayDone() */
- if (IconBase = OpenLibrary("icon.library", 36L))
- {
- if (broker_mp = CreateMsgPort())
- {
- newbroker.nb_Port = broker_mp;
- cxsigflag = 1L << broker_mp->mp_SigBit;
-
- /* ArgArrayInit() is a support library function (from the 2.0 version
- * of amiga.lib) that makes it easy to read arguments from either a
- * CLI or from Workbench's ToolTypes. Because it uses icon.library,
- * the library has to be open before calling this function.
- * ArgArrayDone() cleans up after this function.
- */
- ttypes = ArgArrayInit(argc, argv);
-
- /* ArgInt() (also from amiga.lib) searches through the array set up
- * by ArgArrayInit() for a specific ToolType. If it finds one, it
- * returns the numeric value of the number that followed the
- * ToolType (i.e., CX_PRIORITY=7). If it doesn't find the ToolType,
- * it returns the default value (the third argument)
- */
- newbroker.nb_Pri = (BYTE)ArgInt(ttypes, "CX_PRIORITY", 0);
-
- /* ArgString() works just like ArgInt(), except it returns a pointer to a string
- * rather than an integer. In the example below, if there is no ToolType
- * "HOTKEY", the function returns a pointer to "rawkey control esc".
- */
- hotkey = ArgString(ttypes, "HOTKEY", "rawkey alt z");
-
- if (broker = CxBroker(&newbroker, NULL))
- {
- /* CxFilter() is a macro that creates a filter CxObject. This filter
- * passes input events that match the string pointed to by hotkey.
- */
- if (filter = CxFilter(hotkey))
- {
- /* Add a CxObject to another's personal list */
- AttachCxObj(broker, filter);
-
- /* CxSender() creates a sender CxObject. Every time a sender gets
- * a CxMessage, it sends a new CxMessage to the port pointed to in
- * the first argument. CxSender()'s second argument will be the ID
- * of any CxMessages the sender sends to the port. The data pointer
- * associated with the CxMessage will point to a *COPY* of the
- * InputEvent structure associated with the orginal CxMessage.
- */
- if (sender = CxSender(broker_mp, EVT_HOTKEY))
- {
- AttachCxObj(filter, sender);
-
- /* CxTranslate() creates a translate CxObject. When a translate
- * CxObject gets a CxMessage, it deletes the original CxMessage
- * and adds a new input event to the input.device's input stream
- * after the Commodities input handler. CxTranslate's argument
- * points to an InputEvent structure from which to create the new
- * input event. In this example, the pointer is NULL, meaning no
- * new event should be introduced, which causes any event that
- * reaches this object to disappear from the input stream.
- */
- if (translate = (CxTranslate(NULL)))
- {
- AttachCxObj(filter, translate);
-
- /* CxObjError() is a commodities.library function that returns
- * the internal accumulated error code of a CxObject.
- */
- if (! CxObjError(filter))
- {
- ActivateCxObj(broker, 1L);
- ProcessMsg();
- }
- }
- }
- }
-
- }
-
- /* DeleteCxObjAll() is a commodities.library function that not only
- * deletes the CxObject pointed to in its argument, but it deletes
- * all of the CxObjects that are attached to it.
- */
- DeleteCxObjAll(broker);
-
- /* Empty the port of all CxMsgs */
- while(msg = (CxMsg *)GetMsg(broker_mp))
- ReplyMsg((struct Message *)msg);
- }
- DeletePort(broker_mp);
- }
- /* this amiga.lib function cleans up after ArgArrayInit() */
- ArgArrayDone();
- CloseLibrary(IconBase);
- }
- CloseLibrary(CxBase);
- }
- else
- printf("Error: Release 2 (V36) or a later version of the OS required.\n");
- }
-
- void Sayit()
- {
- struct MsgPort *VoiceMP;
- struct narrator_rb *VoiceIO;
- BYTE audio_chan[4] = {3, 5, 10, 12};
-
- ThisTime();
- Phoneme();
-
- /* Create the message port */
- if (VoiceMP=CreateMsgPort())
- {
- /* Create the IORequest */
- if (VoiceIO = CreateIORequest(VoiceMP,sizeof(struct narrator_rb)))
- {
- /* Set the NEWIORB bit in the flags field to use the new fields */
- VoiceIO->flags = NDF_NEWIORB;
-
- /* Open the narrator device */
- if (OpenDevice("narrator.device",0,(struct IORequest *)VoiceIO,0L))
-
- /* Inform user that it could not be opened */
- printf("Error: narrator.device did not open\n");
-
- else
- {
- /* Speak the string using the default parameters */
- VoiceIO->ch_masks = &audio_chan[0];
- VoiceIO->nm_masks = sizeof(audio_chan);
- VoiceIO->message.io_Command = CMD_WRITE;
- VoiceIO->message.io_Data = PhonBuffer;
- VoiceIO->message.io_Length = strlen(PhonBuffer);
- DoIO((struct IORequest *)VoiceIO);
-
-
- /* Close the narrator device */
- CloseDevice((struct IORequest *)VoiceIO);
- }
- /* Delete the IORequest */
- DeleteIORequest(VoiceIO);
- }
- else
- /* Inform user that the IORequest could be created */
- printf("Error: Could not create IORequest\n");
-
- /* Delete the message port */
- DeleteMsgPort(VoiceMP);
- }
- else
- /* Inform user that the message port could not be created */
- printf("Error: Could not create message port\n");
- }
-
- void ProcessMsg(void)
- {
- extern struct MsgPort *broker_mp;
- extern CxObj *broker;
- extern ULONG cxsigflag;
- CxMsg *msg;
- ULONG sigrcvd, msgid, msgtype;
- LONG returnvalue = 1L;
-
- while(returnvalue)
- {
- sigrcvd = Wait(cxsigflag);
-
- while(msg = (CxMsg *)GetMsg(broker_mp))
- {
- msgid = CxMsgID(msg);
- msgtype = CxMsgType(msg);
- ReplyMsg((struct Message *)msg);
-
- switch(msgtype)
- {
- case CXM_IEVENT:
- switch(msgid)
- {
- case EVT_HOTKEY: /* We got the message from the sender CxObject */
- Sayit();
- break;
- default:
- break;
- }
- break;
- case CXM_COMMAND:
- switch(msgid)
- {
- case CXCMD_UNIQUE:
- /* Commodities Exchange can be told not only to refuse to launch a
- * commodity with a name already in use but also can notify the
- * already running commodity that it happened. It does this by
- * sending a CXM_COMMAND with the ID set to CXMCMD_UNIQUE. If the
- * user tries to run a windowless commodity that is already running,
- * the user wants the commodity to shut down. */
- returnvalue = 0L;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
- }
- }
-
- Phoneme()
- {
- LONG EnglLen;
- LONG rtnCode;
-
- TranslatorBase = OpenLibrary("translator.library",37);
- if (TranslatorBase == NULL)
- {
- printf("No Translator Library available.\n");
- exit(0);
- }
- Makeword();
- EnglLen = strlen(sentence);
- rtnCode = Translate(sentence, EnglLen, (STRPTR)&PhonBuffer[0], BUFLEN);
-
- CloseLibrary(TranslatorBase);
- return(rtnCode);
- }
- STRPTR ThisTime()
- {
- struct tm *p;
- long t;
-
- time(&t);
- p = localtime(&t);
- hourmin = asctime(p);
- return(hourmin);
- }
- void Makeword()
- {
- int i,m,n,hourflag,ampm, pmdigits;
-
- for(i=0;i<=6;++i)
- { numbers[i] = hourmin[i+11];
- }
- numbers[6] = NULL;
- strcpy(sentence, "Local time is ");
- m = numbers[0]-48;
- n = numbers[1]-48;
- hourflag = 1;
- ampm = 0;
- pmdigits = (m*10)+n;
- if (pmdigits>11)
- { ampm = 1;
- pmdigits=pmdigits-12;
- if (pmdigits==0) pmdigits=12;
- if (pmdigits>9)
- {
- n=pmdigits % 10;
- m=1;
- }
- else {
- m=0;
- n=pmdigits;
- }
- }
- testdigit(m,n,ampm,hourflag);
- m = numbers[3]-48;
- n = numbers[4]-48;
- hourflag = 0;
- testdigit(m,n,ampm,hourflag);
- }
- void testdigit(m,n,ampm,hourflag)
- {
- char *texts[]=
- {
- "ten", "alevehn", "twelve", "thir", "fif", "teeen", "twenty", "thirty", "forty", "fifty", "ayh m", "p m,"
- };
- char *nums[]= { "o", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", "00" };
-
- switch (m)
- {
- case 0:
- switch (n)
- {
- case 0:
- if (!hourflag)
- {
- strcat(sentence, nums[11]);
- break;
- }
- if (ampm) break;
- strcat(sentence, texts[2]);
- break;
- default:
- if (!hourflag) strcat(sentence, nums[0]);
- strcat(sentence, nums[n]);
- break;
- }
- break;
- case 1:
- switch (n)
- {
- case 0:
- strcat(sentence, texts[0]);
- break;
- case 1:
- strcat(sentence, texts[1]);
- break;
- case 2:
- strcat(sentence, texts[2]);
- break;
- case 3:
- strcat(sentence, texts[3]);
- strcat(sentence, texts[5]);
- break;
- case 4:
- strcat(sentence, nums[4]);
- strcat(sentence, texts[5]);
- break;
- case 5:
- strcat(sentence, texts[4]);
- strcat(sentence, texts[5]);
- break;
- case 6:
- strcat(sentence, nums[6]);
- strcat(sentence, texts[5]);
- break;
- case 7:
- strcat(sentence, nums[7]);
- strcat(sentence, texts[5]);
- break;
- case 8:
- strcat(sentence, nums[8]);
- strcat(sentence, texts[5]);
- break;
- case 9:
- strcat(sentence, nums[9]);
- strcat(sentence, texts[5]);
- break;
- }
- break;
- case 2:
- strcat(sentence, texts[6]);
- if (n) strcat(sentence, nums[n]);
- break;
- case 3:
- strcat(sentence, texts[7]);
- if (n) strcat(sentence, nums[n]);
- break;
- case 4:
- strcat(sentence, texts[8]);
- if (n) strcat(sentence, nums[n]);
- break;
- case 5:
- strcat(sentence, texts[9]);
- if (n) strcat(sentence, nums[n]);
- break;
- }
- strcat(sentence, nums[10]);
- if (!ampm && !hourflag)
- {
- strcat(sentence, texts[10]);
- strcat(sentence, nums[10]);
- }
- else if (!hourflag)
- {
- strcat(sentence, texts[11]);
- strcat(sentence, nums[10]);
- }
-
- }
-