home *** CD-ROM | disk | FTP | other *** search
- /*
- ReaderMouse
-
- Written by Katherine Smith &
- Jesse Donaldson
-
- We used a bit of apple sample source code, so portions are copyright Apple.
-
- */
- #include <Speech.h>
-
- #include "MyHeaders.h"
-
- #include "MyCaptureAppShell.h"
- #include "LetterFind.h"
- #include "WorkFunctions.h"
- #include "MyUtils.h"
-
- #define kMouseRegionWidth 120
- #define kMouseRegionHeight 50
-
- #ifdef powerc
- //QDGlobals qd;
- #endif
-
- Boolean gDone; // Set to true if you want to Application to kindly quit.
-
- WindowPtr gWin = 0;
-
- GWorldPtr gRecognizeThis = 0;
- unsigned long gLastTicks = 0;
- Rect gLastWordRect = {0,0,0,0};
- Point gLastMousePos = {0,0};
- unsigned long gLastMouseTicks = 0;
-
- void DoStuffo(void);
- void DoWorkOnImageData(GWorldPtr inGWorld, Point* origin);
- void PostProcessWord(Str255 str);
- Boolean CheckMouse(void);
-
- /* ------------------------------------------------------------------------- */
-
- void main()
- {
- EventRecord myEvent;
- long yieldTime = 10;
- WindowPtr foundWindow;
- short windowPart;
- Boolean isEvent;
- GrafPtr savePort;
- GDHandle saveGD;
- OSErr err=noErr;
-
- // Initialize here. Set the yield time too.
- // bestTimeBase
- // err = ProfilerInit(collectDetailed,microsecondsTimeBase,50,10);
- Initialize();
-
- // Event loop.
- for ( ; ; ) {
-
- // Get the event.
- isEvent = WaitNextEvent(everyEvent, &myEvent, yieldTime, nil);
-
-
- if((TickCount() - gLastTicks) > (60*1))
- {
- DoStuffo();
- gLastTicks = TickCount();
- }
- // If the event is unhandled by app specific event handling, then we proceed.
- if ( isEvent ) {
- switch ( myEvent.what ) {
-
- case mouseDown:
- // Get current port and device.
- GetPort(&savePort);
- saveGD = GetGDevice();
-
- // Set the port and gdevice to the window if we own the window.
- // We can then assume anytime the event occured in one of our windows,
- // that the port and gdevice are set correctly.
- windowPart = FindWindow(myEvent.where, &foundWindow);
- SetPort(foundWindow);
- SetGDevice(GetMainDevice());
-
- // Handle the different mouse down events.
- switch ( windowPart ) {
- case inSysWindow:
- SystemClick(&myEvent, foundWindow);
- break;
- case inMenuBar:
- DoCommand(MenuSelect(myEvent.where));
- break;
- case inContent:
- break;
- case inDrag:
- // If dragging one of the application's windows, then handle it.
- // However, if we are dragging a zoomed window, we
- // must remember to save the new window location into the
- // zoomed rect in the data handle. Otherwise, the event
- // manager will think that we are no longer zoomed.
- {
- WStateData *zoomData;
- Rect windowRect;
-
- // Get window location before drag.
- GetGlobalWindow(foundWindow, &windowRect);
-
- // Drag window.
- DragWindow (foundWindow, myEvent.where, &qd.screenBits.bounds);
- // MyDrag(foundWindow, myEvent.where);
-
- // If the windowRect in global coordinates matches the zoom rect,
- // then assume that we are dragging the zoomed window. update
- // zoom rect.
- zoomData = (WStateData *) *(((CWindowPeek) foundWindow)->dataHandle);
- if ( EqualRect(&(zoomData->stdState), &windowRect) ) {
- GetGlobalWindow(foundWindow, &windowRect);
- zoomData = (WStateData *) *(((CWindowPeek) foundWindow)->dataHandle);
- zoomData->stdState = windowRect;
- }
- }
- break;
- case inGrow:
- break;
- case inGoAway:
- // Handle clicking on the go away. If it is the clip window,
- // then hide it.
- if ( TrackGoAway (foundWindow, myEvent.where) ) {
- BringToFront(foundWindow);
- // MyClose();
- DisposeWindow(foundWindow);
- if(foundWindow == gWin) gWin = 0;
- }
- break;
- case inZoomIn:
- case inZoomOut:
- break;
- default:
- break;
- }
-
- // Restore port and device.
- SetPort(savePort);
- SetGDevice(saveGD);
-
- break;
- case keyDown:
- case autoKey:
- if ( myEvent.modifiers & cmdKey ) {
- if ( myEvent.what == keyDown ) {
- DoCommand(MenuKey(myEvent.message & charCodeMask));
- }
- }
- break;
- case updateEvt:
- // Handle update events for window and clip window.
- foundWindow = (WindowPtr) myEvent.message;
- GetPort(&savePort);
- saveGD = GetGDevice();
- SetPort(foundWindow);
- SetGDevice(GetMainDevice());
- BeginUpdate(foundWindow);
- EndUpdate(foundWindow);
- SetPort(savePort);
- SetGDevice(saveGD);
- break;
- case diskEvt:
- // This handles a bad disk. Otherwise the disk will not eject.
- if ( myEvent.message >> 16 ) {
- Point tempPoint;
- tempPoint.v = 50; tempPoint.h = 50;
- DIBadMount(tempPoint, myEvent.message);
- }
- break;
- case activateEvt:
- break;
- case app4Evt:
- switch ( myEvent.message >> 24 ) {
- case suspendResumeMessage:
- // yieldTime = MyYieldTime(myEvent.message & 0x01);
- break;
- default:
- DebugStr("\pUnexpected suspend/resume message.");
- }
- break;
- default:
- break;
- }
- }
-
- // If DoneFlag set, then quit.
- if ( gDone ) {
- // err = ProfilerDump((unsigned char *)"\pProfileInfo");
- // ProfilerTerm();
- ExitToShell();
- }
- }
- }
-
- /* ------------------------------------------------------------------------- */
-
- void Initialize()
- {
- OSErr err;
- Handle myMenu;
- Rect bounds;
-
- // Initialize Managaer.
- MaxApplZone();
- MoreMasters(); MoreMasters();
- MoreMasters(); MoreMasters();
- MoreMasters(); MoreMasters();
- MoreMasters(); MoreMasters();
- InitGraf(&qd.thePort);
- InitFonts();
- FlushEvents(everyEvent, 0);
- InitWindows();
- InitDialogs(nil);
- InitCursor();
-
- // Set up menus.
- myMenu = GetNewMBar(kMENUBAR);
- SetMenuBar(myMenu);
- DisposeHandle(myMenu);
- AppendResMenu(GetMenuHandle(kMENU_APPLEID), 'DRVR');
- DrawMenuBar();
-
- // Setup other globals.
- gDone = false;
-
- // Create window:
- bounds.top = 50;
- bounds.left = 50;
- bounds.bottom = bounds.top + kMouseRegionHeight;
- bounds.right = bounds.left + kMouseRegionWidth;
-
- gWin = NewCWindow(0, &bounds, "\pBits", true, documentProc, (WindowPtr)-1, true, 0);
- SetPort(gWin);
-
- // Create gworld:
- bounds.top = bounds.left = 0;
- bounds.right = kMouseRegionWidth;
- bounds.bottom = kMouseRegionHeight;
-
- err = NewGWorld(&gRecognizeThis, 16, &bounds, nil, nil, 0);
-
-
- // Call app specific Intialization.
- // Initialize Font data
- err = InitializeFonts();
- if (err != noErr)
- DebugStr("\perror initializing...");
-
-
- return;
- }
-
- void DoCommand(long mResult)
- {
- short theMenu, theItem;
- Str255 myStr;
- GrafPtr savePort;
- GDHandle saveGD;
-
- theItem = LoWord(mResult);
- theMenu = HiWord(mResult);
-
- if ( theItem != 0 || theMenu != 0 ) {
- switch ( theMenu ) {
- case kMENU_APPLEID:
- if ( theItem == 1 ) {
- ParamText("\pSample QuickTime Recording Application", "\pUses Sequence Grabber.", nil, nil);
- Alert(kALERT_ABOUT, nil);
- } else {
- GetMenuItemText(GetMenuHandle(kMENU_APPLEID), theItem, myStr);
- GetPort(&savePort);
- saveGD = GetGDevice();
- (void) OpenDeskAcc(myStr);
- SetPort(savePort);
- SetGDevice(saveGD);
- }
- break;
-
- case kMENU_FILEID:
- switch ( theItem ) {
- case kMENU_FILENEW:
- // MyNew();
- break;
- case kMENU_FILECLOSE:
- // MyClose();
- break;
- case kMENU_FILEQUIT:
- gDone = true;
- break;
- default:
- ReportFatal("\pError in handling file menu:", theItem);
- }
- break;
-
- case kMENU_SETTINGSID:
- // MySettings(theItem);
- break;
-
- case kMENU_RESIZEID:
- // MyResize(theItem);
- break;
-
- case kMENU_SPECIALID:
- // MySpecial(theItem);
- break;
-
- case kMENU_RECORDID:
- // MyRecord();
- break;
-
- default:
- ReportFatal("\pError in handling menu:", theMenu);
- }
- }
- HiliteMenu(0);
- }
-
- void DoStuffo(void)
- {
- Rect srcRect, dstRect = {0,0,0,0};
- Point where;
-
- if(gWin == 0) return;
-
- SetPort(gWin);
- GetMouse(&where);
- LocalToGlobal(&where);
-
- // don't do any work if we're still
- // pointing at the last word we recognized.
- if(PtInRect(where, &gLastWordRect)) return;
-
- // clear rectangle now that we've moved out of it.
- gLastWordRect.top = gLastWordRect.left = 0;
- gLastWordRect.bottom = gLastWordRect.right = 0;
-
- // abort if we moved the mouse.
- // if( CheckMouse() ) return;
-
- // GetPort(&savePort);
- // saveGD = GetGDevice();
- // SetPort((GrafPort*)gWorkGWorldPtr);
-
- LockPixels(GetGWorldPixMap(gRecognizeThis));
-
- srcRect.left = where.h - (kMouseRegionWidth/2);
- srcRect.right = srcRect.left + kMouseRegionWidth;
- srcRect.top = where.v - (kMouseRegionHeight/2);
- srcRect.bottom = srcRect.top + kMouseRegionHeight;
-
- dstRect.right = gWin->portRect.right - gWin->portRect.left;
- dstRect.bottom = gWin->portRect.bottom - gWin->portRect.top;
-
- CopyBits (&qd.screenBits, (BitMap*)*GetGWorldPixMap(gRecognizeThis),
- &srcRect, &dstRect, srcCopy, 0);
-
- CopyBits ((BitMap*)*GetGWorldPixMap(gRecognizeThis), &gWin->portBits,
- &dstRect, &dstRect, srcCopy, 0);
-
- UnlockPixels(GetGWorldPixMap(gRecognizeThis));
-
- // convert 'where' to GWorld origin in global coords
- where.h = srcRect.left;
- where.v = srcRect.top;
-
- DoWorkOnImageData(gRecognizeThis, &where);
-
- // qd.screenBits
- }
-
- Boolean CheckMouse(void)
- {
- Point where;
- Boolean result;
-
- if(gWin == 0) return true;
-
- SetPort(gWin);
- GetMouse(&where);
- LocalToGlobal(&where);
-
- result = (where.h != gLastMousePos.h || where.v != gLastMousePos.v);
- gLastMousePos = where;
-
- return result;
-
- /* // If we move the mouse, reset the position & countdown timer
- if(where.h != gLastMousePos.h || where.v != gLastMousePos.v)
- {
- gLastMousePos = where;
- gLastMouseTicks = TickCount();
- return true;
- }
- */
-
-
- // Recognition takes long enough that we can remove the artificial delay,
- // as well as the earlier check, and then just check if the mouse
- // has moved before we speak the string...
-
- // If the mouse hasn't moved for 20 ticks,
- // go ahead & recognize the pixels.
- /* if((TickCount() - gLastMouseTicks) < 20)
- {
- return true;
- }
- else
- {
- gLastMousePos = where;
- gLastMouseTicks = TickCount();
- }
- */
- return false;
- }
-
- /*
- Do post processing on string to make a good guess whether
- a glyph is a capitol i or a lowercase L.
- */
- void PostProcessWord(Str255 str)
- {
- Boolean allCaps, allLower;
- short i, len;
- Boolean letter2IsVowel;
-
- len = str[0];
-
- allCaps = true;
- allLower = true;
-
- // Word is all capitol letters?
- for(i=1; i<=len; i++)
- {
- if(str[i] < 'A' || str[i] > 'Z')
- {
- if(str[i] != 'l') allCaps = false;
- }
- }
-
- // Word is all lowercase letters?
- for(i=1; i<=len; i++)
- {
- if(str[i] < 'a' || str[i] > 'z')
- {
- if(str[i] != 'L') allCaps = false;
- }
- }
-
- // Determine if 2nd letter is a vowel.
- if(len <= 1) letter2IsVowel = false;
- else if(str[2] == 'a' || str[2] == 'e' || str[2] == 'i' ||
- str[2] == 'o' || str[2] == 'u')
- letter2IsVowel = true;
- else letter2IsVowel = false;
-
- // Post process L's and i's.
- for(i=1; i<=len; i++)
- {
- // turn capitol i into lowercase L.
- // if its a capitol i and the word isn't all caps...
- if(str[i] == 'I' && !allCaps)
- {
-
- // .. and if its NOT the first letter, or if its followed by a vowel...
- if(i > 1 || letter2IsVowel)
- {
- str[i] = 'l'; // then turn it into a lowercase L.
- }
- }
-
- // turn lowercase L into capitol i.
- if(str[i] == 'l')
- {
- if(allCaps || (i==1 && !letter2IsVowel))
- str[i] = 'I';
- }
-
- }
-
- return;
- }
-
-
- void DoWorkOnImageData (GWorldPtr inGWorld, Point *origin)
- {
- WordData bestWord;
- Str255 spokenString;
-
- CheckMouse();
-
-
- MyFindWord(&bestWord, inGWorld);
-
- CopyGWorldToWindow(gScreenHDiff, gWin);
-
- DrawChosenString(gWin, &bestWord);
-
- CopyWordToPascalString(spokenString, &bestWord);
- SetWTitle(gWin, spokenString);
-
-
- // special case for illegal 1-letter strings which seem to pop
- // up when the recognizer doesn't have anything better to say.
- if(spokenString[0] == 1 && spokenString[1] != 'I' && spokenString[1] != 'a'
- && spokenString[1] != 'A' &&
- (spokenString[1] < '0'|| spokenString[1] > '9'))
- {
- return;
- }
-
- PostProcessWord(spokenString);
-
- // abort if we moved the mouse.
- if( CheckMouse() ) return;
-
- // set up the word rect so we don't say it over & over again.
- gLastWordRect = bestWord.wordBounds;
- gLastWordRect.top += origin->v;
- gLastWordRect.bottom += origin->v;
- gLastWordRect.left += origin->h;
- gLastWordRect.right += origin->h;
-
- SpeakString(spokenString);
-
- return;
- }
-
-