The DigitaOS: An Extensible Imaging Platform by Carlos E. Vidales and Eugene M. Farrelly Listing One #include #include TVoidPtr entry(void) { TAMAppID appId ; TEMEventRecord * theEvent ; TBoolean doExit ; AppInit() ; RegisterForEvents() ; while( !doExit ) { EMGetEvent( appId, &theEvent ) ; doExit = HandleEvent( &theEvent ) ; } AppExit() ; return(NULL); } Listing Two # Sample configuration file for extended time-lapse application # Turn logging on to catch any errors during command execution Log on # Label statement for flow control with goto statements Label repeat # Wake at 1:30:00 pm wake 13 30 00 # Zoom to 2x magnification zoom 200 # Capture 1 image capture 1 # Zoom out Zoom out # Capture 1 image capture 1 # Repeat the sequence goto repeat Listing Three /* structure of a node in the doubly linked list */ struct cmd_list { TErrCo (* cmdFunc) (); TShort argc; TChar ** argv; TShort cmdMinNumOfArgs; TShort fileLineNum; TBoolean isResolved; TShort cmdExecutionCounter; struct cmd_list * nextCmd; struct cmd_list * prevCmd; } ; Listing Four /* entry point for Digita apps */ TInt entry(TInt argc, TChar **argv) { TErrCo err = kNoErr, appErr = kNoErr; TAMAppID appID = 0; sigset_t pendingSet; TBoolean alarmSignal; TEMEventRecord *theEvent; TChar text[kMaxTextLength]; TBoolean doExit; // Start the necessary subsystems according to app content. err = ProcessInit(); // Start the graphics subsystem and display a global banner.... if (kNoErr == (err = SDKDInit(TRUE))) { LMEnableLCDController() ; SDKDDrawTextandScrollUp(" Digita Sample Application "); } else { return(NULL); } // Process functions before enabling button events. err = ProcessBeforeEventLoop(); // Get the application ID and ensure it's valid if (0 == (appID = RegisterWithEventManager())) err = !kNoErr; // Set to not no-error gAppID = appID ; SDKDDrawTextandScrollUp("Press Menu button for options"); // Process while there are no system event errors doExit = FALSE ; while ( (err == kNoErr) && !doExit ) { // Block & wait for next event. Event subsystem allocated mem for event. err = EMGetEvent( appID, &theEvent); if (err != kNoErr) { //Handle a signal that is posted. if (0 == sigpending(&pendingSet)) { alarmSignal = sigismember(&pendingSet, SIGALRM); err = kNoErr; } } else { // Got an event, now Handle it. appErr = HandleEvent(theEvent, &doExit); // Release the event, specifically the mem allocated EMReleaseEventRecord(theEvent); // Now check the application error. if ((err == kNoErr) && (appErr != kNoErr)) { err = appErr; } } } // Exit the application. SDKDScrollUp(); sprintf( text, "Exiting sample, rc = %ld", FPERROR(err) ); SDKDDrawTextandScrollUp(text); DelayTime( 30 ) ; // let me see the message ... err = SDKDTerminate(); //Terminate the graphic manager err = ProcessTerm(); // ProcessTerm() will turn off the camera. return(NULL); } // entry Listing Five TErrCo ProcessButtonEvent(const TBTNDigitaButtonId buttonID, const TBTNDigitaButtonPosition buttonState) { TErrCo err = kNoErr; switch (buttonID) { case kDigitaSoftKey2: CenterSoftkeyButton(buttonState); break; default: break; } return(err); } // ProcessButtonEvent Listing Six TVoid CenterSoftkeyButton(TBTNDigitaButtonPosition buttonState) { TErrCo err = kNoErr; TChar msg[kMaxTextLength]; if (!sCommandProcessorStarted) { if (buttonState == kButtonUp) { if (sCommandInitSuccess) { // set a flag disable button events (except power down) sCommandProcessorStarted = TRUE; // Start with the first command CommandGoToCmdStart(); if (kNoErr != (err = CommandDispatch(gCmdCur,FALSE))) { sprintf(msg,sDispatchEventError, FPERROR (err)); SDKDDrawTextandScrollUp(msg); } } else { sprintf(msg,"Commands contained errors."); SDKDDrawTextandScrollUp(msg); } } } return; } // CenterSoftkeyButton Listing Seven TErrCo CommandDispatch(TCmdData * pCmd, TBoolean validate) { TErrCo err = kNoErr; // if arg is null, use current command if (pCmd == NULL) { pCmd = gCmdCur; } // Record the time when the command is dispatched CommandGetTime(&sCurSystemTime,&sCurTmTime); // Dispatch the command if (pCmd != NULL) { err = (*(pCmd->cmdFunc)) (pCmd,validate); } else { // Current command is not set err = kCurrentCmdNotSetErr; } if (sLoggingEnabled) { // Log the command CommandLogCmd(FPERROR (err)); } return(err); } // CommandDispatch Listing Eight // Convert the zoom value to an integer zoomValue = atoi(pCmd->argv[zoomIndex]); // Retrieve the current zoom position setting if (kNoErr == (err = PARMGetCurrentSetting( kFTAGzpos, &nameTypeValue ))) { // Set the zoom position nameTypeValue.fTypeValue.fValue.fUint = zoomValue ; // write the structure back to make it take effect. err = PARMSetCurrentSetting( kFTAGzpos, &(nameTypeValue.fTypeValue) ); } Listing Nine TInt LocalCaptureSpoolingComplete(TVoidPtr data) { TErrCo err = kNoErr; DispatchEvent(fData0_Group,fData1_Spooled,"Capture spooling complete"); return(err); } // LocalCaptureSpoolingComplete Listing Ten #include #include #include // forward declaration TBoolean myHandler(TEMEventRecord pEvent, TVoidPtr pData) ; TBoolean myHandler(TEMEventRecord pEvent, TVoidPtr pData) { TBoolean handled = TRUE ; // sample implementation return(handled) ; } // end of myHandler TVoidPtr entry(void) { TErrCo err ; CAFShell *app = new CAFShell(kAMImagingApp) ; MyView *view = new MyView() ; err = app->OpenFW() ; app->RegisterSystemHandler(myHandler, NULL) ; if(err == kNoErr) { // miscellaneous initialization view = new MyView() ; app->OpenView(view) ; app->DoEventLoop() ; app->CloseFW(); delete view ; } delete app ; return(NULL) ; } Listing Eleven #define kMyDoThis "MyDoThis" #define kMyDoThat "MyDoThat" #define kMyAbout "MyAbout" MyView::MyView() { // Could create own workspace (container) but using the one supplied. // mWorkspace = new CAFWorkSpace() ; mItemBar = new CAFItemBar() ; mOptionListBox = new CAFListBox(); mAboutView = new MyAboutView() ; SetCommandButton(kCBLeftButton, kMyDoThis ) ; SetCommandButton(kCBMiddleButton, kMyDoThat ) ; SetCommandButton(kCBRightButton, kMyAbout ) ; } // end of constructor MyView::TargetSwitchEnter(TVoid *pData) { int n, options ; CAFActionListItem *nextItem ; CAFView * pView ; // create a menu nextItem = new CAFActionListItem(); nextItem->SetItemLabel(kMyMenu); nextItem->SetActionLabel(kMyDoThis); pView = new MyMenuView(); nextItem->SetView(pView); mViewList.AddItem(pView); nextItem->SetHelpText((TChar *)NULL, kMyMenuIcon); mOptionListBox->AddOption(nextItem); // create another menu nextItem = new CAFActionListItem(); nextItem->SetItemLabel(kMyNextMenu); nextItem->SetActionLabel(kMyDoThat); pView = new MyNextMenuView(); nextItem->SetView(pView); mViewList.AddItem(pView); nextItem->SetHelpText((TChar *)NULL, kMyNextMenuIcon); mOptionListBox->AddOption(nextItem); // more menus // Initialize the item bar for this view SetItemBar( mItemBar, FALSE) ; // set the view parameters options = mOptionListBox->GetOptionCount() ; for(n = 0 ; n < options ; n++ ) { mOptionListBox->GetOption(n)->SetViewParm(mItemBar) ; } } // end of TargetSwitchEnter() TBoolean MyView:HandleEvent( TEMEventRecord *pEvent ) { TBoolean handled = FALSE ; TBTNDigitaButtonID buttonIndex ; if( pEvent->fEvClass == kButtonClassEvent && pEvent->fParams.fButtonEvent.fPosition == kButtonUp ) { // will handle this event buttonIndex = pEvent->fParams.fButtonEvent.fButtonIndex ; switch(buttonIndex) { case kDigitaSoftKey1: // perform specific operation // might be appropriate to refresh views Refresh() ; FWRefreshView() ; handled = TRUE ; break ; // other cases . . . } // end of switch } // end of handling event if(!handled) { // let the parent class handle this event handle = CAFBaseView::HandleEvent(pEvent); } return(handled) ; } // end of HandleEvent() 6