home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / apps.to.go / Kibitz / SpeechMessage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-02  |  4.5 KB  |  203 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        speechmessage.c
  5. ** Written by:  Eric Soldan
  6. **
  7. ** Copyright © 1990-1992 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11.  
  12.  
  13. /*****************************************************************************/
  14.  
  15.  
  16.  
  17. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  18. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  19. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  20.  
  21. #ifndef __GESTALTEQU__
  22. #include <GestaltEqu.h>
  23. #endif
  24.  
  25. #ifndef __MEMORY__
  26. #include <Memory.h>
  27. #endif
  28.  
  29. #ifndef __OSUTILS__
  30. #include <OSUtils.h>
  31. #endif
  32.  
  33. #ifndef __TOOLUTILS__
  34. #include <ToolUtils.h>
  35. #endif
  36.  
  37. #ifndef __TEXTEDITCONTROL__
  38. #include <TextEditControl.h>
  39. #endif
  40.  
  41. #ifndef __UTILITIES__
  42. #include <Utilities.h>
  43. #endif
  44.  
  45.  
  46.  
  47. /*****************************************************************************/
  48. /*****************************************************************************/
  49.  
  50. #include <Speech.h>
  51.  
  52. #ifdef powerc
  53. #pragma options align=mac68k
  54. #endif
  55. struct WordLimits {
  56.     Boolean hilite;
  57.     short    wordStart;
  58.     short    wordEnd;
  59. };
  60. typedef struct WordLimits WordLimits;
  61. typedef WordLimits *WordLimitsPtr;
  62. #ifdef powerc
  63. #pragma options align=reset
  64. #endif
  65.  
  66. pascal void    MyWordCallback(SpeechChannel sChannel, WordLimitsPtr wLP, long wordPos, short wordLen);
  67.  
  68.  
  69.  
  70. /*****************************************************************************/
  71. /*****************************************************************************/
  72.  
  73.  
  74.  
  75. Boolean    SpeechAvailable(void)
  76. {
  77.     long    result;
  78.  
  79.     if (Gestalt(gestaltSpeechAttr, &result)) return (false);
  80.     
  81.     if (!(result & (1 << gestaltSpeechMgrPresent))) return(false);
  82.  
  83.     /*
  84.      * There isn't an equate to identify the PowerPC Speech Mgr. Lib
  85.      * When there is then change this conditional to #ifdef powerc
  86.      */
  87. #if 0
  88.     if (!(result & (1 << gestaltSpeechMgrLibPresent))) return(false);
  89. #endif
  90.  
  91.     return(true);
  92. }
  93.  
  94.  
  95.  
  96. /*****************************************************************************/
  97.  
  98.  
  99.  
  100. /* We will use the word call back to hilite the next word to be spoken. 
  101.    The problem is that this proc is called at interrupt time and can not
  102.    use something that moves memory, so here we only save the information and
  103.    let the "while speechbusy loop do the actual hiliting.
  104. */
  105.  
  106. pascal void MyWordCallback(SpeechChannel sChannel, WordLimitsPtr wLP, long wordPos, short wordLen)
  107. {
  108. #ifndef __MWERKS__
  109. #pragma unused (sChannel)
  110. #endif
  111.  
  112.     wLP->hilite = true;        /* flag that word needs hiliting */
  113.     wLP->wordStart = wordPos;
  114.     wLP->wordEnd = wordPos + wordLen;
  115. }
  116.  
  117.  
  118.  
  119. /*****************************************************************************/
  120.  
  121.  
  122.  
  123. /*     - Calls SpeakText.
  124.     - Opens a speech channel,
  125.     - holds until done
  126.     - hilites the word being spoken
  127.     - checks for command period
  128.     - disposes of the channel.
  129. */
  130.  
  131. OSErr SayText(TEHandle teH, Handle txt, VoiceSpec theVoice)
  132. {
  133.     VoiceSpec        *voicePtr;
  134.     WordLimits        wlimits;
  135.     SpeechChannel    sChannel;
  136.     KeyMap            kMap;
  137.     TEHandle        oldActive;
  138.     OSErr            err;
  139.     Ptr                txtPtr;
  140.     short            txtSiz, txtBeg, txtEnd;
  141.     static SpeechWordUPP    myWordCallbackUPP = nil;
  142.  
  143.     voicePtr = (theVoice.creator) ? &theVoice : nil;
  144.  
  145.     if (!(err = NewSpeechChannel(voicePtr, &sChannel)) ) {
  146.         SetSpeechInfo(sChannel, soRefCon, &wlimits);
  147.         if (!myWordCallbackUPP)
  148.             myWordCallbackUPP = NewSpeechWordProc(MyWordCallback);
  149.         SetSpeechInfo(sChannel, soWordCallBack, myWordCallbackUPP);
  150.  
  151.         /* need to activate to let user see the highlited words as they are spoken. */
  152.  
  153.         if (teH)
  154.             txt = (*teH)->hText;
  155.  
  156.         HLock(txt);
  157.         txtPtr = *txt;
  158.         txtSiz = GetHandleSize(txt);
  159.         txtBeg = 0;
  160.         if (teH) {
  161.             txtBeg  = (*teH)->selStart;
  162.             txtEnd  = (*teH)->selEnd;
  163.             txtPtr += txtBeg;
  164.             txtSiz -= txtBeg;
  165.             CTESetSelect(0, 0, teH);
  166.             oldActive = CTEFindActive(nil);
  167.             CTEActivate(true, teH);
  168.         }
  169.  
  170.         if (!(err = SpeakText(sChannel, *txt + txtBeg, txtSiz))) {
  171.  
  172.             while (SpeechBusy() > 0) { /* Need to wait until all stops */
  173.  
  174.                 if (wlimits.hilite) {            /* first we check if word being spoken needs hiliting */
  175.                     if (teH)
  176.                         CTESetSelect(wlimits.wordStart + txtBeg, wlimits.wordEnd + txtBeg, teH);
  177.                     wlimits.hilite = false;        /* do it only once */
  178.                 }
  179.                 GetKeys(kMap);
  180.                 if ((kMap[1] == 0x808000) ){ /* user is tired of the long message */
  181.                     err = StopSpeech(sChannel);
  182.                     break;
  183.                 }
  184.             }
  185.         }
  186.         HUnlock(txt);
  187.  
  188.         if (teH) {
  189.             CTEActivate(false, teH); /* no more */
  190.             CTEActivate(true, oldActive);
  191.             CTESetSelect(txtBeg, txtEnd, teH);
  192.         }
  193.  
  194.         SetSpeechInfo(sChannel, soWordCallBack, nil);
  195.         err = DisposeSpeechChannel(sChannel);
  196.     }
  197.  
  198.     return err;
  199. }
  200.  
  201.  
  202.  
  203.