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.

355 lines
10 KiB

  1. //
  2. //
  3. // Sapilayr TIP Key event related functions.
  4. //
  5. //
  6. #include "private.h"
  7. #include "sapilayr.h"
  8. #include "nui.h"
  9. #include "keyevent.h"
  10. #include "cregkey.h"
  11. //
  12. // hot key for TTS Play/Stop.
  13. const KESPRESERVEDKEY g_prekeyList[] =
  14. {
  15. { &GUID_HOTKEY_TTS_PLAY_STOP, { 'S', TF_MOD_WIN }, L"TTS Speech" },
  16. { NULL, { 0, 0}, NULL }
  17. };
  18. KESPRESERVEDKEY g_prekeyList_Mode[] =
  19. {
  20. { &GUID_HOTKEY_MODE_DICTATION, {VK_F11 , 0}, L"Dictation Button" },
  21. { &GUID_HOTKEY_MODE_COMMAND, {VK_F12 , 0}, L"Command Button" },
  22. { NULL, { 0, 0}, NULL }
  23. };
  24. //+---------------------------------------------------------------------------
  25. //
  26. // CSptipKeyEventSink::RegisterEx: Registr the special speech mode buttons.
  27. //
  28. //----------------------------------------------------------------------------
  29. HRESULT CSptipKeyEventSink::_RegisterEx(ITfThreadMgr *ptim, TfClientId tid, const KESPRESERVEDKEY *pprekey)
  30. {
  31. HRESULT hr;
  32. ITfKeystrokeMgr_P *pKeyMgr;
  33. if (FAILED(ptim->QueryInterface(IID_ITfKeystrokeMgr_P, (void **)&pKeyMgr)))
  34. return E_FAIL;
  35. hr = E_FAIL;
  36. while (pprekey->pguid)
  37. {
  38. if (FAILED(pKeyMgr->PreserveKeyEx(tid,
  39. *pprekey->pguid,
  40. &pprekey->tfpk,
  41. pprekey->psz,
  42. wcslen(pprekey->psz),
  43. TF_PKEX_SYSHOTKEY | TF_PKEX_NONEEDDIM)))
  44. goto Exit;
  45. pprekey++;
  46. }
  47. ptim->AddRef();
  48. hr = S_OK;
  49. Exit:
  50. SafeRelease(pKeyMgr);
  51. return hr;
  52. }
  53. HRESULT CSapiIMX::_PreKeyEventCallback(ITfContext *pic, REFGUID rguid, BOOL *pfEaten, void *pv)
  54. {
  55. CSapiIMX *_this = (CSapiIMX *)pv;
  56. CSpeechUIServer *pSpeechUIServer;
  57. BOOL fButtonEnable;
  58. TraceMsg(TF_SPBUTTON, "_PreKeyEventCallback is called");
  59. *pfEaten = FALSE;
  60. if (_this == NULL)
  61. return S_OK;
  62. pSpeechUIServer = _this->GetSpeechUIServer( );
  63. if (!pSpeechUIServer)
  64. return S_OK;
  65. fButtonEnable = pSpeechUIServer->GetTtsButtonStatus( );
  66. if (IsEqualGUID(rguid, GUID_HOTKEY_TTS_PLAY_STOP))
  67. {
  68. if ( fButtonEnable )
  69. {
  70. _this->_HandleEventOnPlayButton( );
  71. *pfEaten = TRUE;
  72. }
  73. }
  74. else if ( IsEqualGUID(rguid, GUID_HOTKEY_MODE_DICTATION) ||
  75. IsEqualGUID(rguid, GUID_HOTKEY_MODE_COMMAND) )
  76. {
  77. if ( _this->_IsModeKeysEnabled( ) )
  78. *pfEaten = TRUE;
  79. else
  80. *pfEaten = FALSE;
  81. }
  82. TraceMsg(TF_SPBUTTON, "_PreKeyEventCallback fEaten=%d", *pfEaten);
  83. return S_OK;
  84. }
  85. //+---------------------------------------------------------------------------
  86. //
  87. // _KeyEventCallback
  88. //
  89. //----------------------------------------------------------------------------
  90. HRESULT CSapiIMX::_KeyEventCallback(UINT uCode, ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten, void *pv)
  91. {
  92. CSapiIMX *pimx;
  93. HRESULT hr = S_OK;
  94. CSapiIMX *_this = (CSapiIMX *)pv;
  95. *pfEaten = FALSE;
  96. Assert(uCode != KES_CODE_FOCUS); // we should never get this callback because we shouldn't take the keyboard focus
  97. if (!(uCode & KES_CODE_KEYDOWN))
  98. return S_OK; // only want key downs
  99. if (pic == NULL) // no focus ic?
  100. return S_OK;
  101. pimx = (CSapiIMX *)pv;
  102. *pfEaten = TRUE;
  103. switch (wParam & 0xFF)
  104. {
  105. case VK_F8:
  106. if (!(uCode & KES_CODE_TEST))
  107. {
  108. CSapiPlayBack *ppb;
  109. if (ppb = new CSapiPlayBack(pimx))
  110. {
  111. CPlayBackEditSession *pes;
  112. if (pes = new CPlayBackEditSession(ppb, pic))
  113. {
  114. pes->_SetEditSessionData(ESCB_PLAYBK_PLAYSNDSELECTION, NULL, 0);
  115. pic->RequestEditSession(_this->_tid, pes, TF_ES_READ | TF_ES_SYNC, &hr);
  116. pes->Release();
  117. }
  118. ppb->Release();
  119. }
  120. }
  121. break;
  122. case VK_ESCAPE:
  123. if (!(uCode & KES_CODE_TEST))
  124. {
  125. if (_this->m_pCSpTask)
  126. hr = _this->m_pCSpTask->_StopInput();
  127. }
  128. *pfEaten = FALSE;
  129. break;
  130. default:
  131. *pfEaten = FALSE;
  132. #ifdef LONGHORN
  133. //
  134. // For english composition scenario, I'm trying to see if this works.
  135. // Note that this is not the final design to support typing while
  136. // composing dictation. m_pMouseSink != NULL only when composition
  137. // is active so I'm overriding it as a flag.
  138. //
  139. if (_this->GetLangID() == 0x0409)
  140. {
  141. if ((BYTE)wParam != VK_LEFT && (BYTE)wParam != VK_RIGHT
  142. && (isprint((BYTE)wParam)
  143. || (VK_OEM_1 <= (BYTE)wParam && (BYTE)wParam < VK_OEM_8))
  144. && _this->m_pMouseSink)
  145. {
  146. WCHAR wc[3];
  147. BYTE keystate[256];
  148. if (GetKeyboardState(keystate))
  149. {
  150. if (ToUnicodeEx(wParam,(UINT)lParam, keystate, wc,
  151. ARRAYSIZE(wc), 0, GetKeyboardLayout(NULL)) > 0)
  152. {
  153. *pfEaten = TRUE; // want this key only if there is
  154. // a printable character
  155. if (!(uCode & KES_CODE_TEST))
  156. {
  157. // we don't handle deadkeys here for now
  158. wc[1] = L'\0';
  159. // call InjectSpelledText() with fOwnerId == TRUE
  160. hr = _this->InjectSpelledText(wc, _this->GetLangID(), TRUE);
  161. }
  162. }
  163. }
  164. }
  165. }
  166. break;
  167. #endif
  168. }
  169. return hr;
  170. }
  171. //
  172. // ITfKeyTraceEventSink method functions.
  173. //
  174. //
  175. STDAPI CSapiIMX::OnKeyTraceUp(WPARAM wParam,LPARAM lParam)
  176. {
  177. // We just check KeyDown, ignore KeyUp event.
  178. // so just return S_OK immediately.
  179. TraceMsg(TF_SPBUTTON, "OnKeyTraceUp is called");
  180. UNREFERENCED_PARAMETER(lParam);
  181. HandleModeKeyEvent( (DWORD)wParam, FALSE);
  182. return S_OK;
  183. }
  184. //
  185. // Take use this method to detect if user is typing
  186. //
  187. // if it is typing, disable dictation rule temporally.
  188. //
  189. STDAPI CSapiIMX::OnKeyTraceDown(WPARAM wParam,LPARAM lParam)
  190. {
  191. BOOL fDictOn;
  192. TraceMsg(TF_SPBUTTON, "OnKeyTraceDown is called, wParam=%x", wParam);
  193. if ( HandleModeKeyEvent((DWORD)wParam, TRUE ))
  194. {
  195. // if the mode key is pressed, don't disable dictation as usual.
  196. return S_OK;
  197. }
  198. fDictOn = (GetOnOff( ) && GetDICTATIONSTAT_DictOnOff( ));
  199. if (fDictOn && !m_ulSimulatedKey && m_pCSpTask &&
  200. S_OK == IsActiveThread()) // Only want this to happen on the active thread which could be the stage.
  201. {
  202. // User is typing.
  203. //
  204. // Temporally disable Dictation if Dictation Mode is ON
  205. //
  206. if ( _NeedDisableDictationWhileTyping( ) )
  207. {
  208. if ( _GetNumCharTyped( ) == 0 )
  209. {
  210. m_pCSpTask->_SetDictRecoCtxtState(FALSE);
  211. m_pCSpTask->_SetRecognizerInterest(0);
  212. m_pCSpTask->_UpdateBalloon(IDS_BALLOON_DICTAT_PAUSED, IDS_BALLOON_TOOLTIP_TYPING);
  213. }
  214. //
  215. // and then start a timer to watch for the end of typing.
  216. //
  217. _SetCharTypeTimer( );
  218. }
  219. }
  220. if ( m_ulSimulatedKey > 0 )
  221. m_ulSimulatedKey --;
  222. return S_OK;
  223. }
  224. // +--------------------------------------------------------------------------
  225. // HandleModeKeySettingChange
  226. //
  227. // When any mode button setting is changed, such as mode button's
  228. // enable/disable status change, virtual keys for dictation and command
  229. // are changed, this function will respond for this change.
  230. //
  231. // ---------------------------------------------------------------------------
  232. void CSapiIMX::HandleModeKeySettingChange(BOOL fSetttingChanged )
  233. {
  234. BOOL fModeKeyEnabled = _IsModeKeysEnabled( );
  235. DWORD dwDictVirtKey = _GetDictationButton( );
  236. DWORD dwCommandVirtKey = _GetCommandButton( );
  237. if ( !fSetttingChanged || !_pkes ) return;
  238. // mode button setting is changed.
  239. // unregister the hotkey first if the keys were registered before.
  240. if ( m_fModeKeyRegistered )
  241. {
  242. _pkes->_Unregister(_tim, _tid, (const KESPRESERVEDKEY *)g_prekeyList_Mode);
  243. m_fModeKeyRegistered = FALSE;
  244. }
  245. // Update the virtual keys in g_prekeyList_Mode
  246. g_prekeyList_Mode[0].tfpk.uVKey = (UINT)dwDictVirtKey;
  247. g_prekeyList_Mode[1].tfpk.uVKey = (UINT)dwCommandVirtKey;
  248. // register hotkeys again based on the mode button enable status setting
  249. if ( fModeKeyEnabled )
  250. {
  251. _pkes->_RegisterEx(_tim, _tid, (const KESPRESERVEDKEY *)g_prekeyList_Mode);
  252. m_fModeKeyRegistered = TRUE;
  253. }
  254. }
  255. // +--------------------------------------------------------------------------
  256. // HandleModeKeyEvent
  257. //
  258. // dwModeKey to indicate which mode key is process.
  259. // fDown to indicate if the button is down or up
  260. //
  261. // Return TRUE means this key is a correct mode key and processed sucessfully
  262. // otherwisze, the keyevent is not handled correctly or not a mode key.
  263. // ---------------------------------------------------------------------------
  264. BOOL CSapiIMX::HandleModeKeyEvent(DWORD dwModeKey, BOOL fDown)
  265. {
  266. BOOL fRet=FALSE;
  267. BOOL fModeKeyEnabled;
  268. DWORD DictVirtKey, CommandVirtKey;
  269. fModeKeyEnabled = _IsModeKeysEnabled( );
  270. DictVirtKey = _GetDictationButton( );
  271. CommandVirtKey = _GetCommandButton( );
  272. if ( fModeKeyEnabled && ((dwModeKey == DictVirtKey) || (dwModeKey == CommandVirtKey)) )
  273. {
  274. if ( !m_pSpButtonControl )
  275. m_pSpButtonControl = new SpButtonControl(this);
  276. if ( m_pSpButtonControl )
  277. {
  278. // GetMessageTime( ) will return the real time when
  279. // KEYDOWN and KEYUP event was generated.
  280. UINT uTimeKey=(UINT)GetMessageTime( );
  281. if ( dwModeKey == DictVirtKey )
  282. m_pSpButtonControl->SetDictationButton(fDown,uTimeKey);
  283. else
  284. m_pSpButtonControl->SetCommandingButton(fDown, uTimeKey);
  285. fRet = TRUE;
  286. }
  287. }
  288. return fRet;
  289. }