////////////////////////////////////////////////////////////////// // // GetTerminalFromStreamEvent - get the stream from the event and // after this get the terminal from stream - if any // ////////////////////////////////////////////////////////////////// HRESULT GetTerminalFromStreamEvent( IN ITCallMediaEvent * pCallMediaEvent, OUT ITTerminal ** ppTerminal ) { // //do not return bogus value // *ppTerminal = NULL; // // Get the stream for this event. // ITStream * pStream = NULL; HRESULT hr = pCallMediaEvent->get_Stream( &pStream ); if (FAILED(hr)) { DoMessage( _T("GetTerminalFromStreamEvent: get_Stream failed")); return E_FAIL; } // // Enumerate the terminals on this stream. // IEnumTerminal * pEnumTerminal = NULL; hr = pStream->EnumerateTerminals( &pEnumTerminal ); // //not need this anymore // pStream->Release(); if ( FAILED(hr) ) { DoMessage(_T("GetTerminalFromStreamEvent: EnumerateTerminals failed")); return hr; } // // Get the first terminal -- if there aren't any, return E_FAIL so that // we skip this event (this happens when the terminal is on the other // stream). // hr = pEnumTerminal->Next(1, ppTerminal, NULL); // //clean up // pEnumTerminal->Release(); // //map anything but S_OK to failure - even S_FALSE // if ( hr != S_OK ) { return E_FAIL; } return S_OK; }
///////////////////////////////////////////////////////////// // Click on the Ok button, check and save keyboard config ///////////////////////////////////////////////////////////// void CKeyboardDialog::OnOk(wxCommandEvent& WXUNUSED(event)) { for(int i = 0; i<8; i++) { // Special key check if(m_pInput->IsSpecialKey(m_pKeys[i])) { DoMessage(GetText("ForbiddenKey"), MSG_ERROR); return; } // Check if a key has already been used for another direction for(int j=0; j<8; j++) { if(i != j) { if(m_pKeys[i] == m_pKeys[j]) { DoMessage(GetText("RedundantKey"), MSG_ERROR); return; } } } } // Now set the keys to the input object for(int iDir=0; iDir<4; iDir++) { m_pInput->SetKeysControl((eDirection)iDir, m_pKeys[iDir*2+1], m_pKeys[iDir*2]); } EndModal(0); }
/////////////////////////////////////////////////////////////////// // DoCallState // // TE_CALLSTATE is a call state event. pEvent is // an ITCallStateEvent // /////////////////////////////////////////////////////////////////// HRESULT DoCallState( IN IDispatch * pEvent) { CALL_STATE cs = CS_IDLE; ITCallStateEvent * pCallStateEvent = NULL; // // Get the interface // HRESULT hr = pEvent->QueryInterface( IID_ITCallStateEvent, (void **)&pCallStateEvent ); if(FAILED(hr)) { DoMessage( _T("CallStateEvent, but failed to get the interface")); return hr; } // //check if same call - if it is not do not process the event // if(false == SameCall(pCallStateEvent)) { pCallStateEvent->Release(); return hr; } // // get the CallState that we are being notified of. // hr = pCallStateEvent->get_State( &cs ); pCallStateEvent->Release(); if(FAILED(hr)) { DoMessage( _T("ITCallStateEvent, but failed to get_State")); return hr; } // // send messages to main dialog procedure // if (CS_OFFERING == cs) { PostMessage(g_hDlg, WM_COMMAND, IDC_ANSWER, 0); } else if (CS_DISCONNECTED == cs) { PostMessage(g_hDlg, WM_COMMAND, IDC_DISCONNECTED, 0); } else if (CS_CONNECTED == cs) { PostMessage(g_hDlg, WM_COMMAND, IDC_CONNECTED, 0); } return hr; }
/********************************************************** * COperator::AnswerTheCall * *--------------------------* * Description: * Called whenever notification is received of an * incoming call and the app wants to answer it. * Answers and handles the call. * Return: * S_OK * Failed retval of QI(), ITCallInfo::get_Address(), * COperator::SetAudioOutForCall(), ************************************************************/ HRESULT COperator::AnswerTheCall() { if (NULL == m_pCall) { return E_UNEXPECTED; } // Get the LegacyCallMediaControl interface so that we can // get a device ID to reroute the audio ITLegacyCallMediaControl *pLegacyCallMediaControl; HRESULT hr = m_pCall->QueryInterface( IID_ITLegacyCallMediaControl, (void**)&pLegacyCallMediaControl ); // Set the audio for the SAPI objects so that the call // can be handled if ( SUCCEEDED( hr ) ) { hr = SetAudioOutForCall( pLegacyCallMediaControl ); if ( FAILED( hr ) ) { DoMessage( L"Could not set up audio out for text-to-speech" ); } } if ( SUCCEEDED( hr ) ) { hr = SetAudioInForCall( pLegacyCallMediaControl ); if ( FAILED( hr ) ) { DoMessage( L"Could not set up audio in for speech recognition" ); } } pLegacyCallMediaControl->Release(); if ( FAILED(hr) ) { return hr; } // Now we can actually answer the call hr = m_pCall->Answer(); return hr; } /* COperator::AnswerTheCall */
/********************************************************** * COperator::ListenOnAddresses * *------------------------------* * Description: * Find all addresses that support audio in and audio * out. Call ListenOnThisAddress to start listening * Return: * S_OK * S_FALSE if there are no addresses to listen on * Failed HRESULT ITTAPI::EnumberateAddresses() * or IEnumAddress::Next() ************************************************************/ HRESULT COperator::ListenOnAddresses() { // enumerate the addresses IEnumAddress * pEnumAddress; HRESULT hr = m_pTapi->EnumerateAddresses( &pEnumAddress ); if ( FAILED(hr) ) { return hr; } ITAddress * pAddress; bool fAddressExists = false; while ( true ) { // get the next address hr = pEnumAddress->Next( 1, &pAddress, NULL ); if (S_OK != hr) { // Done dealing with all the addresses break; } // Does the address support audio? if ( AddressSupportsMediaType(pAddress, TAPIMEDIATYPE_AUDIO) ) { // If it does then we'll listen. HRESULT hrListen = ListenOnThisAddress( pAddress ); if ( S_OK == hrListen ) { fAddressExists = true; } } pAddress->Release(); } pEnumAddress->Release(); if ( !fAddressExists ) { DoMessage( L"Could not find any addresses to listen on" ); } if ( FAILED( hr ) ) { return hr; } else { return fAddressExists ? S_OK : S_FALSE; } } /* COperator::ListenOnAddress */
/* output callback */ ivTTSErrID ivCall OutputCB( ivPointer pParameter, /* [in] user callback parameter */ ivUInt16 nCode, /* [in] output data code */ ivCPointer pcData, /* [in] output data buffer */ ivSize nSize ) /* [in] output data size */ { /* »ñÈ¡Ïß³ÌÏûÏ¢£¬ÊÇ·ñÍ˳öºÏ³É */ pParameter = NULL; ivTTSErrID tErr = DoMessage(); if ( tErr != ivTTS_ERR_OK ) return tErr; /* °ÑÓïÒôÊý¾ÝËÍÈ¥²¥Òô */ return OnOutput(nCode, pcData, nSize); }
// The override of the "game loop" isn't much different from the base class version. // We purposely render here rather than within in an OnPaint handler. // This method returns the wParam of the WM_QUIT message. int TApp::MainLoop() { m_keepGoing = TRUE; while (m_keepGoing) { frame->canvas->Draw(); while (!Pending() && ProcessIdle()) ; DoMessage(); } return s_currentMsg.wParam; }
/////////////////////////////////////////////////////////////////// // DoCallMedia // // // TE_CALLMEDIA is a media event. pEvent is an ITCallMediaEvent // // /////////////////////////////////////////////////////////////////// HRESULT DoCallMedia( IN IDispatch * pEvent) { CALL_MEDIA_EVENT cme = CME_STREAM_INACTIVE; ITCallMediaEvent * pCallMediaEvent = NULL; // // check if we still have a call // if(NULL == g_pCall) { return E_UNEXPECTED; } // // Get the interface // HRESULT hr = pEvent->QueryInterface( IID_ITCallMediaEvent, (void **)&pCallMediaEvent ); if(FAILED(hr)) { DoMessage( _T("ITCallMediaEvent, but failed to get the interface")); return hr; } // // get the CALL_MEDIA_EVENT that we are being notified of. // hr = pCallMediaEvent->get_Event( &cme ); if(FAILED(hr)) { pCallMediaEvent->Release(); DoMessage( _T("ITCallMediaEvent, but failed to get_Event")); return hr; } switch ( cme ) { // // the only event we process // case CME_STREAM_ACTIVE: { // // Get the terminal that's now active. // ITTerminal * pTerminal = NULL; hr = GetTerminalFromStreamEvent(pCallMediaEvent, &pTerminal); if ( FAILED(hr) ) { DoMessage(_T("ITCallMediaEvent: GetTerminalFromStreamEvent failed")); g_pCall->Disconnect(DC_NORMAL); break; } // // Process this terminal based on the direction. // TERMINAL_DIRECTION td; hr = pTerminal->get_Direction( &td); // //clean up // pTerminal->Release(); if ( FAILED(hr) ) { DoMessage(_T("ITCallMediaEvent: get_Direction failed")); g_pCall->Disconnect(DC_NORMAL); break; } // // if TD_CAPTURE and we have playback terminal start streaming // if ( TD_CAPTURE == td && NULL != g_pPlayFileTerm) { ITMediaControl* pITMC = NULL; hr = g_pPlayFileTerm->QueryInterface(IID_ITMediaControl, (void**)&pITMC); // // get ITMediaControl so we can start streaming // if(FAILED(hr)) { DoMessage(_T("ITCallMediaEvent: g_pPlayFileTerm QI for ITMediaControl failed")); g_pCall->Disconnect(DC_NORMAL); break; } // // Start streaming // hr = pITMC->Start(); pITMC->Release(); if(SUCCEEDED(hr)) { SetStatusMessage(_T("File Playback Terminal started ")); } else { DoMessage(_T("ITCallMediaEvent: ITMediaControl::Start() failed")); g_pCall->Disconnect(DC_NORMAL); } } break; } default: break; } // // clean up // pCallMediaEvent->Release(); return hr; }
/////////////////////////////////////////////////////////////////// // DoCallNotification // // TE_CALLNOTIFICATION means that the application is being notified // of a new call. // // Note that we don't answer to call at this point. The application // should wait for a CS_OFFERING CallState message before answering // the call. // /////////////////////////////////////////////////////////////////// HRESULT DoCallNotification( IN IDispatch * pEvent) { ITCallNotificationEvent * pNotify = NULL; HRESULT hr = pEvent->QueryInterface( IID_ITCallNotificationEvent, (void **)&pNotify ); if (FAILED(hr)) { DoMessage( _T("Incoming call, but failed to get the interface")); return hr; } CALL_PRIVILEGE cp = CP_MONITOR; ITCallInfo * pCall = NULL; // // get the call // hr = pNotify->get_Call( &pCall ); // // release the event object // pNotify->Release(); if(FAILED(hr)) { DoMessage( _T("Incoming call, but failed to get the call")); return hr; } // // check to see if we own the call // hr = pCall->get_Privilege( &cp ); if(FAILED(hr)) { pCall->Release(); DoMessage( _T("Incoming call, but failed to get_Privilege")); return hr; } if ( CP_OWNER != cp ) { // // just ignore it if we don't own it // pCall->Release(); return hr; } // //check if we already have a call - if yes reject it // if(NULL != g_pCall) { ITBasicCallControl* pITBCC = NULL; hr = pCall->QueryInterface( IID_ITBasicCallControl, (void**)&pITBCC ); pCall->Release(); // //sanity check // if(SUCCEEDED(hr)) { // //disconnect - we'll handle the other events from this call later // pITBCC->Disconnect(DC_REJECTED); pITBCC->Release(); } return hr; } // //get the call if do not have already one // hr = pCall->QueryInterface( IID_ITBasicCallControl, (void**)&g_pCall ); pCall->Release(); if(FAILED(hr)) { DoMessage( _T("Incoming call, but failed to QI ITBasicCallControl")); } else { // // update UI // SetStatusMessage(_T("Incoming Owner Call")); } // //clean up // return hr; }
/////////////////////////////////////////////////////////////////// // CreateAndSelectFileRecordTerminal // // Creates FileRecording terminal, add the audio track, put_FileName // select track on the stream // /////////////////////////////////////////////////////////////////// HRESULT CreateAndSelectFileRecordTerminal() { // // we should already have the call // if (NULL == g_pCall) { DoMessage( _T("CreateAndSelectFileRecordTerminal: we do not have a call")); return E_UNEXPECTED; } // // get the ITStreamControl interface for this call // ITStreamControl* pStreamControl = NULL; HRESULT hr = g_pCall->QueryInterface( IID_ITStreamControl, (void**)&pStreamControl ); if (FAILED(hr)) { DoMessage( _T("CreateAndSelectFileRecordTerminal: QI for ITStreamControl failed")); return E_FAIL; } // // make sure the record terminal was released // if(NULL != g_pRecordFileTerm) { g_pRecordFileTerm->Release(); g_pRecordFileTerm = NULL; } // // QI for ITBasicCallControl2 - prepare to request the terminal // ITBasicCallControl2* pITBCC2 = NULL; hr = g_pCall->QueryInterface( IID_ITBasicCallControl2, (void**)&pITBCC2 ); if(FAILED(hr)) { pStreamControl->Release(); DoMessage( _T("CreateAndSelectFileRecordTerminal: QI for ITBasicCallControl2 failed")); return hr; } // // get the BSTR CLSID used for ReqestTerminal // BSTR bstrCLSID = NULL; hr = StringFromCLSID(CLSID_FileRecordingTerminal, &bstrCLSID); if(FAILED(hr)) { pITBCC2->Release(); pStreamControl->Release(); DoMessage( _T("CreateAndSelectFileRecordTerminal: StringFromCLSID failed")); return hr; } // // request the record terminal - use the right direction and media type // hr = pITBCC2->RequestTerminal(bstrCLSID, TAPIMEDIATYPE_AUDIO, TD_RENDER, &g_pRecordFileTerm); // //clean up // ::CoTaskMemFree(bstrCLSID); pITBCC2->Release(); if(FAILED(hr)) { pStreamControl->Release(); DoMessage( _T("CreateAndSelectFileRecordTerminal: RequestTerminal failed")); return hr; } // // get to the ITMediaRecord interface so we can put_FileName // we can NOT select before put_FileName // ITMediaRecord* pITMediaRec = NULL; hr = g_pRecordFileTerm->QueryInterface( IID_ITMediaRecord, (void**)&pITMediaRec ); if(FAILED(hr)) { pStreamControl->Release(); DoMessage( _T("CreateAndSelectFileRecordTerminal: QI ITMediaRecord failed")); return hr; } // // we will have a file for each message // WCHAR wchFileName[MAX_PATH+1] = {0}; _snwprintf_s(wchFileName, MAX_PATH, _T("%s%ld%s"), REC_FILENAME, g_dwMessages, REC_FILEEXT); wchFileName[MAX_PATH] = 0; BSTR bstrFileName = ::SysAllocString(wchFileName); if(NULL == bstrFileName) { pStreamControl->Release(); DoMessage( _T("CreateAndSelectFileRecordTerminal: SysAllocString failed")); return E_OUTOFMEMORY; } // // put_FileName // hr = pITMediaRec->put_FileName(bstrFileName); // //clean up // ::SysFreeString(bstrFileName); pITMediaRec->Release(); if(FAILED(hr)) { pStreamControl->Release(); DoMessage( _T("CreateAndSelectFileRecordTerminal: put_FileName failed")); return hr; } // // get to the ITMultiTrackTerminal interface so we can create tracks // ITMultiTrackTerminal* pMTRecTerminal = NULL; hr = g_pRecordFileTerm->QueryInterface( IID_ITMultiTrackTerminal, (void**)&pMTRecTerminal ); if(FAILED(hr)) { pStreamControl->Release(); DoMessage( _T("CreateAndSelectFileRecordTerminal: QI IID_ITMultiTrackTerminal failed")); return hr; } // // enumerate the streams on the call // IEnumStream* pEnumStreams = NULL; hr = pStreamControl->EnumerateStreams(&pEnumStreams); pStreamControl->Release(); if (FAILED(hr)) { pMTRecTerminal->Release(); DoMessage( _T("CreateAndSelectFileRecordTerminal: EnumerateStreams failed")); return hr; } // // only do audio for now // long lMediaTypes = TAPIMEDIATYPE_AUDIO; // // walk through the list of streams on the call // create what we need to // ITStream* pStream = NULL; while (S_OK == pEnumStreams->Next(1, &pStream, NULL)) { if ( (S_OK==CheckStreamMT(pStream,lMediaTypes)) && (S_OK==CheckStreamDir(pStream,TD_RENDER))) { // // if we have a recording terminal, attempt to create a track terminal // ITTerminal* pRecordingTrack = NULL; // //check stream for media type - when we check we have an & // long lStreamMediaType=0; hr = pStream->get_MediaType(&lStreamMediaType); if (FAILED(hr)) { pStream->Release(); pStream=NULL; continue; } // // create track terminal // hr = pMTRecTerminal->CreateTrackTerminal(lStreamMediaType, TD_RENDER, &pRecordingTrack); if (FAILED(hr)) { pStream->Release(); pStream=NULL; // //will fail at the end anyway - lMediaTypes!=0 - so break here // break; } // //select it on stream // hr = pStream->SelectTerminal(pRecordingTrack); // //clean up // pStream->Release(); pStream=NULL; pRecordingTrack->Release(); pRecordingTrack=NULL; if (FAILED(hr)) { // //will fail at the end anyway - lMediaTypes!=0 - so break here // break; } lMediaTypes^=lStreamMediaType; if(lMediaTypes==0) { // //we selected terminals for all media types we needed, we're done // break; } } // // clean up // if(pStream!=NULL) { pStream->Release(); pStream = NULL; } } // while (enumerating streams on the call) // //clean up // pMTRecTerminal->Release(); pEnumStreams->Release(); // //check if we were able to select for all media types // if (lMediaTypes==0) { return S_OK; } else { DoMessage( _T("CreateAndSelectFileRecordTerminal: no streams available")); return E_FAIL; } }
/********************************************************** * COperator::InitializeTapi * *---------------------------* * Description: * Various TAPI initializations * Return: * S_OK iff TAPI initialized successfully * Return values of failed TAPI initialization * functions ***********************************************************/ HRESULT COperator::InitializeTapi() { // Cocreate the TAPI object HRESULT hr = CoCreateInstance( CLSID_TAPI, NULL, CLSCTX_INPROC_SERVER, IID_ITTAPI, (LPVOID *)&m_pTapi ); if ( FAILED(hr) ) { DoMessage(L"CoCreateInstance on TAPI failed"); return hr; } // call ITTAPI::Initialize(). this must be called before // any other tapi functions are called. hr = m_pTapi->Initialize(); if ( FAILED(hr) ) { DoMessage(L"TAPI failed to initialize"); m_pTapi->Release(); m_pTapi = NULL; return hr; } // Create our own event notification object and register it // See callnot.h and callnot.cpp m_pTAPIEventNotification = new CTAPIEventNotification; if ( NULL == m_pTAPIEventNotification ) { return E_OUTOFMEMORY; } hr = m_pTAPIEventNotification->Initialize(); if ( SUCCEEDED( hr ) ) { hr = RegisterTapiEventInterface(); } // Set the Event filter to only give us only the events we process if ( SUCCEEDED( hr ) ) { hr = m_pTapi->put_EventFilter(TE_CALLNOTIFICATION | TE_CALLSTATE); } if ( FAILED( hr ) ) { DoMessage( L"Could not set up TAPI event notifications" ); return hr; } // Find all address objects that we will use to listen for calls on hr = ListenOnAddresses(); if ( FAILED(hr) ) { DoMessage(L"Could not find any addresses to listen on"); m_pTapi->Release(); m_pTapi = NULL; return hr; } return S_OK; } /* COperator::InitializeTapi */
void KDialogP::ShowPopup(PopupType type,HUSHORT uAutoHideTimer) { if( NULL != m_pTxt_Popup_Cover ) { if( !m_pTxt_Popup_Cover->IsShow() ) { m_pTxt_Popup_Cover->SetShow(true); } } if( NULL != m_pGrp_Popup ) { if( !m_pGrp_Popup->IsShow() ) { m_pGrp_Popup->SetShow(true); } } switch( type ) { case PT_OK: // OK 按钮对话框 { if( NULL != m_pBtn_OK ) { if( !m_pBtn_OK->IsShow() ) { m_pBtn_OK->SetShow(true); } m_pBtn_OK->MoveTo(263+80,262); } if( NULL != m_pBtn_CANCEL ) { if( m_pBtn_CANCEL->IsShow() ) { m_pBtn_CANCEL->SetShow(false); } } } break; case PT_OKCANCEL: // OK CANCEL 对话框 { if( NULL != m_pBtn_OK ) { if( !m_pBtn_OK->IsShow() ) { m_pBtn_OK->SetShow(true); } m_pBtn_OK->MoveTo(263,262); } if( NULL != m_pBtn_CANCEL ) { if( !m_pBtn_CANCEL->IsShow() ) { m_pBtn_CANCEL->SetShow(true); } m_pBtn_CANCEL->MoveTo(423,262); } } break; default: { if( NULL != m_pBtn_OK ) { if( m_pBtn_OK->IsShow() ) { m_pBtn_OK->SetShow(false); } } if( NULL != m_pBtn_CANCEL ) { if( m_pBtn_CANCEL->IsShow() ) { m_pBtn_CANCEL->SetShow(false); } } } break; } if( uAutoHideTimer > 0 ) { m_ctAutoHidePopup.SetTime(uAutoHideTimer); m_ctAutoHidePopup.StartTimer(); } else { if( m_ctAutoHidePopup.IsActive() ) { m_ctAutoHidePopup.StopTimer(); m_ctAutoHidePopup.SetTime(uAutoHideTimer); } } m_uPopupType = type; // POPUP 出来时如果鼠标在某个按钮的位置处于按下状况就必须要先释放掉 HMessage msg; msg.wParam = 0; msg.lParam = -1; msg.msgtype = KMSG_LBBUTTONUP; DoMessage(&msg); }
HRESULT OnTapiEvent( TAPI_EVENT TapiEvent, IDispatch * pEvent ) { HRESULT hr; switch ( TapiEvent ) { case TE_CALLNOTIFICATION: { // // TE_CALLNOTIFICATION means that the application is being notified // of a new call. // // Note that we don't answer to call at this point. The application // should wait for a CS_OFFERING CallState message before answering // the call. // ITCallNotificationEvent * pNotify; hr = pEvent->QueryInterface( IID_ITCallNotificationEvent, (void **)&pNotify ); if (S_OK != hr) { DoMessage( L"Incoming call, but failed to get the interface"); } else { CALL_PRIVILEGE cp; ITCallInfo * pCall; // // get the call // hr = pNotify->get_Call( &pCall ); pNotify->Release(); if ( SUCCEEDED(hr) ) { // // check to see if we own the call // hr = pCall->get_Privilege( &cp ); if ( FAILED(hr) || (CP_OWNER != cp) ) { // // just ignore it if we don't own it // pCall->Release(); pEvent->Release(); // we addrefed it CTAPIEventNotification::Event() return S_OK; } // // Get the ITBasicCallControl interface // // // If we're already in a call, disconnect the new call. Otherwise, // save it in our global variable. // ITBasicCallControl * pCallControl; hr = pCall->QueryInterface( IID_ITBasicCallControl, (void**)&pCallControl ); pCall->Release(); if ( SUCCEEDED(hr) ) { if (gpCall == NULL) { gpCall = pCallControl; // // update UI // EnableButton( IDC_ANSWER ); DisableButton( IDC_DISCONNECT ); SetStatusMessage(L"Incoming Owner Call"); } else { // // Reject this call since we're already in a call // hr = pCallControl->Disconnect(DC_REJECTED); pCallControl->Release(); if (FAILED(hr)) { break; } } } } } break; } case TE_CALLSTATE: { // TE_CALLSTATE is a call state event. pEvent is // an ITCallStateEvent CALL_STATE cs; ITCallStateEvent * pCallStateEvent; ITCallInfo * pCall; ITBasicCallControl * pCallControl; // Get the interface hr = pEvent->QueryInterface( IID_ITCallStateEvent, (void **)&pCallStateEvent ); if ( FAILED(hr) ) { break; } // get the CallInfo interface hr = pCallStateEvent->get_Call( &pCall ); if ( FAILED(hr) ) { pCallStateEvent->Release(); break; } //get the ITBasicCallControl interface and compare it to our existing call hr = pCall->QueryInterface( IID_ITBasicCallControl,(void**)&pCallControl ); pCall->Release(); if (FAILED(hr)) { pCallStateEvent->Release(); break; } //ignore call state events for other calls if (pCallControl != gpCall) { pCallControl->Release(); pCallStateEvent->Release(); break; } pCallControl->Release(); // // This is a call state event for our call // // get the CallState that we are being notified of. hr = pCallStateEvent->get_State( &cs ); // Release the interface pCallStateEvent->Release(); if ( FAILED(hr) ) { break; } // if it's offering, update our UI if (CS_OFFERING == cs) { if (gfAutoAnswer) { PostMessage(ghDlg, WM_COMMAND, IDC_ANSWER, 0); } else { SetStatusMessage(L"Click the Answer button"); } } else if (CS_DISCONNECTED == cs) { PostMessage(ghDlg, WM_COMMAND, IDC_DISCONNECTED, 0); } else if (CS_CONNECTED == cs) { // nothing to do -- we handle connection synchronously } break; } case TE_CALLMEDIA: { // TE_CALLMEDIA is a media event. pEvent is // an ITCallMediaEvent CALL_MEDIA_EVENT cme; ITCallMediaEvent * pCallMediaEvent; // Get the interface hr = pEvent->QueryInterface( IID_ITCallMediaEvent, (void **)&pCallMediaEvent ); if ( FAILED(hr) ) { break; } // get the CALL_MEDIA_EVENT that we are being notified of. hr = pCallMediaEvent->get_Event( &cme ); if ( SUCCEEDED(hr) ) { switch ( cme ) { case CME_STREAM_NOT_USED: case CME_STREAM_INACTIVE: case CME_NEW_STREAM: break; case CME_STREAM_FAIL: DoMessage( L"Call media event: stream failed"); break; case CME_TERMINAL_FAIL: DoMessage( L"Call media event: terminal failed"); break; case CME_STREAM_ACTIVE: { // // Find out if this stream has a video render terminal. If not, // we don't need to do anything with this stream. Also note // if this is the video capture stream or the video render // stream. // ITTerminal * pTerminal; BOOL fRenderStream; hr = GetVideoRenderTerminalFromStreamEvent( pCallMediaEvent, &pTerminal, &fRenderStream ); if ( SUCCEEDED(hr) ) { // Get the video window interface for the terminal IVideoWindow *pVideoWindow = NULL; hr = pTerminal->QueryInterface( IID_IVideoWindow, (void**)&pVideoWindow ); pTerminal->Release(); if ( SUCCEEDED(hr) ) { // Put this window in our dialog HostWindow(pVideoWindow, fRenderStream); pVideoWindow->Release(); } } break; } default: break; } } // We no longer need this interface. pCallMediaEvent->Release(); break; } default: break; } pEvent->Release(); // we addrefed it CTAPIEventNotification::Event() return S_OK; }
/********************************************************** * COperator::OnTapiEvent * *------------------------* * Description: * This is the real TAPI event handler, called on our * UI thread upon receipt of the WM_PRIVATETAPIEVENT * message. * Return: * S_OK ************************************************************/ HRESULT COperator::OnTapiEvent( TAPI_EVENT TapiEvent, IDispatch * pEvent ) { HRESULT hr; switch ( TapiEvent ) { case TE_CALLNOTIFICATION: { // TE_CALLNOTIFICATION means that the application is being notified // of a new call. // // Note that we don't answer to call at this point. The application // should wait for a CS_OFFERING CallState message before answering // the call. // ITCallNotificationEvent * pNotify; hr = pEvent->QueryInterface( IID_ITCallNotificationEvent, (void **)&pNotify ); if (S_OK != hr) { DoMessage( L"Incoming call, but failed to get the interface"); } else { CALL_PRIVILEGE cp; ITCallInfo * pCall; // Get the call hr = pNotify->get_Call( &pCall ); pNotify->Release(); if ( SUCCEEDED(hr) ) { // Check to see if we own the call hr = pCall->get_Privilege( &cp ); if ( FAILED(hr) || (CP_OWNER != cp) ) { // Just ignore it if we don't own it pCall->Release(); pEvent->Release(); // We addrefed it CTAPIEventNotification::Event() return S_OK; } // Get the ITBasicCallControl interface and save it in our // member variable. hr = pCall->QueryInterface( IID_ITBasicCallControl, (void**)&m_pCall ); pCall->Release(); if ( SUCCEEDED(hr) ) { // Update UI ::EnableWindow( ::GetDlgItem( m_hDlg, IDC_ANSWER ), TRUE ); SetStatusMessage(L"Incoming Owner Call"); } } } break; } case TE_CALLSTATE: { // TE_CALLSTATE is a call state event. pEvent is // an ITCallStateEvent // Get the interface ITCallStateEvent * pCallStateEvent; hr = pEvent->QueryInterface( IID_ITCallStateEvent, (void **)&pCallStateEvent ); if ( FAILED(hr) ) { break; } // Get the CallState that we are being notified of. CALL_STATE cs; hr = pCallStateEvent->get_State( &cs ); pCallStateEvent->Release(); if ( FAILED(hr) ) { break; } // If it's offering to be answered, update our UI if (CS_OFFERING == cs) { if (m_fAutoAnswer) { ::PostMessage(m_hDlg, WM_COMMAND, IDC_ANSWER, 0); } else { SetStatusMessage(L"Click the Answer button"); } } else if (CS_DISCONNECTED == cs) { ::PostMessage(m_hDlg, WM_COMMAND, IDC_DISCONNECTED, 0); } else if (CS_CONNECTED == cs) { // Nothing to do -- we handle connection synchronously } break; } default: break; } pEvent->Release(); // We addrefed it CTAPIEventNotification::Event() return S_OK; }
/////////////////////////////////////////////////////////////////// // DoFileEvent // // // TE_FILETERMINAL is a file terminal event. pEvent is an ITFileTerminalEvent // // /////////////////////////////////////////////////////////////////// HRESULT DoFileEvent( IN IDispatch * pEvent) { // // check if we still have a call // if(NULL == g_pCall) { return E_UNEXPECTED; } ITFileTerminalEvent* pITFTEvent = NULL; HRESULT hr = pEvent->QueryInterface( IID_ITFileTerminalEvent, reinterpret_cast<void **>(&pITFTEvent) ); if (FAILED(hr)) { // // fatal error - can not continue - disconnect the call // DoMessage( _T("ITFileTerminalEvent, but failed to get the interface")); g_pCall->Disconnect(DC_NORMAL); return hr; } // // get the state - we'll make some decision based on this // TERMINAL_MEDIA_STATE ftState=TMS_ACTIVE; hr = pITFTEvent->get_State(&ftState); if(FAILED(hr)) { // // fatal error - can not continue - disconnect the call // pITFTEvent->Release(); DoMessage( _T("ITFileTerminalEvent, but failed to get_State")); g_pCall->Disconnect(DC_NORMAL); return hr; } // // we are interesred in TMS_IDLE because we will unselect playback and // select recording // if(ftState != TMS_IDLE) { pITFTEvent->Release(); return hr; } // // get the terminal // ITTerminal *pTerminal = NULL; hr = pITFTEvent->get_Terminal(&pTerminal); // // do not need this anymore // pITFTEvent->Release(); if(FAILED(hr)) { // // fatal error - can not continue - disconnect the call // DoMessage( _T("ITFileTerminalEvent, but failed to get_Terminal")); g_pCall->Disconnect(DC_NORMAL); return hr; } TERMINAL_DIRECTION td; hr = pTerminal->get_Direction( &td); pTerminal->Release(); if(FAILED(hr)) { // // fatal error - can not continue - disconnect the call // DoMessage( _T("ITFileTerminalEvent, but failed to get_Direction")); g_pCall->Disconnect(DC_NORMAL); return hr; } if((td == TD_CAPTURE) && (NULL != g_pPlayFileTerm)) { // // unselect playback - it is done - we reached the end or an error // ITBasicCallControl2 *pITBCC2 = NULL; hr = g_pCall->QueryInterface(IID_ITBasicCallControl2, (void**)&pITBCC2); if(FAILED(hr)) { // // fatal error - can not continue - disconnect the call // DoMessage( _T("ITFileTerminalEvent, but failed to QI for ITBasicCallControl2")); g_pCall->Disconnect(DC_NORMAL); return hr; } // // use ITBasicCallControl2 methods - much easier than // enumerate stream, terminals, etc // hr = pITBCC2->UnselectTerminalOnCall(g_pPlayFileTerm); g_pPlayFileTerm->Release(); g_pPlayFileTerm = NULL; pITBCC2->Release(); if(FAILED(hr)) { // // fatal error - can not continue - disconnect the call // DoMessage( _T("ITFileTerminalEvent, but failed to ITBasicCallControl2::UnselectTerminalOnCall")); g_pCall->Disconnect(DC_NORMAL); return hr; } // // select record - do not use automatic selection // we'll see how to use ITMultiTrackTerminal methods // hr = CreateAndSelectFileRecordTerminal(); if(FAILED(hr)) { // // fatal error - can not continue - disconnect the call // g_pCall->Disconnect(DC_NORMAL); SetStatusMessage(_T("CreateAndSelectFileRecordTerminal failed")); return hr; } // // get ITMediaControl interface - we need to call Start // ITMediaControl* pITMC = NULL; hr = g_pRecordFileTerm->QueryInterface(IID_ITMediaControl, (void**)&pITMC); if(FAILED(hr)) { // // fatal error - can not continue - disconnect the call // DoMessage( _T("ITFileTerminalEvent, but failed to QI ITMediaControl")); g_pCall->Disconnect(DC_NORMAL); return hr; } hr = pITMC->Start(); pITMC->Release(); if(FAILED(hr)) { // // fatal error - can not continue - disconnect the call // DoMessage( _T("ITFileTerminalEvent, but ITMediaControl::Start")); g_pCall->Disconnect(DC_NORMAL); return hr; } SetStatusMessage(_T("File Record Terminal started ")); // // will stop recording after one minute // SetTimer(g_hDlg, TIMER_ID, MAX_REC_TIME, NULL); g_dwMessages++; } return hr; }
DoMail () /* * Process mail into QWK packet */ { struct mail_ent *mailp; struct conf_ent *cp; /* No mail in summary mode */ if (sum_mode) return (0); /* Open the mail spool */ if (NULL == (mail_fd = fopen (mail_file, "rb"))) { fprintf (stderr, "%s: can't open %s\n", progname, mail_file); perror (progname); return (0); } /* Define the mail "conference" */ cp = NewConference (MAIL_CONF_NAME, conf_cnt); /* Construct the mail linked list */ MakeMailList (); /* Open ZipNews mail file */ if (zip_mode && (mail_list != NULL)) OpenZipMail(); /* Walk through all the messages */ mailp = mail_list; while (mailp != NULL) { cp->count++; if (slnp_mode) { SLNPMessage (mailp); } else if (zip_mode) { ZipMessage (mailp); } else { DoMessage (mailp); } mailp = mailp->next; } fclose (mail_fd); if (!slnp_mode && !zip_mode) fclose (ndx_fd); if (slnp_mode) fclose (msg_fd); if (zip_mode && (mail_list != NULL)) fclose (mai_fd); /* Now empty the mail box */ if (!read_only) { if (NULL == (mail_fd = fopen (mail_file, "wb"))) { fprintf (stderr, "%s: can't write %s\n", progname, mail_file); } else { fclose (mail_fd); } } return (1); }
/********************************************************** * COperator::InitializeSapi * *---------------------------* * Description: * Various SAPI initializations. * Return: * S_OK if SAPI initialized successfully * Return values of failed SAPI initialization * functions ***********************************************************/ HRESULT COperator::InitializeSapi() { // Create a voice for speaking on this machine HRESULT hr = m_cpLocalVoice.CoCreateInstance( CLSID_SpVoice ); if ( FAILED( hr ) ) { DoMessage( L"Could not create a TTS voice on the local machine" ); return hr; } // Create a reco engine for recognizing speech over the phone // This is an inproc recognizer since it will likely be // using a format other than the default hr = m_cpIncomingRecognizer.CoCreateInstance( CLSID_SpInprocRecognizer ); if ( FAILED(hr) ) { DoMessage(L"CoCreateInstance on inproc reco engine failed"); return hr; } // Create a reco context for this engine hr = m_cpIncomingRecognizer->CreateRecoContext( &m_cpIncomingRecoCtxt ); if ( FAILED(hr) ) { DoMessage(L"Could not create recognition context"); return hr; } // Set interest only in PHRASE_START, RECOGNITION, FALSE_RECOGNITION const ULONGLONG ullInterest = SPFEI(SPEI_PHRASE_START) | SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_FALSE_RECOGNITION); hr = m_cpIncomingRecoCtxt->SetInterest( ullInterest, ullInterest ); if ( FAILED(hr) ) { DoMessage(L"Could not set interest in SAPI events"); return hr; } // Retain recognized audio hr = m_cpIncomingRecoCtxt->SetAudioOptions( SPAO_RETAIN_AUDIO, NULL, NULL ); if ( FAILED(hr) ) { DoMessage(L"Could not set audio options to retain recognized audio"); return hr; } // Create a dictation grammar and load it hr = m_cpIncomingRecoCtxt->CreateGrammar( 0, &m_cpDictGrammar ); if ( FAILED(hr) ) { DoMessage(L"Could not create dictation grammar"); return hr; } hr = m_cpDictGrammar->LoadDictation( NULL, SPLO_STATIC ); if ( FAILED(hr) ) { DoMessage(L"Could not load dictation"); return hr; } // Create a voice for talking on the phone. hr = m_cpIncomingRecoCtxt->GetVoice( &m_cpOutgoingVoice ); if ( FAILED(hr) ) { DoMessage(L"Could not create a TTS voice for speaking over the phone"); return hr; } return S_OK; } /* COperator::InitializeSapi */