Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
5.6 KiB

  1. // RecoSleep.cpp : implement "Go to Sleep" and "Wakeup" commands.
  2. #include "private.h"
  3. #include "globals.h"
  4. #include "RecoSleep.h"
  5. #include "mui.h"
  6. #include "ids.h"
  7. #include "cicspres.h"
  8. CRecoSleepClass::CRecoSleepClass(CSpTask *pSpTask)
  9. {
  10. Assert(pSpTask);
  11. m_pSpTask = pSpTask;
  12. m_pSpTask->AddRef( );
  13. StringCchCopyW(m_wszRule, ARRAYSIZE(m_wszRule), L"SleepRule");
  14. m_wszSleep[0] = L'\0';
  15. m_wszWakeup[0] = L'\0';
  16. m_fSleeping = FALSE;
  17. m_Initialized = FALSE;
  18. }
  19. CRecoSleepClass::~CRecoSleepClass( )
  20. {
  21. if ( m_cpRecoContext )
  22. m_cpRecoContext->SetNotifySink(NULL);
  23. SafeRelease(m_pSpTask);
  24. }
  25. HRESULT CRecoSleepClass::InitRecoSleepClass( )
  26. {
  27. HRESULT hr = S_OK;
  28. if ( m_Initialized )
  29. return hr;
  30. Assert(m_pSpTask);
  31. // Get the same Recognizer instance from CSpTask.
  32. hr = m_pSpTask->GetSAPIInterface(IID_ISpRecognizer, (void **)&m_cpRecoEngine);
  33. if ( SUCCEEDED(hr) )
  34. hr = m_cpRecoEngine->CreateRecoContext(&m_cpRecoContext);
  35. // set recognition notification
  36. CComPtr<ISpNotifyTranslator> cpNotify;
  37. hr = cpNotify.CoCreateInstance(CLSID_SpNotifyTranslator);
  38. // set this class instance to notify control object
  39. if (SUCCEEDED(hr))
  40. hr = cpNotify->InitCallback( NotifyCallback, 0, (LPARAM)this );
  41. if (SUCCEEDED(hr))
  42. hr = m_cpRecoContext->SetNotifySink(cpNotify);
  43. // set the events we're interested in
  44. if( SUCCEEDED( hr ) )
  45. {
  46. const ULONGLONG ulInterest = SPFEI(SPEI_RECOGNITION);
  47. hr = m_cpRecoContext->SetInterest(ulInterest, ulInterest);
  48. }
  49. m_fSleeping = FALSE;
  50. CicLoadStringWrapW(g_hInst, IDS_GO_TO_SLEEP, m_wszSleep, ARRAYSIZE(m_wszSleep));
  51. CicLoadStringWrapW(g_hInst, IDS_WAKE_UP, m_wszWakeup, ARRAYSIZE(m_wszWakeup));
  52. hr = m_cpRecoContext->CreateGrammar(GRAM_ID_SLEEP, &m_cpSleepGrammar);
  53. //Create the sleep dynamic rule
  54. if (SUCCEEDED(hr))
  55. hr = m_cpSleepGrammar->GetRule(m_wszRule, 0, SPRAF_TopLevel | SPRAF_Active, TRUE, &m_hSleepRule);
  56. if (SUCCEEDED(hr))
  57. hr = m_cpSleepGrammar->SetRuleState(NULL, NULL, SPRS_INACTIVE);
  58. if (SUCCEEDED(hr))
  59. hr = m_cpSleepGrammar->ClearRule(m_hSleepRule);
  60. if (SUCCEEDED(hr))
  61. hr = m_cpSleepGrammar->AddWordTransition(m_hSleepRule, NULL, m_wszSleep, L" ", SPWT_LEXICAL, 1.0, NULL);
  62. if (SUCCEEDED(hr))
  63. hr = m_cpSleepGrammar->AddWordTransition(m_hSleepRule, NULL, m_wszWakeup, L" ", SPWT_LEXICAL, 1.0, NULL);
  64. if (SUCCEEDED(hr))
  65. hr = m_cpSleepGrammar->Commit(NULL);
  66. if (SUCCEEDED(hr))
  67. hr = m_cpSleepGrammar->SetRuleState(NULL, NULL, SPRS_ACTIVE);
  68. if ( SUCCEEDED(hr) )
  69. m_Initialized = TRUE;
  70. return hr;
  71. }
  72. void CRecoSleepClass::NotifyCallback(WPARAM wParam, LPARAM lParam )
  73. {
  74. CRecoSleepClass *_this = (CRecoSleepClass *)lParam;
  75. CSpEvent event;
  76. if ( !_this->m_cpRecoContext)
  77. return;
  78. while (event.GetFrom(_this->m_cpRecoContext) == S_OK)
  79. {
  80. // We just care about SPEI_RECOGNITION event.
  81. if (event.eEventId == SPEI_RECOGNITION)
  82. {
  83. CComPtr<ISpRecoResult> cpRecoResult = event.RecoResult();
  84. if (cpRecoResult)
  85. {
  86. SPPHRASE *pPhrase = NULL;
  87. if (S_OK == cpRecoResult->GetPhrase(&pPhrase) )
  88. {
  89. _this->ProcessSleepGrammar(pPhrase);
  90. CoTaskMemFree(pPhrase);
  91. }
  92. }
  93. }
  94. }
  95. return;
  96. }
  97. HRESULT CRecoSleepClass::ProcessSleepGrammar( SPPHRASE *pPhrase )
  98. {
  99. HRESULT hr = S_OK;
  100. Assert(pPhrase);
  101. ULONGLONG ullGramId = pPhrase->ullGrammarID;
  102. if ( ullGramId != GRAM_ID_SLEEP )
  103. return hr;
  104. // Check the rule name
  105. if (0 == wcscmp(pPhrase->Rule.pszName, m_wszRule) )
  106. {
  107. ULONG ulStartElem, ulNumElems;
  108. CSpDynamicString dstrCommand;
  109. ulStartElem = pPhrase->Rule.ulFirstElement;
  110. ulNumElems = pPhrase->Rule.ulCountOfElements;
  111. for (ULONG i = ulStartElem; i < ulStartElem + ulNumElems; i++ )
  112. {
  113. if ( pPhrase->pElements[i].pszDisplayText)
  114. {
  115. BYTE bAttr = pPhrase->pElements[i].bDisplayAttributes;
  116. dstrCommand.Append(pPhrase->pElements[i].pszDisplayText);
  117. if ( i < ulStartElem + ulNumElems-1 )
  118. {
  119. if (bAttr & SPAF_ONE_TRAILING_SPACE)
  120. dstrCommand.Append(L" ");
  121. else if (bAttr & SPAF_TWO_TRAILING_SPACES)
  122. dstrCommand.Append(L" ");
  123. }
  124. }
  125. }
  126. if ( dstrCommand )
  127. {
  128. BOOL fProcessed = FALSE;
  129. if ((!wcscmp(dstrCommand, m_wszSleep)) && (!m_fSleeping))
  130. {
  131. hr = m_cpSleepGrammar->SetGrammarState(SPGS_EXCLUSIVE);
  132. m_fSleeping = TRUE;
  133. TraceMsg(TF_ALWAYS, "SetGrammarState to SPGS_EXCLUSIVE, hr=%x", hr);
  134. fProcessed = TRUE;
  135. }
  136. else if ((!wcscmp(dstrCommand, m_wszWakeup)) && (m_fSleeping))
  137. {
  138. hr = m_cpSleepGrammar->SetGrammarState(SPGS_ENABLED);
  139. m_fSleeping = FALSE;
  140. TraceMsg(TF_ALWAYS, "SetGrammarState to SPGS_ENABLED, hr=%x", hr);
  141. fProcessed = TRUE;
  142. }
  143. if ( fProcessed )
  144. m_pSpTask->_ShowCommandOnBalloon(pPhrase);
  145. }
  146. }
  147. return hr;
  148. }