home *** CD-ROM | disk | FTP | other *** search
- /* Welcome!
-
- Welcome is an recreation of the Welcome2 application using the new Speech Manager.
- I have no connection with the original author, except fond memories. :-)
-
- Copyright 1993 by Garrett Fitzgerald
- A product of donnael Software
-
- v1.3.2 - Adds Halloween (ARGH!) and fixes bug in selection of day-of-week holidays - 12/12/93
- Also fixed Munger bug--brought back from v2.0d (to appear later...)
- v1.3.1 - Added FlushEvents call, but it didn't help. The Speech Manager doesn't
- seem too happy with Male Voice and only 4M RAM....
- v1.3 - Menu selection of future default voice works! - 8/25/93
- v1.2 - Show speaking voice - 8/22/93
- Error alerts
- Gestalt now works, with inclusion of <GestaltEqu.h>
- Lists voices
- Added about box
- Defaults to "Female Voice", if available
- v1.1.1 - Increased app partition to permit more complicated voices - 8/16/93
- Changed to StopSpeechAt end of word
- Added commas after weekday
- Re-did Finder icon
- v1.1 - Added WaitNextEvent to allow quitting - 8/16/93
- v1.0 - initial release - 8/15/93
- */
-
- #include "Welcome.h"
- short vol_refnum,
- prefs_file_refnum;
-
- /* toolbox_init()
-
- Initializes the full toolbox--things here seem to depend on it.
- */
-
- toolbox_init()
- {
-
- InitGraf(&thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
- }
-
- /* prefs_init()
-
- Finds the Welcome! preferences file, or creates a new one. Returns true if file
- exists, false if the prefs folder can't be found or the file can't be opened.
- */
-
- Boolean
- prefs_init()
-
- {
- OSErr err;
- StringHandle vol_name;
- long prefs_dir;
- FSSpec prefs_spec;
- Handle voice_res;
- VoiceSpec init_voice_res;
- extern short prefs_file_refnum,
- vol_refnum;
-
- vol_name = NewString("\p");
- err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder,
- &vol_refnum, &prefs_dir);
- if (err != noErr)
- return false;
-
- err = FSMakeFSSpec(vol_refnum, prefs_dir, PREFS_FILE_NAME, &prefs_spec);
-
- if (err == fnfErr) {
- FSpCreateResFile(&prefs_spec, 'GSFC', 'pref', smSystemScript);
- err = ResError();
- if (err != noErr) {
- FSpDelete(&prefs_spec);
- return false;
- }
- prefs_file_refnum = FSpOpenResFile(&prefs_spec, fsRdWrPerm);
- err = ResError();
- if (err != noErr) {
- FSpDelete(&prefs_spec);
- return false;
- }
-
- init_voice_res.creator = '????';
- init_voice_res.id = '????';
- PtrToHand((Ptr)&init_voice_res, &voice_res, sizeof(VoiceSpec));
- AddResource(voice_res, VOICE_RES_TYPE, VOICE_RES_NUMB, "\pPreferred voice");
- WriteResource(voice_res);
- FlushVol(*vol_name, vol_refnum);
- }
- else {
- prefs_file_refnum = FSpOpenResFile(&prefs_spec, fsRdWrPerm);
- err = ResError();
- if (err != noErr) {
- return false;
- }
- }
- }
-
- /* date_to_text()
-
- Converts the numbers returned in Secs2Date to more readable months, days, time, and
- days of the week.
- */
-
- void
- date_to_text(StringHandle *month, StringHandle *day, StringHandle *weekday,
- StringHandle *time, StringHandle *greeting)
- {
- long secs,
- mil_time;
- Str255 hmin;
- DateTimeRec now;
-
- GetDateTime(&secs);
- IUTimeString(secs, false, hmin); /* 4:22 AM */
- *(hmin+*hmin+1) = '%'; /* Stick in a % for Munger to find later */
- *hmin += 1; /* and fix the length byte... */
- *time = NewString(hmin);
- mil_time = Munger(*time, 5, "M", 1, ".M.", 3); /* If this is 12 hour time, change */
- if (mil_time >= 0) /* AM/PM to A.M./P.M. */
- ***time += 2; /* Length byte again... */
-
- Secs2Date(secs, &now); /* Turn the seconds since 1904 into a date/time record */
- switch (now.dayOfWeek) { /* Change the day of week, month, and date into words */
- case 1:
- *weekday = NewString("\pSunday, %"); /* and stick in a % for Munger to find later... */
- break;
- case 2:
- *weekday = NewString("\pMonday, %");
- break;
- case 3:
- *weekday = NewString("\pTuesday, %");
- break;
- case 4:
- *weekday = NewString("\pWednesday, %");
- break;
- case 5:
- *weekday = NewString("\pThursday, %");
- break;
- case 6:
- *weekday = NewString("\pFriday, %");
- break;
- case 7:
- *weekday = NewString("\pSaturday, %");
- break;
- }
- switch (now.month) {
- case 1:
- *month = NewString("\pJanuary %");
- break;
- case 2:
- *month = NewString("\pFebruary %");
- break;
- case 3:
- *month = NewString("\pMarch %");
- break;
- case 4:
- *month = NewString("\pApril %");
- break;
- case 5:
- *month = NewString("\pMay %");
- break;
- case 6:
- *month = NewString("\pJune %");
- break;
- case 7:
- *month = NewString("\pJuly %");
- break;
- case 8:
- *month = NewString("\pAugust %");
- break;
- case 9:
- *month = NewString("\pSeptember %");
- break;
- case 10:
- *month = NewString("\pOctober %");
- break;
- case 11:
- *month = NewString("\pNovember %");
- break;
- case 12:
- *month = NewString("\pDecember %");
- break;
- }
- switch (now.day) {
- case 1:
- *day = NewString("\pfirst %");
- break;
- case 2:
- *day = NewString("\psecond %");
- break;
- case 3:
- *day = NewString("\pthird %");
- break;
- case 4:
- *day = NewString("\pfourth %");
- break;
- case 5:
- *day = NewString("\pfifth %");
- break;
- case 6:
- *day = NewString("\psixth %");
- break;
- case 7:
- *day = NewString("\pseventh %");
- break;
- case 8:
- *day = NewString("\peighth %");
- break;
- case 9:
- *day = NewString("\pnineth %");
- break;
- case 10:
- *day = NewString("\ptenth %");
- break;
- case 11:
- *day = NewString("\peleventh %");
- break;
- case 12:
- *day = NewString("\ptwelveth %");
- break;
- case 13:
- *day = NewString("\pthirteenth %");
- break;
- case 14:
- *day = NewString("\pfourteenth %");
- break;
- case 15:
- *day = NewString("\pfifteenth %");
- break;
- case 16:
- *day = NewString("\psixteenth %");
- break;
- case 17:
- *day = NewString("\pseventeenth %");
- break;
- case 18:
- *day = NewString("\peighteenth %");
- break;
- case 19:
- *day = NewString("\pnineteenth %");
- break;
- case 20:
- *day = NewString("\ptwentieth %");
- break;
- case 21:
- *day = NewString("\ptwenty-first %");
- break;
- case 22:
- *day = NewString("\ptwenty-second %");
- break;
- case 23:
- *day = NewString("\ptwenty-third %");
- break;
- case 24:
- *day = NewString("\ptwenty-fourth %");
- break;
- case 25:
- *day = NewString("\ptwenty-fifth %");
- break;
- case 26:
- *day = NewString("\ptwenty-sixth %");
- break;
- case 27:
- *day = NewString("\ptwenty-seventh %");
- break;
- case 28:
- *day = NewString("\ptwenty-eighth %");
- break;
- case 29:
- *day = NewString("\ptwenty-ninth %");
- break;
- case 30:
- *day = NewString("\pthirtieth %");
- break;
- case 31:
- *day = NewString("\pthirty-first %");
- break;
- }
-
- /* Go though and look for holidays -- specific date */
- if ((now.month == 1) & (now.day == 1))
- *greeting = NewString("\pHappy New Year! %");
- else if ((now.month == 2) & (now.day == 14))
- *greeting = NewString("\pHappy Valentine's Day! %");
- else if ((now.month == 3) & (now.day == 17))
- *greeting = NewString("\pHappy Saint Patrick's Day! %");
- else if ((now.month == 3) & (now.day == 19))
- *greeting = NewString("\pHappy Saint Joseph's Day! %"); /* I want a zeppola! */
- else if ((now.month == 6) & (now.day == 14))
- *greeting = NewString("\pHappy Flag Day! %");
- else if ((now.month == 7) & (now.day == 4))
- *greeting = NewString("\pHappy Independence Day! %");
- else if ((now.month == 10) & (now.day == 12))
- *greeting = NewString("\pHappy Columbus Day! %");
- else if ((now.month == 10) & (now.day == 31))
- *greeting = NewString("\pHappy Halloween! %");
- else if ((now.month == 11) & (now.day == 11))
- *greeting = NewString("\pHappy Veterans Day! %");
- else if ((now.month == 12) & (now.day == 25))
- *greeting = NewString("\pMerry Chrismas! %");
-
- /* Now find 2nd Monday, 4th Thursday, etc. */
- else if ((now.month == 2) & (now.day >= 9) & (now.day <= 15) & (now.dayOfWeek == 2))
- *greeting = NewString("\pHappy Presidents' Day! %");
- else if ((now.month == 5) & (now.day >= 8) & (now.day <= 14) & (now.dayOfWeek == 1))
- *greeting = NewString("\pHappy Mother's Day! %");
- else if ((now.month == 6) & (now.day >= 15) & (now.day <= 21) & (now.dayOfWeek ==1))
- *greeting = NewString("\pHappy Father's Day! %");
- else if ((now.month == 9) & (now.day >= 1) & (now.day <= 7) & (now.dayOfWeek == 2))
- *greeting = NewString("\pHappy Labor Day! %");
- else if ((now.month == 11) & (now.day >= 22) & (now.day <= 28) & (now.dayOfWeek == 5))
- *greeting = NewString("\pHappy Thanksgiving! %");
-
- /* Evening before holidays... */
- else if ((now.month == 12) & (now.day == 31) & (now.hour >= 18))
- *greeting = NewString("\pit's New Year's Eve! %");
- else if ((now.month == 12) & (now.day == 25) & (now.hour >= 18))
- *greeting = NewString("\pit's Chrismas Eve! %");
-
- /* If it's not a holiday, then... */
- else if ((now.hour >= 0) & (now.hour <= 4))
- *greeting = NewString("\pyou should be in bed! %");
- else if ((now.hour >= 5) & (now.hour <= 11))
- *greeting = NewString("\pgood morning. %");
- else if ((now.hour >= 12) & (now.hour <= 17))
- *greeting = NewString("\pgood afternoon. %");
- else if ((now.hour >= 18) & (now.hour <= 23))
- *greeting = NewString("\pgood evening. %");
- }
-
- Boolean
- handle_menus(long menu_choice, Boolean prefs)
- {
- static int checked_voice = 0;
- short menu,
- choice;
- Str255 da_name;
- MenuHandle voice_menu;
- VoiceSpec voice;
- Handle voice_res,
- voice_hand;
- OSErr err;
-
- menu = HiWord(menu_choice);
- choice = LoWord(menu_choice);
-
- switch (menu) {
- case MENU_APPLE:
- switch (choice) {
- case 1: /* About Branagh */
- Alert(ALRT_ABOUT, nil);
- break;
- default: /* DAs */
- GetItem(GetMHandle(MENU_APPLE), choice, da_name);
- OpenDeskAcc(da_name);
- break;
- }
- break;
- case MENU_FILE:
- if (choice == FILE_QUIT)
- return true;
- break;
- case MENU_VOICES:
- if ((prefs = true) && (choice != 0)) {
- voice_menu = GetMHandle(MENU_VOICES);
- if (checked_voice != 0)
- CheckItem(voice_menu, checked_voice, false);
- CheckItem(voice_menu, choice, true);
- GetIndVoice(choice, &voice);
- voice_res = GetResource(VOICE_RES_TYPE, VOICE_RES_NUMB);
- PtrToXHand((Ptr)&voice, voice_res, sizeof(VoiceSpec));
- ChangedResource(voice_res);
- err = ResError();
- if (err != noErr)
- SysBeep(20);
- }
- break;
- }
- return false;
- }
-
- stop_speech(SpeechChannel channel)
- {
- OSErr err;
-
- err = StopSpeechAt(channel, kEndOfWord);
- if (err != noErr)
- SysBeep(20);
- while (SpeechBusy() > 0);
- }
-
- main()
- {
- long info,
- ticks,
- menu_choice;
- int i;
- Boolean done = false,
- prefs;
- EventRecord choice;
- short index;
- StringHandle month,
- day,
- weekday,
- time,
- greeting,
- text;
- OSErr err;
- VoiceSpec voice;
- VoiceDescription voice_info;
- SpeechChannel channel;
- DialogPtr voice_dlog;
- Handle menu_bar,
- default_voice;
- MenuHandle menu,
- voice_menu;
- Point where;
- WindowPtr which_window;
- Boolean galatea = false;
- extern short prefs_file_refnum,
- vol_refnum;
-
- toolbox_init();
- FlushEvents(everyEvent, 0);
- prefs = prefs_init();
-
- menu_bar = GetNewMBar(MENU_BAR); /* Set up menus... */
- if (menu_bar == nil) {
- SysBeep(20);
- return;
- }
- else
- SetMenuBar(menu_bar);
-
- menu = GetMHandle(MENU_APPLE);
- AddResMenu(menu, 'DRVR');
-
- err = Gestalt(gestaltSpeechAttr, &info);
- if (err == gestaltUndefSelectorErr) {
- ParamText("\pWelcome! requires that the Speech Manager be installed. Sorry.", "\p", "\p", "\p");
- StopAlert(ALRT_ERR, nil);
- SysBeep(20);
- return;
- }
- else if (err != noErr) {
- ParamText("\pProblem calling Gestalt: exiting.", "\p", "\p", "\p");
- StopAlert(ALRT_ERR, nil);
- SysBeep(20);
- return;
- }
-
- if (!(info && (1L << gestaltSpeechMgrPresent))) {
- ParamText("\pWelcome! requires that the Speech Manager be installed. Sorry.", "\p", "\p", "\p");
- StopAlert(ALRT_ERR, nil);
- SysBeep(20);
- return;
- }
-
- err = CountVoices(&index); /* How many voices do we have? */
- if (err != noErr) {
- ParamText("\pI really don't think there should have been an error here...", "\p", "\p", "\p");
- StopAlert(ALRT_ERR, nil);
- SysBeep(20);
- return;
- }
-
- voice_menu = GetMHandle(MENU_VOICES);
- for (i = 1; i <= index; i++) {
- err = GetIndVoice(i, &voice);
- if (err != noErr) {
- ParamText("\pCouldn't find indicated voice. Exiting.", "\p", "\p", "\p");
- StopAlert(ALRT_ERR, nil);
- SysBeep(20);
- return;
- }
- GetVoiceDescription(&voice, &voice_info, sizeof(VoiceDescription));
- AppendMenu(voice_menu, voice_info.name);
- if ((voice.creator == 'gala') && (voice.id == 12)) /* If "Female voice" is available,*/
- galatea = true; /* use it, unless overruled */
- }
-
- DrawMenuBar();
-
- default_voice = GetResource(VOICE_RES_TYPE, VOICE_RES_NUMB);
- HLock(default_voice);
- if (((VoiceSpec *)*default_voice)->creator != '????') {
- voice.creator = ((VoiceSpec *)*default_voice)->creator;
- voice.id = ((VoiceSpec *)*default_voice)->id;
- GetVoiceDescription(&voice, &voice_info, sizeof(VoiceDescription));
- galatea = false;
- }
- HUnlock(default_voice);
-
- if (galatea) {
- voice.creator = 'gala';
- voice.id = (long)12;
- GetVoiceDescription(&voice, &voice_info, sizeof(VoiceDescription));
- }
-
- err = NewSpeechChannel(&voice, &channel); /* Open a SpeechChannel */
- if (err == synthOpenFailed) {
- ParamText("\pCould not open SpeechChannel: Try increasing the memory partition.", "\p", "\p", "\p");
- StopAlert(ALRT_ERR, nil);
- return;
- }
- else if (err != noErr) {
- ParamText("\pCould not open SpeechChannel: exiting.", "\p", "\p", "\p");
- StopAlert(ALRT_ERR, nil);
- SysBeep(20);
- return;
- }
-
- ParamText(voice_info.name, "\p", "\p", "\p");
- voice_dlog = GetNewDialog(DLOG_VOICE, nil, WINDOW_IN_FRONT);
- if (voice_dlog == nil) {
- ParamText("\pCan't show current voice...", "\p", "\p", "\p");
- StopAlert(ALRT_ERR, nil);
- }
- ShowWindow(voice_dlog);
- DrawDialog(voice_dlog);
-
- date_to_text(&month, &day, &weekday, &time, &greeting);
-
- /* Plug everything into one long string... */
- text = NewString("\pWelcome to Mackintosh, and %");
- SetHandleSize(text, sizeof(Str255));
- Munger(text, 1, "%", 1, *greeting+1, **greeting); /* Find the %, and replace it with */
- **text = **text + **greeting - 1; /* the next part of the string... */
- Munger(text, 1, "%", 1, "It's %", 6);
- **text = **text + 5; /* Fix the length byte, ignoring the */
- Munger(text, 1, "%", 1, *weekday+1, **weekday); /* length byte from the replacement string*/
- **text = **text + **weekday - 1; /* (it got cut out, *weekday+1, anyway) */
- Munger(text, 1, "%", 1, *month+1, **month);
- **text = **text + **month - 1;
- Munger(text, 1, "%", 1, *day+1, **day);
- **text = **text + **day - 1;
- Munger(text, 1, "%", 1, "at %", 4);
- **text = **text + 3;
- Munger(text, 1, "%", 1, *time + 1, **time);
- **text = **text + **time - 1;
- Munger(text, 1, "%", 1, ". Let's go!", 11);
- **text = **text + 10;
-
- MoveHHi(text);
- HLock(text);
- SpeakText(channel, (Ptr)(*text + 1), **text); /* Then speak the text through the channel */
- /* we got up top... */
- while(!done) {
- WaitNextEvent((mDownMask | keyDownMask), &choice, 15, nil);
- switch (choice.what) {
- case mouseDown:
- where = choice.where;
- switch (FindWindow(where, &which_window)) {
- case inMenuBar:
- menu_choice = MenuSelect(where);
- if (HiWord(menu_choice) != 0) {
- done = handle_menus(menu_choice, prefs);
- if (done == true)
- stop_speech(channel);
- }
- HiliteMenu(0);
- break;
- default:
- stop_speech(channel);
- done = true;
- break;
- }
- break;
- case keyDown:
- stop_speech(channel);
- done = true;
- break;
- }
- if (SpeechBusy() == 0)
- done = true;
- }
-
- HUnlock(text);
-
- DisposeSpeechChannel(channel); /* And clean up. */
- DisposeDialog(voice_dlog);
- DisposeHandle(month);
- DisposeHandle(day);
- DisposeHandle(weekday);
- DisposeHandle(greeting);
- DisposeHandle(text);
- DisposeHandle(time);
- CloseResFile(prefs_file_refnum);
- FlushVol(NewString("\p"), vol_refnum);
- }
-