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.

897 lines
22 KiB

  1. /*++
  2. Copyright (c) 2001, Microsoft Corporation
  3. Module Name:
  4. wrapper.cpp
  5. Abstract:
  6. This file implements the IME entry.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #include "private.h"
  12. #include "globals.h"
  13. #include "tls.h"
  14. #include "cic.h"
  15. #include "uiwndhd.h"
  16. #include "delay.h"
  17. #include "profile.h"
  18. extern "C" {
  19. DWORD WINAPI ImeConversionList(
  20. HIMC hIMC,
  21. LPCTSTR lpszSrc,
  22. LPCANDIDATELIST lpCandList,
  23. DWORD dwBufLen,
  24. UINT uFlag)
  25. {
  26. DebugMsg(TF_ERROR, TEXT("ImeConversionList. Not support."));
  27. Assert(0);
  28. return 0;
  29. }
  30. BOOL WINAPI ImeConfigure(
  31. HKL hKL, // hKL of this IME
  32. HWND hAppWnd, // the owner window
  33. DWORD dwMode, // mode of dialog
  34. LPVOID lpData) // the data depend on each mode
  35. {
  36. TLS* ptls = TLS::GetTLS();
  37. if (ptls == NULL)
  38. {
  39. DebugMsg(TF_ERROR, TEXT("ImeConfigure. ptls==NULL."));
  40. return FALSE;
  41. }
  42. CicBridge* cic = ptls->GetCicBridge();
  43. if (cic == NULL)
  44. {
  45. DebugMsg(TF_ERROR, TEXT("ImeConfigure. cic==NULL."));
  46. return FALSE;
  47. }
  48. ITfThreadMgr_P* ptim_P = ptls->GetTIM();
  49. if (ptim_P == NULL)
  50. {
  51. DebugMsg(TF_ERROR, TEXT("ImeConfigure. ptim_P==NULL."));
  52. return FALSE;
  53. }
  54. if (dwMode & IME_CONFIG_GENERAL)
  55. {
  56. return cic->ConfigureGeneral(ptls, ptim_P, hKL, hAppWnd) == S_OK ? TRUE : FALSE;
  57. }
  58. else if (dwMode & IME_CONFIG_REGISTERWORD)
  59. {
  60. return cic->ConfigureRegisterWord(ptls, ptim_P, hKL, hAppWnd, (REGISTERWORDW*)lpData) == S_OK ? TRUE : FALSE;
  61. }
  62. else
  63. {
  64. DebugMsg(TF_ERROR, TEXT("ImeConfigure(%x). Not support."), dwMode);
  65. Assert(0);
  66. }
  67. return FALSE;
  68. }
  69. BOOL WINAPI ImeDestroy(
  70. UINT uReserved)
  71. {
  72. TLS* ptls = TLS::ReferenceTLS();
  73. if (ptls == NULL)
  74. {
  75. DebugMsg(TF_ERROR, TEXT("ImeDestroy. ptls==NULL."));
  76. return FALSE;
  77. }
  78. CicBridge* cic = ptls->GetCicBridge();
  79. if (cic == NULL)
  80. {
  81. DebugMsg(TF_ERROR, TEXT("ImeDestroy. cic==NULL."));
  82. return FALSE;
  83. }
  84. ITfThreadMgr_P* ptim_P = ptls->GetTIM();
  85. if (ptim_P == NULL)
  86. {
  87. DebugMsg(TF_ERROR, TEXT("ImeDestroy. ptim_P==NULL."));
  88. return FALSE;
  89. }
  90. if (ptls->GetSystemInfoFlags() & IME_SYSINFO_WINLOGON)
  91. {
  92. DebugMsg(TF_FUNC, TEXT("ImeDestroy. dwSystemInfoFlags=IME_SYSINFO_WINLOGON."));
  93. return TRUE;
  94. }
  95. else
  96. {
  97. HRESULT hr = cic->DeactivateIMMX(ptls, ptim_P);
  98. if (hr == S_OK)
  99. {
  100. return cic->UnInitIMMX(ptls);
  101. }
  102. }
  103. return FALSE;
  104. }
  105. LRESULT WINAPI ImeEscape(
  106. HIMC hIMC,
  107. UINT uSubFunc,
  108. LPVOID lpData)
  109. {
  110. DebugMsg(TF_ERROR, TEXT("ImeEscape. Never called when Cicero unaware support."));
  111. Assert(0);
  112. return FALSE;
  113. }
  114. BOOL WINAPI ImeInquire(
  115. LPIMEINFO lpImeInfo, // IME specific data report to IMM
  116. LPTSTR lpszWndCls, // the class name of UI
  117. DWORD dwSystemInfoFlags)
  118. {
  119. DebugMsg(TF_ERROR, TEXT("ImeInquire. Never called when Cicero unaware support."));
  120. Assert(0);
  121. return FALSE;
  122. }
  123. BOOL WINAPI ImeProcessKey(
  124. HIMC hIMC,
  125. UINT uVirtKey,
  126. LPARAM lParam,
  127. CONST LPBYTE lpbKeyState)
  128. {
  129. TLS* ptls = TLS::GetTLS();
  130. if (ptls == NULL)
  131. {
  132. DebugMsg(TF_ERROR, TEXT("ImeProcessKey. ptls==NULL."));
  133. return FALSE;
  134. }
  135. CicBridge* cic = ptls->GetCicBridge();
  136. if (cic == NULL)
  137. {
  138. DebugMsg(TF_ERROR, TEXT("ImeProcessKey. cic==NULL."));
  139. return FALSE;
  140. }
  141. ITfThreadMgr_P* ptim_P = ptls->GetTIM();
  142. if (ptim_P == NULL)
  143. {
  144. DebugMsg(TF_ERROR, TEXT("ImeProcessKey. ptim_P==NULL."));
  145. return FALSE;
  146. }
  147. if (ptls->IsCTFAware())
  148. {
  149. Interface<ITfDocumentMgr> pdimFocus;
  150. ptim_P->GetFocus(pdimFocus);
  151. if ((ITfDocumentMgr*)pdimFocus)
  152. {
  153. //
  154. // Check if it is our dim or app dim.
  155. // if it is app dim, it is Cicero aware app.
  156. //
  157. //
  158. if (!cic->IsOwnDim((ITfDocumentMgr*)pdimFocus))
  159. return FALSE;
  160. }
  161. DebugMsg(TF_ERROR, TEXT("ImeProcessKey. why IsCTFAware?"));
  162. }
  163. if (ptls->IsAIMMAware())
  164. {
  165. // This is AIMM aware application.
  166. //
  167. // check imc->hWnd is filtered or not.
  168. //
  169. if (MsimtfIsGuidMapEnable(hIMC, NULL))
  170. return FALSE;
  171. DebugMsg(TF_ERROR, TEXT("ImeProcessKey. why IsAIMMAware?"));
  172. }
  173. //
  174. // #476089
  175. //
  176. // MSCTF.DLL handles Alt+VKDBE and pass it to KeyStrokeManager if focus DIM
  177. // is available. So msctfime does not have to handle this.
  178. //
  179. // MSCTF!HandleDBEKeys() in hotkey.cpp checks
  180. // - if it is Japanese layout.
  181. // - if ptim->_GetFocusDocInputMgr() is not NULL.
  182. // - if ALT is down.
  183. //
  184. // Alt+VK_DBE_xxx key comes here even if IME does not have
  185. // IME_PROP_NEED_ALTKEY.
  186. //
  187. if ((HIWORD(lParam) & KF_ALTDOWN) &&
  188. (LOWORD(GetKeyboardLayout(0)) == 0x411))
  189. {
  190. if (IsVKDBEKey(uVirtKey))
  191. return FALSE;
  192. }
  193. return cic->ProcessKey(ptls, ptim_P, hIMC, uVirtKey, lParam, lpbKeyState);
  194. }
  195. BOOL WINAPI CtfImeProcessCicHotkey(
  196. HIMC hIMC,
  197. UINT uVirtKey,
  198. LPARAM lParam)
  199. {
  200. TLS* ptls = TLS::GetTLS();
  201. if (ptls == NULL)
  202. {
  203. DebugMsg(TF_ERROR, TEXT("CtfImeProcessCicHotkey. ptls==NULL."));
  204. return FALSE;
  205. }
  206. Interface<ITfThreadMgr> ptim;
  207. Interface<ITfThreadMgr_P> ptim_P;
  208. HRESULT hr;
  209. //
  210. // ITfThreadMgr is per thread instance.
  211. //
  212. hr = TF_GetThreadMgr(ptim);
  213. if (hr != S_OK)
  214. {
  215. DebugMsg(TF_ERROR, TEXT("CtfImeProcessCicHotkey. TF_GetThreadMgr failed"));
  216. Assert(0); // couldn't create tim!
  217. return FALSE;
  218. }
  219. hr = ptim->QueryInterface(IID_ITfThreadMgr_P, (void **)ptim_P);
  220. if (hr != S_OK)
  221. {
  222. DebugMsg(TF_ERROR, TEXT("CtfImeProcessCicHotkey. IID_ITfThreadMgr_P==NULL"));
  223. Assert(0); // couldn't find ITfThreadMgr_P
  224. return FALSE;
  225. }
  226. if (!CtfImmIsCiceroStartedInThread()) {
  227. DebugMsg(TF_ERROR, TEXT("CicBridge::ProcessCicHotkey. StopImm32HotkeyHandler returns Error."));
  228. return FALSE;
  229. }
  230. BOOL bHandled;
  231. hr = ptim_P->CallImm32HotkeyHanlder((WPARAM)uVirtKey, lParam, &bHandled);
  232. if (FAILED(hr)) {
  233. DebugMsg(TF_ERROR, TEXT("CtfImeProcessCicHotkey. CallImm32HotkeyHandler returns Error."));
  234. return FALSE;
  235. }
  236. return bHandled;
  237. }
  238. BOOL WINAPI ImeSelect(
  239. HIMC hIMC,
  240. BOOL fSelect)
  241. {
  242. DebugMsg(TF_ERROR, TEXT("ImeSelect. Never called when Cicero unaware support."));
  243. Assert(0);
  244. return FALSE;
  245. }
  246. BOOL WINAPI ImeSetActiveContext(
  247. HIMC hIMC,
  248. BOOL fOn)
  249. {
  250. DebugMsg(TF_ERROR, TEXT("ImeSetActiveContext. Never called when Cicero unaware support."));
  251. Assert(0);
  252. return FALSE;
  253. }
  254. BOOL WINAPI ImeSetCompositionString(
  255. HIMC hIMC,
  256. DWORD dwIndex,
  257. LPVOID lpComp,
  258. DWORD dwCompLen,
  259. LPVOID lpRead,
  260. DWORD dwReadLen)
  261. {
  262. TLS* ptls = TLS::GetTLS();
  263. if (ptls == NULL)
  264. {
  265. DebugMsg(TF_ERROR, TEXT("ImeSetCompositionString. ptls==NULL."));
  266. return FALSE;
  267. }
  268. CicBridge* cic = ptls->GetCicBridge();
  269. if (cic == NULL)
  270. {
  271. DebugMsg(TF_ERROR, TEXT("ImeSetCompositionString. cic==NULL."));
  272. return FALSE;
  273. }
  274. ITfThreadMgr_P* ptim_P = ptls->GetTIM();
  275. if (ptim_P == NULL)
  276. {
  277. DebugMsg(TF_ERROR, TEXT("ImeSetCompositionString. ptim_P==NULL."));
  278. return FALSE;
  279. }
  280. return cic->SetCompositionString(ptls, ptim_P, hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
  281. }
  282. UINT WINAPI ImeToAsciiEx(
  283. UINT uVirtKey,
  284. UINT uScanCode,
  285. CONST LPBYTE lpbKeyState,
  286. LPTRANSMSGLIST lpTransBuf,
  287. UINT fuState,
  288. HIMC hIMC)
  289. {
  290. UINT uNum = 0;
  291. HRESULT hr;
  292. TLS* ptls = TLS::GetTLS();
  293. if (ptls == NULL)
  294. {
  295. DebugMsg(TF_ERROR, TEXT("ImeToAsciiEx. ptls==NULL."));
  296. return 0;
  297. }
  298. CicBridge* cic = ptls->GetCicBridge();
  299. if (cic == NULL)
  300. {
  301. DebugMsg(TF_ERROR, TEXT("ImeToAsciiEx. cic==NULL."));
  302. return 0;
  303. }
  304. ITfThreadMgr_P* ptim_P = ptls->GetTIM();
  305. if (ptim_P == NULL)
  306. {
  307. DebugMsg(TF_ERROR, TEXT("ImeToAsciiEx. ptim_P==NULL."));
  308. return 0;
  309. }
  310. hr = cic->ToAsciiEx(ptls, ptim_P, uVirtKey, uScanCode, lpbKeyState, lpTransBuf, fuState, hIMC, &uNum);
  311. if (hr != S_OK)
  312. {
  313. uNum = 0;
  314. }
  315. return uNum;
  316. }
  317. BOOL WINAPI NotifyIME(
  318. HIMC hIMC,
  319. DWORD dwAction,
  320. DWORD dwIndex,
  321. DWORD dwValue)
  322. {
  323. TLS* ptls = TLS::GetTLS();
  324. if (ptls == NULL)
  325. {
  326. DebugMsg(TF_ERROR, TEXT("NotifyIME. ptls==NULL."));
  327. return FALSE;
  328. }
  329. CicBridge* cic = ptls->GetCicBridge();
  330. if (cic == NULL)
  331. {
  332. DebugMsg(TF_ERROR, TEXT("NotifyIME. cic==NULL."));
  333. return FALSE;
  334. }
  335. ITfThreadMgr_P* ptim_P = ptls->GetTIM();
  336. if (ptim_P == NULL)
  337. {
  338. DebugMsg(TF_ERROR, TEXT("NotifyIME. ptim_P==NULL."));
  339. return FALSE;
  340. }
  341. return cic->Notify(ptls, ptim_P, hIMC, dwAction, dwIndex, dwValue) == S_OK ? TRUE : FALSE;
  342. }
  343. BOOL WINAPI ImeRegisterWord(
  344. LPCTSTR lpszReading,
  345. DWORD dwStyle,
  346. LPCTSTR lpszString)
  347. {
  348. DebugMsg(TF_ERROR, TEXT("ImeRegisterWord. Not support."));
  349. Assert(0);
  350. return FALSE;
  351. }
  352. BOOL WINAPI ImeUnregisterWord(
  353. LPCTSTR lpszReading,
  354. DWORD dwStyle,
  355. LPCTSTR lpszString)
  356. {
  357. DebugMsg(TF_ERROR, TEXT("ImeUnregisterWord. Not support."));
  358. Assert(0);
  359. return FALSE;
  360. }
  361. UINT WINAPI ImeGetRegisterWordStyle(
  362. UINT nItem,
  363. LPSTYLEBUF lpStyleBuf)
  364. {
  365. DebugMsg(TF_ERROR, TEXT("ImeGetRegisterWordStyle. Not support."));
  366. Assert(0);
  367. return FALSE;
  368. }
  369. UINT WINAPI ImeEnumRegisterWord(
  370. REGISTERWORDENUMPROC lpfnRegisterWordEnumProc,
  371. LPCTSTR lpszReading,
  372. DWORD dwStyle,
  373. LPCTSTR lpszString,
  374. LPVOID lpData)
  375. {
  376. DebugMsg(TF_ERROR, TEXT("ImeEnumRegisterWord. Not support."));
  377. Assert(0);
  378. return FALSE;
  379. }
  380. LRESULT CALLBACK UIWndProc(
  381. HWND hUIWnd,
  382. UINT uMsg,
  383. WPARAM wParam,
  384. LPARAM lParam)
  385. {
  386. return CIMEUIWindowHandler::ImeUIWndProcWorker(hUIWnd, uMsg, wParam, lParam);
  387. }
  388. //
  389. // Cicero IME extended entry
  390. //
  391. HRESULT WINAPI CtfImeInquireExW(
  392. LPIMEINFO lpImeInfo, // IME specific data report to IMM
  393. LPWSTR lpszWndCls, // the class name of UI
  394. DWORD dwSystemInfoFlags,
  395. HKL hKL)
  396. {
  397. TLS* ptls = TLS::GetTLS();
  398. if (ptls == NULL)
  399. {
  400. DebugMsg(TF_ERROR, TEXT("CtfImeInquireExW. ptls==NULL."));
  401. return E_OUTOFMEMORY;
  402. }
  403. DebugMsg(TF_FUNC, TEXT("CtfImeInquireExW. hKL=%lx, dwSystemInfoFlags=%lx."), hKL, dwSystemInfoFlags);
  404. //
  405. // Bug#524962 - Won't support CUAS in case of unauthorized user.
  406. //
  407. if (!IsInteractiveUserLogon())
  408. {
  409. g_bWinLogon = TRUE;
  410. dwSystemInfoFlags |= IME_SYSINFO_WINLOGON;
  411. }
  412. ptls->SetSystemInfoFlags(dwSystemInfoFlags);
  413. #if 0
  414. //
  415. // Even this is WinLogon process, never return error code to imm32.
  416. // Once imm32 receives error code with some hKL,
  417. // This hKL is marked IMEF_LOADERROR then all desktop doesn't load this IME.
  418. //
  419. if (ptls->GetSystemInfoFlags() & IME_SYSINFO_WINLOGON)
  420. {
  421. return E_NOTIMPL;
  422. }
  423. #endif
  424. return Inquire(lpImeInfo, lpszWndCls, dwSystemInfoFlags, hKL);
  425. }
  426. HRESULT WINAPI CtfImeCreateThreadMgr()
  427. {
  428. TLS* ptls = TLS::GetTLS();
  429. if (ptls == NULL)
  430. {
  431. DebugMsg(TF_ERROR, TEXT("CtfImeCreateThreadMgr. ptls==NULL."));
  432. return E_OUTOFMEMORY;
  433. }
  434. CicBridge* cic = ptls->GetCicBridge();
  435. if (cic == NULL)
  436. {
  437. cic = new CicBridge;
  438. if (cic == NULL)
  439. {
  440. DebugMsg(TF_ERROR, TEXT("CtfImeCreateThreadMgr. cic==NULL."));
  441. return E_OUTOFMEMORY;
  442. }
  443. ptls->SetCicBridge(cic);
  444. }
  445. HRESULT hr;
  446. if (g_bWinLogon || (ptls->GetSystemInfoFlags() & IME_SYSINFO_WINLOGON))
  447. {
  448. DebugMsg(TF_FUNC, TEXT("CtfImeCreateThreadMgr. dwSystemInfoFlags=IME_SYSINFO_WINLOGON."));
  449. hr = S_OK;
  450. }
  451. else
  452. {
  453. hr = cic->InitIMMX(ptls);
  454. if (SUCCEEDED(hr))
  455. {
  456. ITfThreadMgr_P* ptim_P = ptls->GetTIM();
  457. if (ptim_P == NULL)
  458. {
  459. DebugMsg(TF_ERROR, TEXT("CtfImeCreateThreadMgr. ptim_P==NULL."));
  460. return E_OUTOFMEMORY;
  461. }
  462. hr = cic->ActivateIMMX(ptls, ptim_P);
  463. if (FAILED(hr))
  464. {
  465. DebugMsg(TF_ERROR, TEXT("CtfImeCreateThreadMgr. cic->ActivateIMMX==NULL."));
  466. cic->UnInitIMMX(ptls);
  467. }
  468. }
  469. }
  470. return hr;
  471. }
  472. HRESULT WINAPI CtfImeDestroyThreadMgr()
  473. {
  474. TLS* ptls = TLS::ReferenceTLS(); // Should not allocate TLS. ie. TLS::GetTLS
  475. // DllMain -> ImeDestroy -> DeactivateIMMX -> Deactivate
  476. if (ptls == NULL)
  477. {
  478. DebugMsg(TF_ERROR, TEXT("CtfImeDestroyThreadMgr. ptls==NULL."));
  479. return E_OUTOFMEMORY;
  480. }
  481. CicBridge* cic = ptls->GetCicBridge();
  482. if (cic == NULL)
  483. {
  484. cic = new CicBridge;
  485. if (cic == NULL)
  486. {
  487. DebugMsg(TF_ERROR, TEXT("CtfImeDestroyThreadMgr. cic==NULL."));
  488. return E_OUTOFMEMORY;
  489. }
  490. ptls->SetCicBridge(cic);
  491. }
  492. ITfThreadMgr_P* ptim_P = ptls->GetTIM();
  493. if (ptim_P == NULL)
  494. {
  495. DebugMsg(TF_ERROR, TEXT("CtfImeDestroyThreadMgr. ptim_P==NULL."));
  496. return E_OUTOFMEMORY;
  497. }
  498. if (ptls->GetSystemInfoFlags() & IME_SYSINFO_WINLOGON)
  499. {
  500. DebugMsg(TF_FUNC, TEXT("CtfImeDestroyThreadMgr. dwSystemInfoFlags=IME_SYSINFO_WINLOGON."));
  501. return S_OK;
  502. }
  503. else
  504. {
  505. HRESULT hr = cic->DeactivateIMMX(ptls, ptim_P);
  506. if (hr == S_OK)
  507. {
  508. cic->UnInitIMMX(ptls);
  509. }
  510. return hr;
  511. }
  512. }
  513. HRESULT WINAPI CtfImeCreateInputContext(
  514. HIMC hImc)
  515. {
  516. TLS* ptls = TLS::GetTLS();
  517. if (ptls == NULL)
  518. {
  519. DebugMsg(TF_ERROR, TEXT("CtfImeCreateInputContext. ptls==NULL."));
  520. return E_OUTOFMEMORY;
  521. }
  522. CicBridge* cic = ptls->GetCicBridge();
  523. if (cic == NULL)
  524. {
  525. DebugMsg(TF_ERROR, TEXT("CtfImeCreateInputContext. cic==NULL."));
  526. return E_OUTOFMEMORY;
  527. }
  528. return cic->CreateInputContext(ptls, hImc);
  529. }
  530. HRESULT WINAPI CtfImeDestroyInputContext(
  531. HIMC hImc)
  532. {
  533. TLS* ptls = TLS::ReferenceTLS(); // Should not allocate TLS. ie. TLS::GetTLS
  534. // IMM32::ImmDllInitialize -> IMM32::DestroyInputContext
  535. if (ptls == NULL)
  536. {
  537. DebugMsg(TF_ERROR, TEXT("CtfImeDestroyInputContext. ptls==NULL."));
  538. return E_OUTOFMEMORY;
  539. }
  540. CicBridge* cic = ptls->GetCicBridge();
  541. if (cic == NULL)
  542. {
  543. DebugMsg(TF_ERROR, TEXT("CtfImeDestroyInputContext. cic==NULL."));
  544. return E_OUTOFMEMORY;
  545. }
  546. return cic->DestroyInputContext(ptls, hImc);
  547. }
  548. HRESULT InternalSelectEx(
  549. HIMC hImc,
  550. BOOL fSelect,
  551. HKL hKL)
  552. {
  553. DebugMsg(TF_FUNC, TEXT("InternalSelectEx(hImc=%x, fSelect=%x, hKL=%x)"), hImc, fSelect, hKL);
  554. HRESULT hr;
  555. IMCLock imc(hImc);
  556. if (FAILED(hr = imc.GetResult()))
  557. {
  558. DebugMsg(TF_ERROR, TEXT("InternalSelectEx. imc==NULL"));
  559. return hr;
  560. }
  561. LANGID langid = LANGIDFROMLCID(PtrToUlong(hKL));
  562. //
  563. // Chinese Legacy IME hack code for near caret IME.
  564. //
  565. if (PRIMARYLANGID(langid) == LANG_CHINESE)
  566. {
  567. imc->cfCandForm[0].dwStyle = CFS_DEFAULT;
  568. imc->cfCandForm[0].dwIndex = (DWORD)-1;
  569. }
  570. if (fSelect)
  571. {
  572. if (! imc.ClearCand()) {
  573. return E_FAIL;
  574. }
  575. if ((imc->fdwInit & INIT_CONVERSION) == 0) {
  576. DWORD fdwConvForLang = (imc->fdwConversion & IME_CMODE_SOFTKBD); // = IME_CMODE_ALPHANUMERIC
  577. if (langid)
  578. {
  579. switch(PRIMARYLANGID(langid))
  580. {
  581. case LANG_JAPANESE:
  582. //
  583. // Roman-FullShape-Native is a major convmode to
  584. // initialize.
  585. //
  586. fdwConvForLang |= IME_CMODE_ROMAN |
  587. IME_CMODE_FULLSHAPE |
  588. IME_CMODE_NATIVE;
  589. break;
  590. case LANG_KOREAN:
  591. // IME_CMODE_ALPHANUMERIC
  592. break;
  593. #ifdef CICERO_4428
  594. case LANG_CHINESE:
  595. switch(SUBLANGID(langid))
  596. {
  597. case SUBLANG_CHINESE_TRADITIONAL:
  598. // IME_CMODE_ALPHANUMERIC
  599. break;
  600. default:
  601. fdwConvForLang |= IME_CMODE_NATIVE;
  602. break;
  603. }
  604. break;
  605. #endif
  606. default:
  607. fdwConvForLang |= IME_CMODE_NATIVE;
  608. break;
  609. }
  610. }
  611. imc->fdwConversion |= fdwConvForLang;
  612. imc->fdwInit |= INIT_CONVERSION;
  613. }
  614. //
  615. // Also, initialize extended fdwSentence flag.
  616. //
  617. imc->fdwSentence |= IME_SMODE_PHRASEPREDICT;
  618. if ((imc->fdwInit & INIT_LOGFONT) == 0) {
  619. HDC hDC;
  620. HGDIOBJ hSysFont;
  621. hDC = ::GetDC(imc->hWnd);
  622. hSysFont = ::GetCurrentObject(hDC, OBJ_FONT);
  623. LOGFONTW font;
  624. ::GetObjectW(hSysFont, sizeof(LOGFONTW), &font);
  625. ::ReleaseDC(NULL, hDC);
  626. memcpy(&imc->lfFont.W, &font, sizeof(LOGFONTW));
  627. imc->fdwInit |= INIT_LOGFONT;
  628. }
  629. // if this IME is run under Chicago Simplified Chinese version
  630. imc->lfFont.W.lfCharSet = GetCharsetFromLangId(langid);
  631. imc.InitContext();
  632. }
  633. else { // being unselected
  634. //
  635. // Reset INIT_GUID_ATOM flag here.
  636. //
  637. imc->fdwInit &= ~INIT_GUID_ATOM;
  638. }
  639. return hr;
  640. }
  641. HRESULT WINAPI CtfImeSelectEx(
  642. HIMC hIMC,
  643. BOOL fSelect,
  644. HKL hKL)
  645. {
  646. TLS* ptls = TLS::ReferenceTLS(); // Should not allocate TLS. ie. TLS::GetTLS
  647. // IMM32::ImmDllInitialize -> IMM32::DestroyInputContext
  648. if (ptls == NULL)
  649. {
  650. DebugMsg(TF_ERROR, TEXT("CtfImeSelectEx. ptls==NULL."));
  651. return E_OUTOFMEMORY;
  652. }
  653. //
  654. // This is only related hIMC content.
  655. // Even no cic object, hIMC should be updated.
  656. //
  657. InternalSelectEx(hIMC, fSelect, hKL);
  658. CicBridge* cic = ptls->GetCicBridge();
  659. if (cic == NULL)
  660. {
  661. DebugMsg(TF_ERROR, TEXT("CtfImeSelectEx. cic==NULL."));
  662. return E_OUTOFMEMORY;
  663. }
  664. ITfThreadMgr_P* ptim_P = ptls->GetTIM();
  665. if (ptim_P == NULL)
  666. {
  667. DebugMsg(TF_ERROR, TEXT("CtfImeSelectEx. ptim_P==NULL."));
  668. return E_OUTOFMEMORY;
  669. }
  670. return cic->SelectEx(ptls, ptim_P, hIMC, fSelect, hKL);
  671. }
  672. HRESULT WINAPI CtfImeSetActiveContextAlways(
  673. HIMC hIMC,
  674. BOOL fOn,
  675. HWND hWnd,
  676. HKL hKL)
  677. {
  678. TLS* ptls = TLS::GetTLS();
  679. if (ptls == NULL)
  680. {
  681. DebugMsg(TF_ERROR, TEXT("CtfImeSetActiveContextAlways. ptls==NULL."));
  682. return E_OUTOFMEMORY;
  683. }
  684. CicBridge* cic = ptls->GetCicBridge();
  685. if (cic == NULL)
  686. {
  687. DebugMsg(TF_ERROR, TEXT("CtfImeSetActiveContextAlways. cic==NULL."));
  688. return E_OUTOFMEMORY;
  689. }
  690. return cic->SetActiveContextAlways(ptls, hIMC, fOn, hWnd, hKL);
  691. }
  692. LRESULT WINAPI CtfImeEscapeEx(
  693. HIMC hIMC,
  694. UINT uSubFunc,
  695. LPVOID lpData,
  696. HKL hKL)
  697. {
  698. if (LOWORD(HandleToUlong(hKL)) == MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT))
  699. {
  700. TLS* ptls = TLS::GetTLS();
  701. if (ptls == NULL)
  702. {
  703. DebugMsg(TF_ERROR, TEXT("CtfImeEscapeEx. ptls==NULL."));
  704. return FALSE;
  705. }
  706. CicBridge* cic = ptls->GetCicBridge();
  707. if (cic == NULL)
  708. {
  709. DebugMsg(TF_ERROR, TEXT("CtfImeEscapeEx. cic==NULL."));
  710. return FALSE;
  711. }
  712. return cic->EscapeKorean(ptls, hIMC, uSubFunc, lpData);
  713. }
  714. return FALSE;
  715. }
  716. HRESULT WINAPI CtfImeGetGuidAtom(
  717. HIMC hIMC,
  718. BYTE bAttr,
  719. TfGuidAtom* pAtom)
  720. {
  721. TLS* ptls = TLS::GetTLS();
  722. if (ptls == NULL)
  723. {
  724. DebugMsg(TF_ERROR, TEXT("CtfImeGetGuidAtom. ptls==NULL."));
  725. return E_OUTOFMEMORY;
  726. }
  727. CicBridge* cic = ptls->GetCicBridge();
  728. if (cic == NULL)
  729. {
  730. DebugMsg(TF_ERROR, TEXT("CtfImeGetGuidAtom. cic==NULL."));
  731. return E_OUTOFMEMORY;
  732. }
  733. return cic->GetGuidAtom(ptls, hIMC, bAttr, pAtom);
  734. }
  735. BOOL WINAPI CtfImeIsGuidMapEnable(
  736. HIMC hIMC)
  737. {
  738. HRESULT hr;
  739. IMCLock imc(hIMC);
  740. if (FAILED(hr=imc.GetResult()))
  741. {
  742. DebugMsg(TF_ERROR, TEXT("CtfImeIsGuidMapEnable. imc==NULL"));
  743. return FALSE;
  744. }
  745. return (imc->fdwInit & INIT_GUID_ATOM) ? TRUE : FALSE;
  746. }
  747. HRESULT WINAPI CtfImeThreadDetach()
  748. {
  749. ImeDestroy(0);
  750. return S_OK;
  751. }
  752. BOOL WINAPI CtfImeIsIME(
  753. HKL hkl)
  754. {
  755. if (IS_IME_KBDLAYOUT(hkl))
  756. return TRUE;
  757. TLS* ptls = TLS::GetTLS();
  758. if (ptls == NULL)
  759. {
  760. DebugMsg(TF_ERROR, TEXT("CtfImeIsIME. ptls==NULL."));
  761. return FALSE;
  762. }
  763. CicProfile* pProfile = ptls->GetCicProfile();
  764. if (pProfile == NULL)
  765. {
  766. DebugMsg(TF_ERROR, TEXT("CtfImeIsIME. pProfile==NULL."));
  767. return FALSE;
  768. }
  769. return (pProfile->IsIME(hkl) == S_OK) ? TRUE : FALSE;
  770. }
  771. } // extern "C"