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.

1169 lines
28 KiB

  1. /*++
  2. Copyright (c) 1985 - 1999, Microsoft Corporation
  3. Module Name:
  4. context.cpp
  5. Abstract:
  6. This file implements the Input Context Class.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #include "private.h"
  12. #include "cdimm.h"
  13. #include "context.h"
  14. #include "globals.h"
  15. #include "defs.h"
  16. #include "delay.h"
  17. #include "computil.h"
  18. BOOL
  19. CInputContext::_CreateDefaultInputContext(
  20. IN DWORD dwPrivateSize,
  21. IN BOOL fUnicode,
  22. IN BOOL fCiceroActivated
  23. )
  24. /*++
  25. Routine Description:
  26. Create a default input context
  27. Arguments:
  28. dwPrivateSize - [in] Unsigned integer long value that contains the size of private IMCC
  29. data.
  30. Return Value:
  31. Returns TRUE if successful, or an error code otherwise.
  32. --*/
  33. {
  34. // create a default IMC for this thread
  35. if (IsOnImm()) {
  36. // On FE systems, we use system allocated HIMCs
  37. // but here we want to use the thread default HIMC
  38. // which the system has already allocated.
  39. CActiveIMM *_pActiveIMM = GetTLS();
  40. if (_pActiveIMM == NULL)
  41. return FALSE;
  42. // consider: find a better way to get the def HIMC!
  43. HWND hWnd = CreateWindow(TEXT("STATIC"), TEXT(""), WS_DISABLED | WS_POPUP,
  44. 0, 0, 0, 0, 0, 0, g_hInst, NULL);
  45. if (hWnd)
  46. {
  47. Imm32_GetContext(hWnd, &_hDefaultIMC);
  48. if (_hDefaultIMC)
  49. Imm32_ReleaseContext(hWnd, _hDefaultIMC);
  50. DestroyWindow(hWnd);
  51. }
  52. if (_hDefaultIMC == NULL)
  53. return FALSE;
  54. CContextList::CLIENT_IMC_FLAG client_flag = (fUnicode ? CContextList::IMCF_UNICODE
  55. : CContextList::IMCF_NONE );
  56. ContextList.SetAt(_hDefaultIMC, client_flag);
  57. // we can't create the cicero context until ITfThreadMgr::Activate has been called
  58. // we'll do this later if we need to
  59. if (fCiceroActivated)
  60. {
  61. if (FAILED(CreateAImeContext(_hDefaultIMC))) {
  62. ContextList.RemoveKey(_hDefaultIMC);
  63. return FALSE;
  64. }
  65. }
  66. _pActiveIMM->_ResizePrivateIMCC(_hDefaultIMC, dwPrivateSize);
  67. }
  68. else {
  69. if (FAILED(CreateContext(dwPrivateSize, fUnicode, &_hDefaultIMC, fCiceroActivated)))
  70. return FALSE;
  71. }
  72. return TRUE;
  73. }
  74. BOOL
  75. CInputContext::_DestroyDefaultInputContext(
  76. )
  77. {
  78. // destroy a default IMC for this thread
  79. if (! IsOnImm()) {
  80. if (FAILED(DestroyContext(_hDefaultIMC)))
  81. return FALSE;
  82. }
  83. else {
  84. if (FAILED(DestroyAImeContext(_hDefaultIMC)))
  85. return FALSE;
  86. }
  87. return TRUE;
  88. }
  89. HRESULT
  90. CInputContext::UpdateInputContext(
  91. IN HIMC hIMC,
  92. IN DWORD dwPrivateDataSize
  93. )
  94. {
  95. HRESULT hr;
  96. DIMM_IMCLock lpIMC(hIMC);
  97. if (FAILED(hr = lpIMC.GetResult()))
  98. return hr;
  99. /*
  100. * hPrivate
  101. */
  102. if (FAILED(hr = UpdateIMCC(&lpIMC->hPrivate, dwPrivateDataSize))) {
  103. TraceMsg(TF_ERROR, "CInputContext::UpdateInputContext: hIMCC::hRivate failure");
  104. return hr;
  105. }
  106. /*
  107. * hMsgBuf
  108. */
  109. if (FAILED(hr = UpdateIMCC(&lpIMC->hMsgBuf, sizeof(UINT)))) {
  110. TraceMsg(TF_ERROR, "CInputContext::UpdateInputContext: hIMCC::hMsgBuf failure");
  111. return hr;
  112. }
  113. lpIMC->dwNumMsgBuf = 0;
  114. /*
  115. * hGuideLine
  116. */
  117. if (FAILED(hr = UpdateIMCC(&lpIMC->hGuideLine, sizeof(GUIDELINE)))) {
  118. TraceMsg(TF_ERROR, "CInputContext::UpdateInputContext: hIMCC::hGuideLine failure");
  119. return hr;
  120. }
  121. DIMM_IMCCLock<GUIDELINE> pGuideLine(lpIMC->hGuideLine);
  122. if (FAILED(hr = pGuideLine.GetResult())) {
  123. TraceMsg(TF_ERROR, "CInputContext::UpdateInputContext: can not lock hGuideLine");
  124. return hr;
  125. }
  126. pGuideLine->dwSize = sizeof(GUIDELINE);
  127. /*
  128. * hCandInfo
  129. */
  130. if (FAILED(hr = UpdateIMCC(&lpIMC->hCandInfo, sizeof(CANDIDATEINFO)))) {
  131. TraceMsg(TF_ERROR, "CInputContext::UpdateInputContext: hIMCC::hCandInfo failure");
  132. return hr;
  133. }
  134. DIMM_IMCCLock<CANDIDATEINFO> pCandInfo(lpIMC->hCandInfo);
  135. if (FAILED(hr = pCandInfo.GetResult())) {
  136. TraceMsg(TF_ERROR, "CInputContext::UpdateInputContext: can not lock hCandInfo");
  137. return hr;
  138. }
  139. pCandInfo->dwSize = sizeof(CANDIDATEINFO);
  140. /*
  141. * hCompStr
  142. */
  143. if (FAILED(hr = UpdateIMCC(&lpIMC->hCompStr, sizeof(COMPOSITIONSTRING_AIMM12)))) {
  144. TraceMsg(TF_ERROR, "CInputContext::UpdateInputContext: hIMCC::hCompStr failure");
  145. return hr;
  146. }
  147. DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12> lpCompStr(lpIMC->hCompStr);
  148. if (FAILED(hr = lpCompStr.GetResult())) {
  149. TraceMsg(TF_ERROR, "CInputContext::UpdateInputContext: can not lock hCompStr");
  150. return hr;
  151. }
  152. lpCompStr->CompStr.dwSize = sizeof(COMPOSITIONSTRING_AIMM12);
  153. /*
  154. * AIME private context.
  155. */
  156. if (lpIMC->m_pContext != NULL) {
  157. hr = lpIMC->m_pContext->UpdateAImeContext(hIMC);
  158. }
  159. return hr;
  160. }
  161. HRESULT
  162. CInputContext::ResizePrivateIMCC(
  163. IN HIMC hIMC,
  164. IN DWORD dwPrivateSize
  165. )
  166. {
  167. HRESULT hr;
  168. // Make sure Private context data size
  169. DIMM_IMCLock imc(hIMC);
  170. if (FAILED(hr = imc.GetResult()))
  171. return hr;
  172. return UpdateIMCC(&imc->hPrivate, dwPrivateSize);
  173. }
  174. HRESULT
  175. CInputContext::UpdateIMCC(
  176. IN HIMCC* phIMCC,
  177. IN DWORD dwRequestSize
  178. )
  179. {
  180. HRESULT hr;
  181. DWORD dwSize;
  182. DWORD dwLockCount;
  183. const DWORD IMCC_ALLOC_TOOLARGE = 0x1000;
  184. if (*phIMCC == NULL) {
  185. hr = CreateIMCC(dwRequestSize, phIMCC);
  186. }
  187. else {
  188. hr = GetIMCCSize(*phIMCC, &dwSize);
  189. if (SUCCEEDED(hr)) {
  190. if (dwSize < dwRequestSize ||
  191. dwSize > IMCC_ALLOC_TOOLARGE) {
  192. hr = GetIMCCLockCount(*phIMCC, &dwLockCount);
  193. if (SUCCEEDED(hr)) {
  194. ASSERT(dwLockCount == 0);
  195. if (dwLockCount != 0) {
  196. TraceMsg(TF_ERROR, "CInputContext::UpdateIMCC: Unlock resource");
  197. do {
  198. if (FAILED(hr = _UnlockIMCC(*phIMCC)))
  199. return hr;
  200. if (FAILED(hr = GetIMCCLockCount(*phIMCC, &dwLockCount)))
  201. return hr;
  202. } while(dwLockCount);
  203. if (SUCCEEDED(hr = DestroyIMCC(*phIMCC)))
  204. hr = CreateIMCC(dwRequestSize, phIMCC);
  205. }
  206. else {
  207. HIMCC hResizeIMCC;
  208. hr = ReSizeIMCC(*phIMCC, dwRequestSize, &hResizeIMCC);
  209. if (SUCCEEDED(hr)) {
  210. *phIMCC = hResizeIMCC;
  211. }
  212. else {
  213. TraceMsg(TF_WARNING, "CInputContext::UpdateIMCC: Resize hIMCC %lX failure", dwRequestSize);
  214. if (SUCCEEDED(hr = DestroyIMCC(*phIMCC)))
  215. hr = CreateIMCC(dwRequestSize, phIMCC);
  216. }
  217. }
  218. }
  219. }
  220. }
  221. }
  222. return hr;
  223. }
  224. BOOL
  225. CInputContext::EnumInputContext(
  226. DWORD idThread,
  227. IMCENUMPROC lpfn,
  228. LPARAM lParam
  229. )
  230. {
  231. UINT cHimc;
  232. /*
  233. * Get the hIMC list. It is returned in a block of memory allocated.
  234. */
  235. if ((cHimc = BuildHimcList(idThread, NULL)) == 0) {
  236. return FALSE;
  237. }
  238. BOOL fSuccess = FALSE;
  239. HIMC* pHimc = new HIMC[cHimc];
  240. if (pHimc) {
  241. BuildHimcList(idThread, pHimc);
  242. /*
  243. * Loop through the input contexts, call the function pointer back for each one.
  244. * End loop if either FALSE is returned or the end-of-list is reached.
  245. */
  246. UINT index;
  247. for (index = 0; index < cHimc; index++) {
  248. if (! (fSuccess = (*lpfn)(pHimc[index], lParam)) )
  249. break;
  250. }
  251. /*
  252. * Free up buffer and return status - TRUE if entire list was enumerated,
  253. * FALSE otherwise.
  254. */
  255. delete [] pHimc;
  256. }
  257. return fSuccess;
  258. }
  259. DWORD
  260. CInputContext::BuildHimcList(
  261. DWORD idThread,
  262. HIMC pHimc[]
  263. )
  264. {
  265. if (idThread != 0 && idThread != GetCurrentThreadId())
  266. return 0;
  267. if (pHimc != NULL) {
  268. POSITION pos = ContextList.GetStartPosition();
  269. int index;
  270. for (index = 0; index < ContextList.GetCount(); index++) {
  271. ContextList.GetNextHimc(pos, &pHimc[index]);
  272. }
  273. }
  274. return (DWORD)(ContextList.GetCount());
  275. }
  276. /*
  277. * AIMM Input Context (hIMC) API Methods.
  278. */
  279. HRESULT
  280. CInputContext::CreateContext(
  281. IN DWORD dwPrivateSize,
  282. IN BOOL fUnicode,
  283. OUT HIMC *phIMC,
  284. IN BOOL fCiceroActivated,
  285. IN DWORD fdwInitConvMode,
  286. IN BOOL fInitOpen
  287. )
  288. {
  289. TraceMsg(TF_API, TEXT("CInputContext::CreateContext"));
  290. *phIMC = NULL;
  291. if (IsOnImm()) {
  292. // defer to the system IMM
  293. HRESULT hr;
  294. CActiveIMM *_pActiveIMM = GetTLS();
  295. if (_pActiveIMM == NULL)
  296. return E_FAIL;
  297. if (FAILED(hr = Imm32_CreateContext(phIMC)))
  298. return hr;
  299. CContextList::CLIENT_IMC_FLAG client_flag = (fUnicode ? CContextList::IMCF_UNICODE
  300. : CContextList::IMCF_NONE );
  301. ContextList.SetAt(*phIMC, client_flag);
  302. // we can't create the cicero context until ITfThreadMgr::Activate has been called
  303. // we'll do this later if we need to
  304. if (fCiceroActivated)
  305. {
  306. if (FAILED(hr=CreateAImeContext(*phIMC))) {
  307. Imm32_DestroyContext(*phIMC);
  308. ContextList.RemoveKey(*phIMC);
  309. return hr;
  310. }
  311. }
  312. _pActiveIMM->_ResizePrivateIMCC(*phIMC, dwPrivateSize);
  313. }
  314. else {
  315. HIMC hIMC = static_cast<HIMC>(LocalAlloc(LHND, sizeof(INPUTCONTEXT_AIMM12)));
  316. CContextList::CLIENT_IMC_FLAG client_flag = (fUnicode ? CContextList::IMCF_UNICODE
  317. : CContextList::IMCF_NONE );
  318. ContextList.SetAt(hIMC, client_flag);
  319. /*
  320. * Ready to use hIMC
  321. */
  322. DIMM_IMCLock lpIMC(hIMC);
  323. if (lpIMC.Valid()) {
  324. //
  325. // Initialize context data.
  326. //
  327. lpIMC->dwNumMsgBuf = 0;
  328. lpIMC->fOpen = fInitOpen;
  329. lpIMC->fdwConversion = fdwInitConvMode;
  330. lpIMC->fdwSentence = 0;
  331. lpIMC->m_pContext = NULL;
  332. for (UINT i = 0; i < 4; i++) {
  333. lpIMC->cfCandForm[i].dwIndex = (DWORD)(-1);
  334. }
  335. HRESULT hr;
  336. // we can't create the cicero context until ITfThreadMgr::Activate has been called
  337. // we'll do this later if we need to
  338. if (fCiceroActivated)
  339. {
  340. if (FAILED(hr=CreateAImeContext(hIMC))) {
  341. DestroyContext(hIMC);
  342. return hr;
  343. }
  344. }
  345. if (FAILED(CreateIMCC(sizeof(COMPOSITIONSTRING_AIMM12), &lpIMC->hCompStr)) ||
  346. FAILED(CreateIMCC(sizeof(CANDIDATEINFO), &lpIMC->hCandInfo)) ||
  347. FAILED(CreateIMCC(sizeof(GUIDELINE), &lpIMC->hGuideLine)) ||
  348. FAILED(CreateIMCC(sizeof(DWORD), &lpIMC->hMsgBuf)) ||
  349. FAILED(CreateIMCC(dwPrivateSize, &lpIMC->hPrivate)) ) {
  350. DestroyContext((HIMC)lpIMC);
  351. return E_OUTOFMEMORY;
  352. }
  353. else {
  354. *phIMC = hIMC;
  355. }
  356. }
  357. else {
  358. return E_OUTOFMEMORY;
  359. }
  360. }
  361. return S_OK;
  362. }
  363. HRESULT
  364. CInputContext::DestroyContext(
  365. IN HIMC hIMC
  366. )
  367. {
  368. TraceMsg(TF_API, "CInputContext::DestroyContext");
  369. if (IsOnImm()) {
  370. HRESULT hr;
  371. if (FAILED(hr=DestroyAImeContext(hIMC)))
  372. return hr;
  373. ContextList.RemoveKey(hIMC);
  374. return Imm32_DestroyContext(hIMC);
  375. }
  376. else {
  377. {
  378. DIMM_IMCLock pIMC(hIMC);
  379. if (!pIMC.Valid())
  380. return E_FAIL;
  381. if (FAILED(DestroyIMCC(pIMC->hCompStr)) ||
  382. FAILED(DestroyIMCC(pIMC->hCandInfo)) ||
  383. FAILED(DestroyIMCC(pIMC->hGuideLine)) ||
  384. FAILED(DestroyIMCC(pIMC->hMsgBuf)) ||
  385. FAILED(DestroyIMCC(pIMC->hPrivate)) ) {
  386. return E_FAIL;
  387. }
  388. HRESULT hr;
  389. if (FAILED(hr=DestroyAImeContext(hIMC)))
  390. return hr;
  391. ContextList.RemoveKey(hIMC);
  392. } // pIMC dtor called here! We must unlock hIMC before calling LocalFree
  393. return LocalFree(hIMC) ? E_FAIL : S_OK;
  394. }
  395. }
  396. HRESULT
  397. CInputContext::AssociateContext(
  398. IN HWND hWnd,
  399. IN HIMC hIMC,
  400. OUT HIMC *phPrev
  401. )
  402. {
  403. TraceMsg(TF_API, "CInputContext::AssociateContext");
  404. if (!IsWindow(hWnd))
  405. return E_INVALIDARG;
  406. DWORD dwProcessId;
  407. if (hIMC && ! ContextLookup(hIMC, &dwProcessId))
  408. return E_ACCESSDENIED;
  409. HRESULT hr = GetContext(hWnd, phPrev);
  410. AssociateList.SetAt(hWnd, hIMC);
  411. return hr;
  412. }
  413. HRESULT
  414. CInputContext::AssociateContextEx(
  415. IN HWND hWnd,
  416. IN HIMC hIMC,
  417. IN DWORD dwFlags
  418. )
  419. {
  420. TraceMsg(TF_API, "CInputContext::AssociateContextEx");
  421. return E_NOTIMPL;
  422. }
  423. HRESULT
  424. CInputContext::GetContext(
  425. IN HWND hWnd,
  426. OUT HIMC* phIMC
  427. )
  428. {
  429. TraceMsg(TF_API, "CInputContext::GetContext");
  430. if (hWnd == NULL || ! IsWindow(hWnd)) {
  431. TraceMsg(TF_WARNING, "CInputContext::GetContext: Invalid window handle %x", hWnd);
  432. return E_FAIL;
  433. }
  434. HIMC hIMC = _hDefaultIMC;
  435. BOOL ret = AssociateList.Lookup(hWnd, hIMC);
  436. if (! ret) {
  437. if (IsOnImm()) {
  438. Imm32_GetContext(hWnd, &hIMC);
  439. if (hIMC) {
  440. /*
  441. * Guaranty of Win98 IMM code that Win98 have a reference count
  442. * of GetContext/ReleaseContext. If under ref cnt occurred, then
  443. * apps had the AV in the IMM code.
  444. * Because it ref cnt keeps the 32bit hIMC data segment for refer
  445. * from 16bit code. When ref cnt is zero, hIMC's data segment has been freed.
  446. * Of course, AIMM1.2's ReleaseContext nothing else to do.
  447. */
  448. Imm32_ReleaseContext(hWnd, hIMC);
  449. }
  450. }
  451. }
  452. *phIMC = hIMC;
  453. return S_OK;
  454. }
  455. HRESULT
  456. CInputContext::GetIMCLockCount(
  457. IN HIMC hIMC,
  458. OUT DWORD* pdwLockCount
  459. )
  460. {
  461. TraceMsg(TF_API, "CInputContext::GetIMCLockCount");
  462. if (IsOnImm()) {
  463. return Imm32_GetIMCLockCount(hIMC, pdwLockCount);
  464. }
  465. else {
  466. *pdwLockCount = LocalFlags(hIMC) & LMEM_LOCKCOUNT;
  467. return S_OK;
  468. }
  469. }
  470. HRESULT
  471. CInputContext::CreateAImeContext(
  472. HIMC hIMC
  473. )
  474. {
  475. HRESULT hr;
  476. DIMM_IMCLock imc(hIMC);
  477. if (FAILED(hr=imc.GetResult()))
  478. return hr;
  479. IAImeContext* pAImeContext;
  480. extern HRESULT CAImeContext_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj);
  481. hr = CAImeContext_CreateInstance(NULL, IID_IAImeContext, (void**)&pAImeContext);
  482. if (FAILED(hr)) {
  483. TraceMsg(TF_ERROR, "CreateAImeContext failed");
  484. return hr;
  485. }
  486. return pAImeContext->CreateAImeContext(hIMC, m_pActiveIME);
  487. }
  488. HRESULT
  489. CInputContext::DestroyAImeContext(
  490. HIMC hIMC
  491. )
  492. {
  493. HRESULT hr;
  494. DIMM_IMCLock imc(hIMC);
  495. if (FAILED(hr=imc.GetResult()))
  496. return hr;
  497. // imc->m_pContext may be NULL if ITfThreadMgr::Activate has not been called
  498. if (imc->m_pContext == NULL)
  499. return S_OK;
  500. //
  501. // Backup IAImeContext pointer and NULL out in imc->m_pContext.
  502. // DestroyAImeContext::pdim->Pop maybe calls ActivateAssembly if it is in queueing.
  503. // ActivateAssembly maybe changes keyboard layout between Cicero and Real IME hKL.
  504. // It happens called ImeActivateLayout from IMM32 and this function updates input context.
  505. // However, imc->m_pContext's object already gone and occurred AV when touch NULL object.
  506. // This NULL out is previent AV in the imc->m_pContext object.
  507. //
  508. IAImeContext* pContext = imc->m_pContext;
  509. imc->m_pContext = NULL;
  510. hr = pContext->DestroyAImeContext(hIMC);
  511. pContext->Release();
  512. return hr;
  513. }
  514. /*
  515. * AIMM Input Context Components (hIMCC) API Methods.
  516. */
  517. HRESULT
  518. CInputContext::CreateIMCC(
  519. IN DWORD dwSize,
  520. OUT HIMCC *phIMCC
  521. )
  522. {
  523. TraceMsg(TF_API, "CInputContext::CreateIMCC");
  524. if (IsOnImm()) {
  525. return Imm32_CreateIMCC(dwSize, phIMCC);
  526. }
  527. else {
  528. if ((*phIMCC = static_cast<HIMCC>(LocalAlloc(LHND, dwSize+sizeof(DWORD)))) == NULL)
  529. return E_OUTOFMEMORY;
  530. }
  531. return S_OK;
  532. }
  533. HRESULT
  534. CInputContext::DestroyIMCC(
  535. IN HIMCC hIMCC
  536. )
  537. {
  538. TraceMsg(TF_API, "CInputContext::DestroyIMCC");
  539. if (IsOnImm()) {
  540. return Imm32_DestroyIMCC(hIMCC);
  541. }
  542. else {
  543. return LocalFree(hIMCC) ? E_FAIL : S_OK;
  544. }
  545. return S_OK;
  546. }
  547. HRESULT
  548. CInputContext::GetIMCCSize(
  549. IN HIMCC hIMCC,
  550. OUT DWORD *pdwSize
  551. )
  552. {
  553. TraceMsg(TF_API, "CInputContext::GetIMCCSize");
  554. if (hIMCC == NULL) {
  555. return E_INVALIDARG;
  556. }
  557. if (IsOnImm()) {
  558. return Imm32_GetIMCCSize(hIMCC, pdwSize);
  559. }
  560. else {
  561. *pdwSize = (DWORD)LocalSize(hIMCC);
  562. }
  563. return S_OK;
  564. }
  565. HRESULT
  566. CInputContext::ReSizeIMCC(
  567. IN HIMCC hIMCC,
  568. IN DWORD dwSize,
  569. OUT HIMCC *phIMCC
  570. )
  571. {
  572. TraceMsg(TF_API, "CInputContext::ReSizeIMCC");
  573. if (hIMCC == NULL) {
  574. return E_INVALIDARG;
  575. }
  576. if (IsOnImm()) {
  577. return Imm32_ReSizeIMCC(hIMCC, dwSize, phIMCC);
  578. }
  579. else {
  580. if ((*phIMCC = (HIMCC)LocalReAlloc(hIMCC, dwSize+sizeof(DWORD), LHND)) == NULL) {
  581. return E_OUTOFMEMORY;
  582. }
  583. }
  584. return S_OK;
  585. }
  586. HRESULT
  587. CInputContext::GetIMCCLockCount(
  588. IN HIMCC hIMCC,
  589. OUT DWORD* pdwLockCount
  590. )
  591. {
  592. TraceMsg(TF_API, "CInputContext::GetIMCLockCount");
  593. if (IsOnImm()) {
  594. return Imm32_GetIMCCLockCount(hIMCC, pdwLockCount);
  595. }
  596. else {
  597. *pdwLockCount = LocalFlags(hIMCC) & LMEM_LOCKCOUNT;
  598. return S_OK;
  599. }
  600. }
  601. /*
  602. * AIMM Open Status API Methods
  603. */
  604. HRESULT
  605. CInputContext::GetOpenStatus(
  606. IN HIMC hIMC
  607. )
  608. {
  609. TraceMsg(TF_API, "CInputContext::GetOpenStatus");
  610. DIMM_IMCLock lpIMC(hIMC);
  611. if (lpIMC.Invalid())
  612. return E_FAIL;
  613. return (lpIMC->fOpen ? S_OK : S_FALSE);
  614. }
  615. HRESULT
  616. CInputContext::SetOpenStatus(
  617. IN DIMM_IMCLock& lpIMC,
  618. IN BOOL fOpen,
  619. OUT BOOL* pfOpenChg
  620. )
  621. {
  622. DWORD dwOpenStatus;
  623. DWORD dwConversion;
  624. TraceMsg(TF_API, "CInputContext::SetOpenStatus");
  625. *pfOpenChg = FALSE;
  626. if (lpIMC->fOpen != fOpen) {
  627. lpIMC->fOpen = fOpen;
  628. *pfOpenChg = TRUE;
  629. }
  630. if (*pfOpenChg) {
  631. dwOpenStatus = (DWORD)lpIMC->fOpen;
  632. dwConversion = (DWORD)lpIMC->fdwConversion;
  633. }
  634. return S_OK;
  635. }
  636. /*
  637. * AIMM Conversion Status API Methods
  638. */
  639. HRESULT
  640. CInputContext::GetConversionStatus(
  641. IN HIMC hIMC,
  642. OUT LPDWORD lpfdwConversion,
  643. OUT LPDWORD lpfdwSentence
  644. )
  645. {
  646. TraceMsg(TF_API, "CInputContext::GetConversionStatus");
  647. if (IsOnImm()) {
  648. return Imm32_GetConversionStatus(hIMC, lpfdwConversion, lpfdwSentence);
  649. }
  650. DIMM_IMCLock pIMC(hIMC);
  651. if (pIMC.Invalid())
  652. return E_FAIL;
  653. *lpfdwSentence = pIMC->fdwSentence;
  654. *lpfdwConversion = pIMC->fdwConversion;
  655. return S_OK;
  656. }
  657. HRESULT
  658. CInputContext::SetConversionStatus(
  659. IN DIMM_IMCLock& lpIMC,
  660. IN DWORD fdwConversion,
  661. IN DWORD fdwSentence,
  662. OUT BOOL* pfConvModeChg,
  663. OUT BOOL* pfSentenceChg,
  664. OUT DWORD* pfdwOldConversion,
  665. OUT DWORD* pfdwOldSentence
  666. )
  667. {
  668. DWORD dwOpenStatus;
  669. DWORD dwConversion;
  670. TraceMsg(TF_API, "CInputContext::SetConversionStatus");
  671. if (fdwConversion != lpIMC->fdwConversion) {
  672. if ((fdwConversion & IME_CMODE_LANGUAGE) == IME_CMODE_KATAKANA) {
  673. TraceMsg(TF_WARNING, "SetConversionStatus: wrong fdwConversion");
  674. }
  675. *pfdwOldConversion = lpIMC->fdwConversion;
  676. lpIMC->fdwConversion = fdwConversion;
  677. *pfConvModeChg = TRUE;
  678. }
  679. if (fdwSentence != lpIMC->fdwSentence) {
  680. *pfdwOldSentence = lpIMC->fdwSentence;
  681. lpIMC->fdwSentence = fdwSentence;
  682. *pfSentenceChg = TRUE;
  683. }
  684. if (*pfConvModeChg) {
  685. dwOpenStatus = (DWORD)lpIMC->fOpen;
  686. dwConversion = lpIMC->fdwConversion;
  687. }
  688. return S_OK;
  689. }
  690. /*
  691. * AIMM Status Window Pos API Methods
  692. */
  693. HRESULT WINAPI
  694. CInputContext::GetStatusWindowPos(
  695. IN HIMC hIMC,
  696. OUT LPPOINT lpCandidate
  697. )
  698. {
  699. TraceMsg(TF_API, "CInputContext::GetStatusWindowPos");
  700. if (IsOnImm()) {
  701. return Imm32_GetStatusWindowPos(hIMC, lpCandidate);
  702. }
  703. if (hIMC == NULL)
  704. return E_INVALIDARG;
  705. DIMM_IMCLock pIMC(hIMC);
  706. if (pIMC.Invalid())
  707. return E_FAIL;
  708. if (pIMC->fdwInit & INIT_STATUSWNDPOS) {
  709. *lpCandidate = pIMC->ptStatusWndPos;
  710. return S_OK;
  711. }
  712. return E_FAIL;
  713. }
  714. HRESULT
  715. CInputContext::SetStatusWindowPos(
  716. IN DIMM_IMCLock& lpIMC,
  717. IN LPPOINT lpptPos
  718. )
  719. {
  720. TraceMsg(TF_API, "CInputContext::SetStatusWindowPos");
  721. lpIMC->ptStatusWndPos = *lpptPos;
  722. lpIMC->fdwInit |= INIT_STATUSWNDPOS;
  723. return S_OK;
  724. }
  725. /*
  726. * AIMM Composition String API Methods
  727. */
  728. HRESULT
  729. CInputContext::GetCompositionString(
  730. IN DIMM_IMCCLock<COMPOSITIONSTRING_AIMM12>& lpCompStr,
  731. IN DWORD dwIndex,
  732. IN LONG*& lpCopied,
  733. IN size_t size
  734. )
  735. {
  736. HRESULT hr;
  737. TraceMsg(TF_API, "CInputContext::GetCompositionStringA(LONG*)");
  738. switch (dwIndex) {
  739. case GCS_COMPSTR:
  740. hr = GetCompInfo(size, lpCompStr->CompStr.dwCompStrLen, lpCopied);
  741. break;
  742. case GCS_COMPREADSTR:
  743. hr = GetCompInfo(size, lpCompStr->CompStr.dwCompReadStrLen, lpCopied);
  744. break;
  745. case GCS_RESULTSTR:
  746. hr = GetCompInfo(size, lpCompStr->CompStr.dwResultStrLen, lpCopied);
  747. break;
  748. case GCS_RESULTREADSTR:
  749. hr = GetCompInfo(size, lpCompStr->CompStr.dwResultReadStrLen, lpCopied);
  750. break;
  751. case GCS_COMPATTR:
  752. hr = GetCompInfo(size, lpCompStr->CompStr.dwCompAttrLen, lpCopied);
  753. break;
  754. case GCS_COMPREADATTR:
  755. hr = GetCompInfo(size, lpCompStr->CompStr.dwCompReadAttrLen, lpCopied);
  756. break;
  757. case GCS_COMPREADCLAUSE:
  758. hr = GetCompInfo(size, lpCompStr->CompStr.dwCompReadClauseLen, lpCopied);
  759. break;
  760. case GCS_RESULTCLAUSE:
  761. hr = GetCompInfo(size, lpCompStr->CompStr.dwResultClauseLen, lpCopied);
  762. break;
  763. case GCS_RESULTREADCLAUSE:
  764. hr = GetCompInfo(size, lpCompStr->CompStr.dwResultReadClauseLen, lpCopied);
  765. break;
  766. case GCS_COMPCLAUSE:
  767. hr = GetCompInfo(size, lpCompStr->CompStr.dwCompClauseLen, lpCopied);
  768. break;
  769. case GCS_CURSORPOS:
  770. *lpCopied = lpCompStr->CompStr.dwCursorPos;
  771. hr = S_OK;
  772. break;
  773. case GCS_DELTASTART:
  774. *lpCopied = lpCompStr->CompStr.dwDeltaStart;
  775. hr = S_OK;
  776. break;
  777. default:
  778. hr = E_INVALIDARG;
  779. *lpCopied = IMM_ERROR_GENERAL; // ala Win32
  780. break;
  781. }
  782. return hr;
  783. }
  784. /*
  785. * AIMM Composition Font API Methods
  786. */
  787. HRESULT
  788. CInputContext::GetCompositionFont(
  789. IN DIMM_IMCLock& lpIMC,
  790. OUT LOGFONTAW* lplf,
  791. IN BOOL fUnicode
  792. )
  793. {
  794. TraceMsg(TF_API, "CInputContext::GetCompositionFont");
  795. if ((lpIMC->fdwInit & INIT_LOGFONT) == INIT_LOGFONT) {
  796. if (fUnicode)
  797. *(&lplf->W) = lpIMC->lfFont.W;
  798. else
  799. *(&lplf->A) = lpIMC->lfFont.A;
  800. return S_OK;
  801. }
  802. return E_FAIL;
  803. }
  804. HRESULT
  805. CInputContext::SetCompositionFont(
  806. IN DIMM_IMCLock& lpIMC,
  807. IN LOGFONTAW* lplf,
  808. IN BOOL fUnicode
  809. )
  810. {
  811. TraceMsg(TF_API, "CInputContext::SetCompositionFont");
  812. if (fUnicode)
  813. lpIMC->lfFont.W = *(&lplf->W);
  814. else
  815. lpIMC->lfFont.A = *(&lplf->A);
  816. lpIMC->fdwInit |= INIT_LOGFONT;
  817. return S_OK;
  818. }
  819. /*
  820. * AIMM Composition Window API Method
  821. */
  822. HRESULT
  823. CInputContext::GetCompositionWindow(
  824. IN HIMC hIMC,
  825. OUT LPCOMPOSITIONFORM lpCompForm
  826. )
  827. {
  828. TraceMsg(TF_API, "CInputContext::GetCompositionWindow");
  829. if (IsOnImm()) {
  830. return Imm32_GetCompositionWindow(hIMC, lpCompForm);
  831. }
  832. else {
  833. HRESULT hr;
  834. DIMM_IMCLock pIMC(hIMC);
  835. if (FAILED(hr = pIMC.GetResult()))
  836. return hr;
  837. if ((pIMC->fdwInit & INIT_COMPFORM) == INIT_COMPFORM) {
  838. *lpCompForm = pIMC->cfCompForm;
  839. return S_OK;
  840. }
  841. }
  842. return E_FAIL;
  843. }
  844. HRESULT
  845. CInputContext::SetCompositionWindow(
  846. IN DIMM_IMCLock& lpIMC,
  847. IN LPCOMPOSITIONFORM lpCompForm
  848. )
  849. {
  850. TraceMsg(TF_API, "CInputContext::SetCompositionWindow");
  851. lpIMC->cfCompForm = *lpCompForm;
  852. lpIMC->fdwInit |= INIT_COMPFORM;
  853. return S_OK;
  854. }
  855. /*
  856. * AIMM Candidate List API Methods
  857. */
  858. HRESULT
  859. CInputContext::GetCandidateList(
  860. IN HIMC hIMC,
  861. IN DWORD dwIndex,
  862. IN DWORD dwBufLen,
  863. OUT LPCANDIDATELIST lpCandList,
  864. OUT UINT* puCopied,
  865. BOOL fUnicode
  866. )
  867. {
  868. TraceMsg(TF_API, "CInputContext::GetCandidateList");
  869. return E_NOTIMPL;
  870. }
  871. HRESULT
  872. CInputContext::GetCandidateListCount(
  873. IN HIMC hIMC,
  874. OUT DWORD* lpdwListSize,
  875. OUT DWORD* pdwBufLen,
  876. BOOL fUnicode
  877. )
  878. {
  879. TraceMsg(TF_API, "CInputContext::GetCandidateListCount");
  880. return E_NOTIMPL;
  881. }
  882. /*
  883. * AIMM Candidate Window API Methods
  884. */
  885. HRESULT
  886. CInputContext::GetCandidateWindow(
  887. IN HIMC hIMC,
  888. IN DWORD dwIndex,
  889. OUT LPCANDIDATEFORM lpCandidate
  890. )
  891. {
  892. TraceMsg(TF_API, "CInputContext::GetCandidateWindow");
  893. if (IsOnImm()) {
  894. return Imm32_GetCandidateWindow(hIMC, dwIndex, lpCandidate);
  895. }
  896. else {
  897. HRESULT hr;
  898. DIMM_IMCLock pIMC(hIMC);
  899. if (FAILED(hr = pIMC.GetResult()))
  900. return hr;
  901. if (pIMC->cfCandForm[dwIndex].dwIndex == -1) {
  902. return E_FAIL;
  903. }
  904. *lpCandidate = pIMC->cfCandForm[dwIndex];
  905. }
  906. return S_OK;
  907. }
  908. HRESULT
  909. CInputContext::SetCandidateWindow(
  910. IN DIMM_IMCLock& lpIMC,
  911. IN LPCANDIDATEFORM lpCandForm
  912. )
  913. {
  914. TraceMsg(TF_API, "CInputContext::SetCandidateWindow");
  915. lpIMC->cfCandForm[lpCandForm->dwIndex] = *lpCandForm;
  916. return S_OK;
  917. }
  918. /*
  919. * AIMM Guide Line API Methods
  920. */
  921. HRESULT
  922. CInputContext::GetGuideLine(
  923. IN HIMC hIMC,
  924. IN DWORD dwIndex,
  925. IN DWORD dwBufLen,
  926. OUT CHARAW* lpBuf,
  927. OUT DWORD* pdwResult,
  928. BOOL fUnicode
  929. )
  930. {
  931. TraceMsg(TF_API, "CInputContext::GetGuideLine");
  932. return E_NOTIMPL;
  933. }
  934. /*
  935. * AIMM Notify IME API Method
  936. */
  937. HRESULT
  938. CInputContext::NotifyIME(
  939. IN HIMC hIMC,
  940. IN DWORD dwAction,
  941. IN DWORD dwIndex,
  942. IN DWORD dwValue
  943. )
  944. {
  945. TraceMsg(TF_API, "CInputContext::NotifyIME");
  946. if (IsOnImm()) {
  947. return Imm32_NotifyIME(hIMC, dwAction, dwIndex, dwValue);
  948. }
  949. return E_NOTIMPL;
  950. }
  951. /*
  952. * AIMM Menu Items API Methods
  953. */
  954. HRESULT
  955. CInputContext::GetImeMenuItems(
  956. IN HIMC hIMC,
  957. IN DWORD dwFlags,
  958. IN DWORD dwType,
  959. IN IMEMENUITEMINFOAW *pImeParentMenu,
  960. OUT IMEMENUITEMINFOAW *pImeMenu,
  961. IN DWORD dwSize,
  962. OUT DWORD* pdwResult,
  963. BOOL fUnicode
  964. )
  965. {
  966. TraceMsg(TF_API, "CInputContext::GetImeMenuItems");
  967. return E_NOTIMPL;
  968. }