xref: /reactos/dll/ime/msctfime/bridge.cpp (revision 1ee01452)
1b2ec7867SKatayama Hirofumi MZ /*
2b2ec7867SKatayama Hirofumi MZ  * PROJECT:     ReactOS msctfime.ime
3b2ec7867SKatayama Hirofumi MZ  * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4980ebf06SKatayama Hirofumi MZ  * PURPOSE:     The bridge of msctfime.ime
5b2ec7867SKatayama Hirofumi MZ  * COPYRIGHT:   Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6b2ec7867SKatayama Hirofumi MZ  */
7b2ec7867SKatayama Hirofumi MZ 
8b2ec7867SKatayama Hirofumi MZ #include "msctfime.h"
9b2ec7867SKatayama Hirofumi MZ 
10b2ec7867SKatayama Hirofumi MZ WINE_DEFAULT_DEBUG_CHANNEL(msctfime);
11b2ec7867SKatayama Hirofumi MZ 
12b2ec7867SKatayama Hirofumi MZ /// @implemented
13b2ec7867SKatayama Hirofumi MZ CicBridge::CicBridge()
14b2ec7867SKatayama Hirofumi MZ {
15b2ec7867SKatayama Hirofumi MZ     m_bImmxInited = FALSE;
16b2ec7867SKatayama Hirofumi MZ     m_bUnknown1 = FALSE;
17b2ec7867SKatayama Hirofumi MZ     m_bDeactivating = FALSE;
18b2ec7867SKatayama Hirofumi MZ     m_bUnknown2 = FALSE;
19b2ec7867SKatayama Hirofumi MZ     m_pKeystrokeMgr = NULL;
20b2ec7867SKatayama Hirofumi MZ     m_pDocMgr = NULL;
21b2ec7867SKatayama Hirofumi MZ     m_pThreadMgrEventSink = NULL;
22b2ec7867SKatayama Hirofumi MZ     m_cliendId = 0;
23b2ec7867SKatayama Hirofumi MZ     m_cRefs = 1;
24b2ec7867SKatayama Hirofumi MZ }
25b2ec7867SKatayama Hirofumi MZ 
26b2ec7867SKatayama Hirofumi MZ /// @implemented
27b2ec7867SKatayama Hirofumi MZ STDMETHODIMP CicBridge::QueryInterface(REFIID riid, LPVOID* ppvObj)
28b2ec7867SKatayama Hirofumi MZ {
29b2ec7867SKatayama Hirofumi MZ     *ppvObj = NULL;
30b2ec7867SKatayama Hirofumi MZ 
31b2ec7867SKatayama Hirofumi MZ     if (!IsEqualIID(riid, IID_ITfSysHookSink))
32b2ec7867SKatayama Hirofumi MZ         return E_NOINTERFACE;
33b2ec7867SKatayama Hirofumi MZ 
34b2ec7867SKatayama Hirofumi MZ     *ppvObj = this;
35b2ec7867SKatayama Hirofumi MZ     AddRef();
36b2ec7867SKatayama Hirofumi MZ 
37b2ec7867SKatayama Hirofumi MZ     return S_OK;
38b2ec7867SKatayama Hirofumi MZ }
39b2ec7867SKatayama Hirofumi MZ 
40b2ec7867SKatayama Hirofumi MZ /// @implemented
41b2ec7867SKatayama Hirofumi MZ STDMETHODIMP_(ULONG) CicBridge::AddRef()
42b2ec7867SKatayama Hirofumi MZ {
43b2ec7867SKatayama Hirofumi MZ     return ::InterlockedIncrement(&m_cRefs);
44b2ec7867SKatayama Hirofumi MZ }
45b2ec7867SKatayama Hirofumi MZ 
46b2ec7867SKatayama Hirofumi MZ /// @implemented
47b2ec7867SKatayama Hirofumi MZ STDMETHODIMP_(ULONG) CicBridge::Release()
48b2ec7867SKatayama Hirofumi MZ {
49b2ec7867SKatayama Hirofumi MZ     if (::InterlockedDecrement(&m_cRefs) == 0)
50b2ec7867SKatayama Hirofumi MZ     {
51b2ec7867SKatayama Hirofumi MZ         delete this;
52b2ec7867SKatayama Hirofumi MZ         return 0;
53b2ec7867SKatayama Hirofumi MZ     }
54b2ec7867SKatayama Hirofumi MZ     return m_cRefs;
55b2ec7867SKatayama Hirofumi MZ }
56b2ec7867SKatayama Hirofumi MZ 
57b2ec7867SKatayama Hirofumi MZ /// @implemented
58b2ec7867SKatayama Hirofumi MZ CicBridge::~CicBridge()
59b2ec7867SKatayama Hirofumi MZ {
60b2ec7867SKatayama Hirofumi MZ     TLS *pTLS = TLS::PeekTLS();
61b2ec7867SKatayama Hirofumi MZ     if (!pTLS || !pTLS->m_pThreadMgr)
62b2ec7867SKatayama Hirofumi MZ         return;
63b2ec7867SKatayama Hirofumi MZ 
64b2ec7867SKatayama Hirofumi MZ     if (SUCCEEDED(DeactivateIMMX(pTLS, pTLS->m_pThreadMgr)))
65b2ec7867SKatayama Hirofumi MZ         UnInitIMMX(pTLS);
66b2ec7867SKatayama Hirofumi MZ }
67b2ec7867SKatayama Hirofumi MZ 
68980ebf06SKatayama Hirofumi MZ /// @implemented
69980ebf06SKatayama Hirofumi MZ ITfDocumentMgr*
70980ebf06SKatayama Hirofumi MZ CicBridge::GetDocumentManager(_Inout_ CicIMCCLock<CTFIMECONTEXT>& imeContext)
71b2ec7867SKatayama Hirofumi MZ {
72b2ec7867SKatayama Hirofumi MZ     CicInputContext *pCicIC = imeContext.get().m_pCicIC;
73980ebf06SKatayama Hirofumi MZ     if (!pCicIC)
74980ebf06SKatayama Hirofumi MZ         return NULL;
75980ebf06SKatayama Hirofumi MZ 
76980ebf06SKatayama Hirofumi MZ     pCicIC->m_pDocumentMgr->AddRef();
77980ebf06SKatayama Hirofumi MZ     return pCicIC->m_pDocumentMgr;
78b2ec7867SKatayama Hirofumi MZ }
79b2ec7867SKatayama Hirofumi MZ 
80980ebf06SKatayama Hirofumi MZ /// @implemented
81b2ec7867SKatayama Hirofumi MZ HRESULT
82b2ec7867SKatayama Hirofumi MZ CicBridge::CreateInputContext(
83b2ec7867SKatayama Hirofumi MZ     _Inout_ TLS *pTLS,
84b2ec7867SKatayama Hirofumi MZ     _In_ HIMC hIMC)
85b2ec7867SKatayama Hirofumi MZ {
86b2ec7867SKatayama Hirofumi MZ     CicIMCLock imcLock(hIMC);
87f53f1334SKatayama Hirofumi MZ     if (FAILED(imcLock.m_hr))
88f53f1334SKatayama Hirofumi MZ         return imcLock.m_hr;
89b2ec7867SKatayama Hirofumi MZ 
90b2ec7867SKatayama Hirofumi MZ     if (!imcLock.get().hCtfImeContext)
91b2ec7867SKatayama Hirofumi MZ     {
92b2ec7867SKatayama Hirofumi MZ         HIMCC hCtfImeContext = ImmCreateIMCC(sizeof(CTFIMECONTEXT));
93b2ec7867SKatayama Hirofumi MZ         if (!hCtfImeContext)
94b2ec7867SKatayama Hirofumi MZ             return E_OUTOFMEMORY;
95b2ec7867SKatayama Hirofumi MZ         imcLock.get().hCtfImeContext = hCtfImeContext;
96b2ec7867SKatayama Hirofumi MZ     }
97b2ec7867SKatayama Hirofumi MZ 
98b2ec7867SKatayama Hirofumi MZ     CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
99b2ec7867SKatayama Hirofumi MZ     CicInputContext *pCicIC = imeContext.get().m_pCicIC;
100980ebf06SKatayama Hirofumi MZ     if (pCicIC)
101980ebf06SKatayama Hirofumi MZ         return S_OK;
102980ebf06SKatayama Hirofumi MZ 
103b2ec7867SKatayama Hirofumi MZ     pCicIC = new(cicNoThrow) CicInputContext(m_cliendId, &m_LibThread, hIMC);
104b2ec7867SKatayama Hirofumi MZ     if (!pCicIC)
105b2ec7867SKatayama Hirofumi MZ     {
106b2ec7867SKatayama Hirofumi MZ         imeContext.unlock();
107b2ec7867SKatayama Hirofumi MZ         imcLock.unlock();
108b2ec7867SKatayama Hirofumi MZ         DestroyInputContext(pTLS, hIMC);
109b2ec7867SKatayama Hirofumi MZ         return E_OUTOFMEMORY;
110b2ec7867SKatayama Hirofumi MZ     }
111b2ec7867SKatayama Hirofumi MZ 
112b2ec7867SKatayama Hirofumi MZ     if (!pTLS->m_pThreadMgr)
113b2ec7867SKatayama Hirofumi MZ     {
114b2ec7867SKatayama Hirofumi MZ         pCicIC->Release();
115b2ec7867SKatayama Hirofumi MZ         imeContext.unlock();
116b2ec7867SKatayama Hirofumi MZ         imcLock.unlock();
117b2ec7867SKatayama Hirofumi MZ         DestroyInputContext(pTLS, hIMC);
118b2ec7867SKatayama Hirofumi MZ         return E_NOINTERFACE;
119b2ec7867SKatayama Hirofumi MZ     }
120b2ec7867SKatayama Hirofumi MZ 
121b2ec7867SKatayama Hirofumi MZ     imeContext.get().m_pCicIC = pCicIC;
122b2ec7867SKatayama Hirofumi MZ 
123f53f1334SKatayama Hirofumi MZ     HRESULT hr = pCicIC->CreateInputContext(pTLS->m_pThreadMgr, imcLock);
124b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
125b2ec7867SKatayama Hirofumi MZ     {
126b2ec7867SKatayama Hirofumi MZ         pCicIC->Release();
127b2ec7867SKatayama Hirofumi MZ         imeContext.get().m_pCicIC = NULL;
128980ebf06SKatayama Hirofumi MZ         return hr;
129b2ec7867SKatayama Hirofumi MZ     }
130980ebf06SKatayama Hirofumi MZ 
131980ebf06SKatayama Hirofumi MZ     HWND hWnd = imcLock.get().hWnd;
132980ebf06SKatayama Hirofumi MZ     if (hWnd && hWnd == ::GetFocus())
133b2ec7867SKatayama Hirofumi MZ     {
134980ebf06SKatayama Hirofumi MZ         ITfDocumentMgr *pDocMgr = GetDocumentManager(imeContext);
135980ebf06SKatayama Hirofumi MZ         if (pDocMgr)
136b2ec7867SKatayama Hirofumi MZ         {
137980ebf06SKatayama Hirofumi MZ             SetAssociate(pTLS, hWnd, hIMC, pTLS->m_pThreadMgr, pDocMgr);
138980ebf06SKatayama Hirofumi MZ             pDocMgr->Release();
139b2ec7867SKatayama Hirofumi MZ         }
140b2ec7867SKatayama Hirofumi MZ     }
141b2ec7867SKatayama Hirofumi MZ 
142980ebf06SKatayama Hirofumi MZ     return hr;
143b2ec7867SKatayama Hirofumi MZ }
144b2ec7867SKatayama Hirofumi MZ 
145b2ec7867SKatayama Hirofumi MZ /// @implemented
146b2ec7867SKatayama Hirofumi MZ HRESULT CicBridge::DestroyInputContext(TLS *pTLS, HIMC hIMC)
147b2ec7867SKatayama Hirofumi MZ {
148b2ec7867SKatayama Hirofumi MZ     CicIMCLock imcLock(hIMC);
149b2ec7867SKatayama Hirofumi MZ     HRESULT hr = imcLock.m_hr;
150b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
151b2ec7867SKatayama Hirofumi MZ         return hr;
152b2ec7867SKatayama Hirofumi MZ 
153b2ec7867SKatayama Hirofumi MZ     hr = E_FAIL;
154b2ec7867SKatayama Hirofumi MZ     CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
155b2ec7867SKatayama Hirofumi MZ     if (imeContext)
156b2ec7867SKatayama Hirofumi MZ         hr = imeContext.m_hr;
157b2ec7867SKatayama Hirofumi MZ 
158b2ec7867SKatayama Hirofumi MZ     if (SUCCEEDED(hr) && !(imeContext.get().m_dwCicFlags & 1))
159b2ec7867SKatayama Hirofumi MZ     {
160b2ec7867SKatayama Hirofumi MZ         imeContext.get().m_dwCicFlags |= 1;
161b2ec7867SKatayama Hirofumi MZ 
162b2ec7867SKatayama Hirofumi MZ         CicInputContext *pCicIC = imeContext.get().m_pCicIC;
163b2ec7867SKatayama Hirofumi MZ         if (pCicIC)
164b2ec7867SKatayama Hirofumi MZ         {
165b2ec7867SKatayama Hirofumi MZ             imeContext.get().m_pCicIC = NULL;
166b2ec7867SKatayama Hirofumi MZ             hr = pCicIC->DestroyInputContext();
167b2ec7867SKatayama Hirofumi MZ             pCicIC->Release();
168b2ec7867SKatayama Hirofumi MZ             imeContext.get().m_pCicIC = NULL;
169b2ec7867SKatayama Hirofumi MZ         }
170b2ec7867SKatayama Hirofumi MZ     }
171b2ec7867SKatayama Hirofumi MZ 
172b2ec7867SKatayama Hirofumi MZ     if (imcLock.get().hCtfImeContext)
173b2ec7867SKatayama Hirofumi MZ     {
174b2ec7867SKatayama Hirofumi MZ         ImmDestroyIMCC(imcLock.get().hCtfImeContext);
175b2ec7867SKatayama Hirofumi MZ         imcLock.get().hCtfImeContext = NULL;
176b2ec7867SKatayama Hirofumi MZ         hr = S_OK;
177b2ec7867SKatayama Hirofumi MZ     }
178b2ec7867SKatayama Hirofumi MZ 
179b2ec7867SKatayama Hirofumi MZ     return hr;
180b2ec7867SKatayama Hirofumi MZ }
181b2ec7867SKatayama Hirofumi MZ 
1827d0b5482SKatayama Hirofumi MZ /// @implemented
183b2ec7867SKatayama Hirofumi MZ ITfContext *
184b2ec7867SKatayama Hirofumi MZ CicBridge::GetInputContext(CicIMCCLock<CTFIMECONTEXT>& imeContext)
185b2ec7867SKatayama Hirofumi MZ {
186b2ec7867SKatayama Hirofumi MZ     CicInputContext *pCicIC = imeContext.get().m_pCicIC;
187b2ec7867SKatayama Hirofumi MZ     if (!pCicIC)
188b2ec7867SKatayama Hirofumi MZ         return NULL;
189b2ec7867SKatayama Hirofumi MZ     return pCicIC->m_pContext;
190b2ec7867SKatayama Hirofumi MZ }
191b2ec7867SKatayama Hirofumi MZ 
1927d0b5482SKatayama Hirofumi MZ /// @implemented
193b2ec7867SKatayama Hirofumi MZ HRESULT CicBridge::OnSetOpenStatus(
194b2ec7867SKatayama Hirofumi MZ     TLS *pTLS,
195b2ec7867SKatayama Hirofumi MZ     ITfThreadMgr_P *pThreadMgr,
196b2ec7867SKatayama Hirofumi MZ     CicIMCLock& imcLock,
197b2ec7867SKatayama Hirofumi MZ     CicInputContext *pCicIC)
198b2ec7867SKatayama Hirofumi MZ {
1997d0b5482SKatayama Hirofumi MZ     if (!imcLock.get().fOpen && imcLock.ValidCompositionString())
2007d0b5482SKatayama Hirofumi MZ         pCicIC->EscbCompComplete(imcLock);
2017d0b5482SKatayama Hirofumi MZ 
2027d0b5482SKatayama Hirofumi MZ     pTLS->m_bNowOpening = TRUE;
2037d0b5482SKatayama Hirofumi MZ     HRESULT hr = SetCompartmentDWORD(m_cliendId, pThreadMgr,
2047d0b5482SKatayama Hirofumi MZ                                      GUID_COMPARTMENT_KEYBOARD_OPENCLOSE,
2057d0b5482SKatayama Hirofumi MZ                                      imcLock.get().fOpen, FALSE);
2067d0b5482SKatayama Hirofumi MZ     pTLS->m_bNowOpening = FALSE;
2077d0b5482SKatayama Hirofumi MZ     return hr;
208b2ec7867SKatayama Hirofumi MZ }
209b2ec7867SKatayama Hirofumi MZ 
210b2ec7867SKatayama Hirofumi MZ /// Selects the IME context.
211b2ec7867SKatayama Hirofumi MZ /// @implemented
212b2ec7867SKatayama Hirofumi MZ HRESULT
213b2ec7867SKatayama Hirofumi MZ CicBridge::SelectEx(
214b2ec7867SKatayama Hirofumi MZ     _Inout_ TLS *pTLS,
215b2ec7867SKatayama Hirofumi MZ     _Inout_ ITfThreadMgr_P *pThreadMgr,
216b2ec7867SKatayama Hirofumi MZ     _In_ HIMC hIMC,
217b2ec7867SKatayama Hirofumi MZ     _In_ BOOL fSelect,
218b2ec7867SKatayama Hirofumi MZ     _In_ HKL hKL)
219b2ec7867SKatayama Hirofumi MZ {
220b2ec7867SKatayama Hirofumi MZ     CicIMCLock imcLock(hIMC);
221b2ec7867SKatayama Hirofumi MZ     if (FAILED(imcLock.m_hr))
222b2ec7867SKatayama Hirofumi MZ         return imcLock.m_hr;
223b2ec7867SKatayama Hirofumi MZ 
224b2ec7867SKatayama Hirofumi MZ     CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
225b2ec7867SKatayama Hirofumi MZ     if (FAILED(imeContext.m_hr))
226b2ec7867SKatayama Hirofumi MZ         return imeContext.m_hr;
227b2ec7867SKatayama Hirofumi MZ 
228b2ec7867SKatayama Hirofumi MZ     CicInputContext *pCicIC = imeContext.get().m_pCicIC;
229b2ec7867SKatayama Hirofumi MZ     if (pCicIC)
230b2ec7867SKatayama Hirofumi MZ         pCicIC->m_bSelecting = TRUE;
231b2ec7867SKatayama Hirofumi MZ 
232b2ec7867SKatayama Hirofumi MZ     if (fSelect)
233b2ec7867SKatayama Hirofumi MZ     {
234b2ec7867SKatayama Hirofumi MZ         if (pCicIC)
23569b08be0SKatayama Hirofumi MZ             pCicIC->m_bCandidateOpen = FALSE;
236b2ec7867SKatayama Hirofumi MZ         if (imcLock.get().fOpen)
237b2ec7867SKatayama Hirofumi MZ             OnSetOpenStatus(pTLS, pThreadMgr, imcLock, pCicIC);
238b2ec7867SKatayama Hirofumi MZ     }
239b2ec7867SKatayama Hirofumi MZ     else
240b2ec7867SKatayama Hirofumi MZ     {
241b2ec7867SKatayama Hirofumi MZ         ITfContext *pContext = GetInputContext(imeContext);
242b2ec7867SKatayama Hirofumi MZ         pThreadMgr->RequestPostponedLock(pContext);
243b2ec7867SKatayama Hirofumi MZ         if (pCicIC)
244b2ec7867SKatayama Hirofumi MZ             pCicIC->m_bSelecting = FALSE;
245b2ec7867SKatayama Hirofumi MZ         if (pContext)
246b2ec7867SKatayama Hirofumi MZ             pContext->Release();
247b2ec7867SKatayama Hirofumi MZ     }
248b2ec7867SKatayama Hirofumi MZ 
249b2ec7867SKatayama Hirofumi MZ     return imeContext.m_hr;
250b2ec7867SKatayama Hirofumi MZ }
251b2ec7867SKatayama Hirofumi MZ 
252b2ec7867SKatayama Hirofumi MZ /// Used in CicBridge::EnumCreateInputContextCallback and
253b2ec7867SKatayama Hirofumi MZ /// CicBridge::EnumDestroyInputContextCallback.
254b2ec7867SKatayama Hirofumi MZ typedef struct ENUM_CREATE_DESTROY_IC
255b2ec7867SKatayama Hirofumi MZ {
256b2ec7867SKatayama Hirofumi MZ     TLS *m_pTLS;
257b2ec7867SKatayama Hirofumi MZ     CicBridge *m_pBridge;
258b2ec7867SKatayama Hirofumi MZ } ENUM_CREATE_DESTROY_IC, *PENUM_CREATE_DESTROY_IC;
259b2ec7867SKatayama Hirofumi MZ 
260b2ec7867SKatayama Hirofumi MZ /// Creates input context for the current thread.
261b2ec7867SKatayama Hirofumi MZ /// @implemented
262b2ec7867SKatayama Hirofumi MZ BOOL CALLBACK CicBridge::EnumCreateInputContextCallback(HIMC hIMC, LPARAM lParam)
263b2ec7867SKatayama Hirofumi MZ {
264b2ec7867SKatayama Hirofumi MZ     PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam;
265b2ec7867SKatayama Hirofumi MZ     pData->m_pBridge->CreateInputContext(pData->m_pTLS, hIMC);
266b2ec7867SKatayama Hirofumi MZ     return TRUE;
267b2ec7867SKatayama Hirofumi MZ }
268b2ec7867SKatayama Hirofumi MZ 
269b2ec7867SKatayama Hirofumi MZ /// Destroys input context for the current thread.
270b2ec7867SKatayama Hirofumi MZ /// @implemented
271b2ec7867SKatayama Hirofumi MZ BOOL CALLBACK CicBridge::EnumDestroyInputContextCallback(HIMC hIMC, LPARAM lParam)
272b2ec7867SKatayama Hirofumi MZ {
273b2ec7867SKatayama Hirofumi MZ     PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam;
274b2ec7867SKatayama Hirofumi MZ     pData->m_pBridge->DestroyInputContext(pData->m_pTLS, hIMC);
275b2ec7867SKatayama Hirofumi MZ     return TRUE;
276b2ec7867SKatayama Hirofumi MZ }
277b2ec7867SKatayama Hirofumi MZ 
278b2ec7867SKatayama Hirofumi MZ /// @implemented
279b2ec7867SKatayama Hirofumi MZ HRESULT
280b2ec7867SKatayama Hirofumi MZ CicBridge::ActivateIMMX(
281b2ec7867SKatayama Hirofumi MZ     _Inout_ TLS *pTLS,
282b2ec7867SKatayama Hirofumi MZ     _Inout_ ITfThreadMgr_P *pThreadMgr)
283b2ec7867SKatayama Hirofumi MZ {
284b2ec7867SKatayama Hirofumi MZ     HRESULT hr = pThreadMgr->ActivateEx(&m_cliendId, 1);
285b2ec7867SKatayama Hirofumi MZ     if (hr != S_OK)
286b2ec7867SKatayama Hirofumi MZ     {
287b2ec7867SKatayama Hirofumi MZ         m_cliendId = 0;
288b2ec7867SKatayama Hirofumi MZ         return E_FAIL;
289b2ec7867SKatayama Hirofumi MZ     }
290b2ec7867SKatayama Hirofumi MZ 
291b2ec7867SKatayama Hirofumi MZ     if (m_cActivateLocks++ != 0)
292b2ec7867SKatayama Hirofumi MZ         return S_OK;
293b2ec7867SKatayama Hirofumi MZ 
294b2ec7867SKatayama Hirofumi MZ     ITfSourceSingle *pSource = NULL;
295b2ec7867SKatayama Hirofumi MZ     hr = pThreadMgr->QueryInterface(IID_ITfSourceSingle, (void**)&pSource);
296b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
297b2ec7867SKatayama Hirofumi MZ     {
298b2ec7867SKatayama Hirofumi MZ         DeactivateIMMX(pTLS, pThreadMgr);
299b2ec7867SKatayama Hirofumi MZ         return hr;
300b2ec7867SKatayama Hirofumi MZ     }
301b2ec7867SKatayama Hirofumi MZ 
302b2ec7867SKatayama Hirofumi MZ     CFunctionProvider *pProvider = new(cicNoThrow) CFunctionProvider(m_cliendId);
303b2ec7867SKatayama Hirofumi MZ     if (!pProvider)
304b2ec7867SKatayama Hirofumi MZ     {
305b2ec7867SKatayama Hirofumi MZ         hr = E_FAIL;
306b2ec7867SKatayama Hirofumi MZ         goto Finish;
307b2ec7867SKatayama Hirofumi MZ     }
308b2ec7867SKatayama Hirofumi MZ 
309b2ec7867SKatayama Hirofumi MZ     pSource->AdviseSingleSink(m_cliendId, IID_ITfFunctionProvider, pProvider);
310b2ec7867SKatayama Hirofumi MZ     pProvider->Release();
311b2ec7867SKatayama Hirofumi MZ 
312b2ec7867SKatayama Hirofumi MZ     if (!m_pDocMgr)
313b2ec7867SKatayama Hirofumi MZ     {
314b2ec7867SKatayama Hirofumi MZ         hr = pThreadMgr->CreateDocumentMgr(&m_pDocMgr);
315b2ec7867SKatayama Hirofumi MZ         if (FAILED(hr))
316b2ec7867SKatayama Hirofumi MZ         {
317b2ec7867SKatayama Hirofumi MZ             hr = E_FAIL;
318b2ec7867SKatayama Hirofumi MZ             goto Finish;
319b2ec7867SKatayama Hirofumi MZ         }
320b2ec7867SKatayama Hirofumi MZ 
321b2ec7867SKatayama Hirofumi MZ         SetCompartmentDWORD(m_cliendId, m_pDocMgr, GUID_COMPARTMENT_CTFIME_DIMFLAGS, TRUE, FALSE);
322b2ec7867SKatayama Hirofumi MZ     }
323b2ec7867SKatayama Hirofumi MZ 
324b2ec7867SKatayama Hirofumi MZ     pThreadMgr->SetSysHookSink(this);
325b2ec7867SKatayama Hirofumi MZ 
326b2ec7867SKatayama Hirofumi MZ     hr = S_OK;
327b2ec7867SKatayama Hirofumi MZ     if (pTLS->m_bDestroyed)
328b2ec7867SKatayama Hirofumi MZ     {
329b2ec7867SKatayama Hirofumi MZ         ENUM_CREATE_DESTROY_IC Data = { pTLS, this };
330b2ec7867SKatayama Hirofumi MZ         ImmEnumInputContext(0, CicBridge::EnumCreateInputContextCallback, (LPARAM)&Data);
331b2ec7867SKatayama Hirofumi MZ     }
332b2ec7867SKatayama Hirofumi MZ 
333b2ec7867SKatayama Hirofumi MZ Finish:
334b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
335b2ec7867SKatayama Hirofumi MZ         DeactivateIMMX(pTLS, pThreadMgr);
336b2ec7867SKatayama Hirofumi MZ     if (pSource)
337b2ec7867SKatayama Hirofumi MZ         pSource->Release();
338b2ec7867SKatayama Hirofumi MZ     return hr;
339b2ec7867SKatayama Hirofumi MZ }
340b2ec7867SKatayama Hirofumi MZ 
341b2ec7867SKatayama Hirofumi MZ /// @implemented
342b2ec7867SKatayama Hirofumi MZ HRESULT
343b2ec7867SKatayama Hirofumi MZ CicBridge::DeactivateIMMX(
344b2ec7867SKatayama Hirofumi MZ     _Inout_ TLS *pTLS,
345b2ec7867SKatayama Hirofumi MZ     _Inout_ ITfThreadMgr_P *pThreadMgr)
346b2ec7867SKatayama Hirofumi MZ {
347b2ec7867SKatayama Hirofumi MZ     if (m_bDeactivating)
348b2ec7867SKatayama Hirofumi MZ         return TRUE;
349b2ec7867SKatayama Hirofumi MZ 
350b2ec7867SKatayama Hirofumi MZ     m_bDeactivating = TRUE;
351b2ec7867SKatayama Hirofumi MZ 
352b2ec7867SKatayama Hirofumi MZ     if (m_cliendId)
353b2ec7867SKatayama Hirofumi MZ     {
354b2ec7867SKatayama Hirofumi MZ         ENUM_CREATE_DESTROY_IC Data = { pTLS, this };
355b2ec7867SKatayama Hirofumi MZ         ImmEnumInputContext(0, CicBridge::EnumDestroyInputContextCallback, (LPARAM)&Data);
356b2ec7867SKatayama Hirofumi MZ         pTLS->m_bDestroyed = TRUE;
357b2ec7867SKatayama Hirofumi MZ 
358b2ec7867SKatayama Hirofumi MZ         ITfSourceSingle *pSource = NULL;
359b2ec7867SKatayama Hirofumi MZ         if (pThreadMgr->QueryInterface(IID_ITfSourceSingle, (void **)&pSource) == S_OK)
360b2ec7867SKatayama Hirofumi MZ             pSource->UnadviseSingleSink(m_cliendId, IID_ITfFunctionProvider);
361b2ec7867SKatayama Hirofumi MZ 
362b2ec7867SKatayama Hirofumi MZ         m_cliendId = 0;
363b2ec7867SKatayama Hirofumi MZ 
364b2ec7867SKatayama Hirofumi MZ         while (m_cActivateLocks > 0)
365b2ec7867SKatayama Hirofumi MZ         {
366b2ec7867SKatayama Hirofumi MZ             --m_cActivateLocks;
367b2ec7867SKatayama Hirofumi MZ             pThreadMgr->Deactivate();
368b2ec7867SKatayama Hirofumi MZ         }
369b2ec7867SKatayama Hirofumi MZ 
370b2ec7867SKatayama Hirofumi MZ         if (pSource)
371b2ec7867SKatayama Hirofumi MZ             pSource->Release();
372b2ec7867SKatayama Hirofumi MZ     }
373b2ec7867SKatayama Hirofumi MZ 
374b2ec7867SKatayama Hirofumi MZ     if (m_pDocMgr)
375b2ec7867SKatayama Hirofumi MZ     {
376b2ec7867SKatayama Hirofumi MZ         m_pDocMgr->Release();
377b2ec7867SKatayama Hirofumi MZ         m_pDocMgr = NULL;
378b2ec7867SKatayama Hirofumi MZ     }
379b2ec7867SKatayama Hirofumi MZ 
380b2ec7867SKatayama Hirofumi MZ     pThreadMgr->SetSysHookSink(NULL);
381b2ec7867SKatayama Hirofumi MZ 
382b2ec7867SKatayama Hirofumi MZ     m_bDeactivating = FALSE;
383b2ec7867SKatayama Hirofumi MZ 
384b2ec7867SKatayama Hirofumi MZ     return S_OK;
385b2ec7867SKatayama Hirofumi MZ }
386b2ec7867SKatayama Hirofumi MZ 
387b2ec7867SKatayama Hirofumi MZ /// @implemented
388b2ec7867SKatayama Hirofumi MZ HRESULT
389b2ec7867SKatayama Hirofumi MZ CicBridge::InitIMMX(_Inout_ TLS *pTLS)
390b2ec7867SKatayama Hirofumi MZ {
391b2ec7867SKatayama Hirofumi MZ     if (m_bImmxInited)
392b2ec7867SKatayama Hirofumi MZ         return S_OK;
393b2ec7867SKatayama Hirofumi MZ 
394b2ec7867SKatayama Hirofumi MZ     HRESULT hr = S_OK;
395b2ec7867SKatayama Hirofumi MZ     if (!pTLS->m_pThreadMgr)
396b2ec7867SKatayama Hirofumi MZ     {
397b2ec7867SKatayama Hirofumi MZ         ITfThreadMgr *pThreadMgr = NULL;
398b2ec7867SKatayama Hirofumi MZ         hr = TF_CreateThreadMgr(&pThreadMgr);
399b2ec7867SKatayama Hirofumi MZ         if (FAILED(hr))
400b2ec7867SKatayama Hirofumi MZ             return E_FAIL;
401b2ec7867SKatayama Hirofumi MZ 
402b2ec7867SKatayama Hirofumi MZ         hr = pThreadMgr->QueryInterface(IID_ITfThreadMgr_P, (void **)&pTLS->m_pThreadMgr);
403b2ec7867SKatayama Hirofumi MZ         if (pThreadMgr)
404b2ec7867SKatayama Hirofumi MZ             pThreadMgr->Release();
405b2ec7867SKatayama Hirofumi MZ         if (FAILED(hr))
406b2ec7867SKatayama Hirofumi MZ             return E_FAIL;
407b2ec7867SKatayama Hirofumi MZ     }
408b2ec7867SKatayama Hirofumi MZ 
409b2ec7867SKatayama Hirofumi MZ     if (!m_pThreadMgrEventSink)
410b2ec7867SKatayama Hirofumi MZ     {
411b2ec7867SKatayama Hirofumi MZ         m_pThreadMgrEventSink =
412b2ec7867SKatayama Hirofumi MZ             new(cicNoThrow) CThreadMgrEventSink(CThreadMgrEventSink::DIMCallback, NULL, NULL);
413b2ec7867SKatayama Hirofumi MZ         if (!m_pThreadMgrEventSink)
414b2ec7867SKatayama Hirofumi MZ         {
415b2ec7867SKatayama Hirofumi MZ             UnInitIMMX(pTLS);
416b2ec7867SKatayama Hirofumi MZ             return E_FAIL;
417b2ec7867SKatayama Hirofumi MZ         }
418b2ec7867SKatayama Hirofumi MZ     }
419b2ec7867SKatayama Hirofumi MZ 
420b2ec7867SKatayama Hirofumi MZ     m_pThreadMgrEventSink->SetCallbackPV(m_pThreadMgrEventSink);
421b2ec7867SKatayama Hirofumi MZ     m_pThreadMgrEventSink->_Advise(pTLS->m_pThreadMgr);
422b2ec7867SKatayama Hirofumi MZ 
423b2ec7867SKatayama Hirofumi MZ     if (!pTLS->m_pProfile)
424b2ec7867SKatayama Hirofumi MZ     {
425b2ec7867SKatayama Hirofumi MZ         pTLS->m_pProfile = new(cicNoThrow) CicProfile();
426b2ec7867SKatayama Hirofumi MZ         if (!pTLS->m_pProfile)
427b2ec7867SKatayama Hirofumi MZ             return E_OUTOFMEMORY;
428b2ec7867SKatayama Hirofumi MZ 
429b2ec7867SKatayama Hirofumi MZ         hr = pTLS->m_pProfile->InitProfileInstance(pTLS);
430b2ec7867SKatayama Hirofumi MZ         if (FAILED(hr))
431b2ec7867SKatayama Hirofumi MZ         {
432b2ec7867SKatayama Hirofumi MZ             UnInitIMMX(pTLS);
433b2ec7867SKatayama Hirofumi MZ             return E_FAIL;
434b2ec7867SKatayama Hirofumi MZ         }
435b2ec7867SKatayama Hirofumi MZ     }
436b2ec7867SKatayama Hirofumi MZ 
437b2ec7867SKatayama Hirofumi MZ     hr = pTLS->m_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr_P, (void **)&m_pKeystrokeMgr);
438b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
439b2ec7867SKatayama Hirofumi MZ     {
440b2ec7867SKatayama Hirofumi MZ         UnInitIMMX(pTLS);
441b2ec7867SKatayama Hirofumi MZ         return E_FAIL;
442b2ec7867SKatayama Hirofumi MZ     }
443b2ec7867SKatayama Hirofumi MZ 
444b2ec7867SKatayama Hirofumi MZ     hr = InitDisplayAttrbuteLib(&m_LibThread);
445b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
446b2ec7867SKatayama Hirofumi MZ     {
447b2ec7867SKatayama Hirofumi MZ         UnInitIMMX(pTLS);
448b2ec7867SKatayama Hirofumi MZ         return E_FAIL;
449b2ec7867SKatayama Hirofumi MZ     }
450b2ec7867SKatayama Hirofumi MZ 
451b2ec7867SKatayama Hirofumi MZ     m_bImmxInited = TRUE;
452b2ec7867SKatayama Hirofumi MZ     return S_OK;
453b2ec7867SKatayama Hirofumi MZ }
454b2ec7867SKatayama Hirofumi MZ 
455b2ec7867SKatayama Hirofumi MZ /// @implemented
456b2ec7867SKatayama Hirofumi MZ BOOL CicBridge::UnInitIMMX(_Inout_ TLS *pTLS)
457b2ec7867SKatayama Hirofumi MZ {
458b2ec7867SKatayama Hirofumi MZ     UninitDisplayAttrbuteLib(&m_LibThread);
459b2ec7867SKatayama Hirofumi MZ     TFUninitLib_Thread(&m_LibThread);
460b2ec7867SKatayama Hirofumi MZ 
461b2ec7867SKatayama Hirofumi MZ     if (m_pKeystrokeMgr)
462b2ec7867SKatayama Hirofumi MZ     {
463b2ec7867SKatayama Hirofumi MZ         m_pKeystrokeMgr->Release();
464b2ec7867SKatayama Hirofumi MZ         m_pKeystrokeMgr = NULL;
465b2ec7867SKatayama Hirofumi MZ     }
466b2ec7867SKatayama Hirofumi MZ 
467b2ec7867SKatayama Hirofumi MZ     if (pTLS->m_pProfile)
468b2ec7867SKatayama Hirofumi MZ     {
469b2ec7867SKatayama Hirofumi MZ         pTLS->m_pProfile->Release();
470b2ec7867SKatayama Hirofumi MZ         pTLS->m_pProfile = NULL;
471b2ec7867SKatayama Hirofumi MZ     }
472b2ec7867SKatayama Hirofumi MZ 
473b2ec7867SKatayama Hirofumi MZ     if (m_pThreadMgrEventSink)
474b2ec7867SKatayama Hirofumi MZ     {
475b2ec7867SKatayama Hirofumi MZ         m_pThreadMgrEventSink->_Unadvise();
476b2ec7867SKatayama Hirofumi MZ         m_pThreadMgrEventSink->Release();
477b2ec7867SKatayama Hirofumi MZ         m_pThreadMgrEventSink = NULL;
478b2ec7867SKatayama Hirofumi MZ     }
479b2ec7867SKatayama Hirofumi MZ 
480b2ec7867SKatayama Hirofumi MZ     if (pTLS->m_pThreadMgr)
481b2ec7867SKatayama Hirofumi MZ     {
482b2ec7867SKatayama Hirofumi MZ         pTLS->m_pThreadMgr->Release();
483b2ec7867SKatayama Hirofumi MZ         pTLS->m_pThreadMgr = NULL;
484b2ec7867SKatayama Hirofumi MZ     }
485b2ec7867SKatayama Hirofumi MZ 
486b2ec7867SKatayama Hirofumi MZ     m_bImmxInited = FALSE;
487b2ec7867SKatayama Hirofumi MZ     return TRUE;
488b2ec7867SKatayama Hirofumi MZ }
489b2ec7867SKatayama Hirofumi MZ 
490b2ec7867SKatayama Hirofumi MZ /// @implemented
491b2ec7867SKatayama Hirofumi MZ STDMETHODIMP CicBridge::OnPreFocusDIM(HWND hwnd)
492b2ec7867SKatayama Hirofumi MZ {
493b2ec7867SKatayama Hirofumi MZ     return S_OK;
494b2ec7867SKatayama Hirofumi MZ }
495b2ec7867SKatayama Hirofumi MZ 
496b2ec7867SKatayama Hirofumi MZ /// @unimplemented
497b2ec7867SKatayama Hirofumi MZ STDMETHODIMP CicBridge::OnSysKeyboardProc(UINT, LONG)
498b2ec7867SKatayama Hirofumi MZ {
499b2ec7867SKatayama Hirofumi MZ     return E_NOTIMPL;
500b2ec7867SKatayama Hirofumi MZ }
501b2ec7867SKatayama Hirofumi MZ 
502b2ec7867SKatayama Hirofumi MZ /// @implemented
503b2ec7867SKatayama Hirofumi MZ STDMETHODIMP CicBridge::OnSysShellProc(INT, UINT, LONG)
504b2ec7867SKatayama Hirofumi MZ {
505b2ec7867SKatayama Hirofumi MZ     return S_OK;
506b2ec7867SKatayama Hirofumi MZ }
507b2ec7867SKatayama Hirofumi MZ 
508b2ec7867SKatayama Hirofumi MZ /// @implemented
509b2ec7867SKatayama Hirofumi MZ void
510b2ec7867SKatayama Hirofumi MZ CicBridge::PostTransMsg(
511b2ec7867SKatayama Hirofumi MZ     _In_ HWND hWnd,
512b2ec7867SKatayama Hirofumi MZ     _In_ INT cTransMsgs,
513b2ec7867SKatayama Hirofumi MZ     _In_ const TRANSMSG *pTransMsgs)
514b2ec7867SKatayama Hirofumi MZ {
515b2ec7867SKatayama Hirofumi MZ     for (INT i = 0; i < cTransMsgs; ++i, ++pTransMsgs)
516b2ec7867SKatayama Hirofumi MZ     {
517b2ec7867SKatayama Hirofumi MZ         ::PostMessageW(hWnd, pTransMsgs->message, pTransMsgs->wParam, pTransMsgs->lParam);
518b2ec7867SKatayama Hirofumi MZ     }
519b2ec7867SKatayama Hirofumi MZ }
520b2ec7867SKatayama Hirofumi MZ 
521b2ec7867SKatayama Hirofumi MZ /// @implemented
522b2ec7867SKatayama Hirofumi MZ HRESULT
523b2ec7867SKatayama Hirofumi MZ CicBridge::ConfigureGeneral(
524b2ec7867SKatayama Hirofumi MZ     _Inout_ TLS* pTLS,
525b2ec7867SKatayama Hirofumi MZ     _In_ ITfThreadMgr *pThreadMgr,
526b2ec7867SKatayama Hirofumi MZ     _In_ HKL hKL,
527b2ec7867SKatayama Hirofumi MZ     _In_ HWND hWnd)
528b2ec7867SKatayama Hirofumi MZ {
529b2ec7867SKatayama Hirofumi MZ     CicProfile *pProfile = pTLS->m_pProfile;
530b2ec7867SKatayama Hirofumi MZ     if (!pProfile)
531b2ec7867SKatayama Hirofumi MZ         return E_OUTOFMEMORY;
532b2ec7867SKatayama Hirofumi MZ 
533b2ec7867SKatayama Hirofumi MZ     TF_LANGUAGEPROFILE profile;
534b2ec7867SKatayama Hirofumi MZ     HRESULT hr = pProfile->GetActiveLanguageProfile(hKL, GUID_TFCAT_TIP_KEYBOARD, &profile);
535b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
536b2ec7867SKatayama Hirofumi MZ         return hr;
537b2ec7867SKatayama Hirofumi MZ 
538b2ec7867SKatayama Hirofumi MZ     ITfFunctionProvider *pProvider = NULL;
539b2ec7867SKatayama Hirofumi MZ     hr = pThreadMgr->GetFunctionProvider(profile.clsid, &pProvider);
540b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
541b2ec7867SKatayama Hirofumi MZ         return hr;
542b2ec7867SKatayama Hirofumi MZ 
543b2ec7867SKatayama Hirofumi MZ     ITfFnConfigure *pFnConfigure = NULL;
544b2ec7867SKatayama Hirofumi MZ     hr = pProvider->GetFunction(GUID_NULL, IID_ITfFnConfigure, (IUnknown**)&pFnConfigure);
545b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
546b2ec7867SKatayama Hirofumi MZ     {
547b2ec7867SKatayama Hirofumi MZ         pProvider->Release();
548b2ec7867SKatayama Hirofumi MZ         return hr;
549b2ec7867SKatayama Hirofumi MZ     }
550b2ec7867SKatayama Hirofumi MZ 
551b2ec7867SKatayama Hirofumi MZ     hr = pFnConfigure->Show(hWnd, profile.langid, profile.guidProfile);
552b2ec7867SKatayama Hirofumi MZ 
553b2ec7867SKatayama Hirofumi MZ     pFnConfigure->Release();
554b2ec7867SKatayama Hirofumi MZ     pProvider->Release();
555b2ec7867SKatayama Hirofumi MZ     return hr;
556b2ec7867SKatayama Hirofumi MZ }
557b2ec7867SKatayama Hirofumi MZ 
558b2ec7867SKatayama Hirofumi MZ /// @implemented
559b2ec7867SKatayama Hirofumi MZ HRESULT
560b2ec7867SKatayama Hirofumi MZ CicBridge::ConfigureRegisterWord(
561b2ec7867SKatayama Hirofumi MZ     _Inout_ TLS* pTLS,
562b2ec7867SKatayama Hirofumi MZ     _In_ ITfThreadMgr *pThreadMgr,
563b2ec7867SKatayama Hirofumi MZ     _In_ HKL hKL,
564b2ec7867SKatayama Hirofumi MZ     _In_ HWND hWnd,
565b2ec7867SKatayama Hirofumi MZ     _Inout_opt_ LPVOID lpData)
566b2ec7867SKatayama Hirofumi MZ {
567b2ec7867SKatayama Hirofumi MZ     CicProfile *pProfile = pTLS->m_pProfile;
568b2ec7867SKatayama Hirofumi MZ     if (!pProfile)
569b2ec7867SKatayama Hirofumi MZ         return E_OUTOFMEMORY;
570b2ec7867SKatayama Hirofumi MZ 
571b2ec7867SKatayama Hirofumi MZ     TF_LANGUAGEPROFILE profile;
572b2ec7867SKatayama Hirofumi MZ     HRESULT hr = pProfile->GetActiveLanguageProfile(hKL, GUID_TFCAT_TIP_KEYBOARD, &profile);
573b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
574b2ec7867SKatayama Hirofumi MZ         return hr;
575b2ec7867SKatayama Hirofumi MZ 
576b2ec7867SKatayama Hirofumi MZ     ITfFunctionProvider *pProvider = NULL;
577b2ec7867SKatayama Hirofumi MZ     hr = pThreadMgr->GetFunctionProvider(profile.clsid, &pProvider);
578b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
579b2ec7867SKatayama Hirofumi MZ         return hr;
580b2ec7867SKatayama Hirofumi MZ 
581b2ec7867SKatayama Hirofumi MZ     ITfFnConfigureRegisterWord *pFunction = NULL;
582b2ec7867SKatayama Hirofumi MZ     hr = pProvider->GetFunction(GUID_NULL, IID_ITfFnConfigureRegisterWord, (IUnknown**)&pFunction);
583b2ec7867SKatayama Hirofumi MZ     if (FAILED(hr))
584b2ec7867SKatayama Hirofumi MZ     {
585b2ec7867SKatayama Hirofumi MZ         pProvider->Release();
586b2ec7867SKatayama Hirofumi MZ         return hr;
587b2ec7867SKatayama Hirofumi MZ     }
588b2ec7867SKatayama Hirofumi MZ 
589b2ec7867SKatayama Hirofumi MZ     REGISTERWORDW* pRegWord = (REGISTERWORDW*)lpData;
590b2ec7867SKatayama Hirofumi MZ     if (pRegWord)
591b2ec7867SKatayama Hirofumi MZ     {
592b2ec7867SKatayama Hirofumi MZ         if (pRegWord->lpWord)
593b2ec7867SKatayama Hirofumi MZ         {
594b2ec7867SKatayama Hirofumi MZ             hr = E_OUTOFMEMORY;
595b2ec7867SKatayama Hirofumi MZ             BSTR bstrWord = SysAllocString(pRegWord->lpWord);
596b2ec7867SKatayama Hirofumi MZ             if (bstrWord)
597b2ec7867SKatayama Hirofumi MZ             {
598b2ec7867SKatayama Hirofumi MZ                 hr = pFunction->Show(hWnd, profile.langid, profile.guidProfile, bstrWord);
599b2ec7867SKatayama Hirofumi MZ                 SysFreeString(bstrWord);
600b2ec7867SKatayama Hirofumi MZ             }
601b2ec7867SKatayama Hirofumi MZ         }
602b2ec7867SKatayama Hirofumi MZ         else
603b2ec7867SKatayama Hirofumi MZ         {
604b2ec7867SKatayama Hirofumi MZ             hr = pFunction->Show(hWnd, profile.langid, profile.guidProfile, NULL);
605b2ec7867SKatayama Hirofumi MZ         }
606b2ec7867SKatayama Hirofumi MZ     }
607b2ec7867SKatayama Hirofumi MZ 
608b2ec7867SKatayama Hirofumi MZ     pProvider->Release();
609b2ec7867SKatayama Hirofumi MZ     pFunction->Release();
610b2ec7867SKatayama Hirofumi MZ     return hr;
611b2ec7867SKatayama Hirofumi MZ }
612980ebf06SKatayama Hirofumi MZ 
613980ebf06SKatayama Hirofumi MZ /// @unimplemented
614980ebf06SKatayama Hirofumi MZ void CicBridge::SetAssociate(
615980ebf06SKatayama Hirofumi MZ     TLS *pTLS,
616980ebf06SKatayama Hirofumi MZ     HWND hWnd,
617980ebf06SKatayama Hirofumi MZ     HIMC hIMC,
618980ebf06SKatayama Hirofumi MZ     ITfThreadMgr_P *pThreadMgr,
619980ebf06SKatayama Hirofumi MZ     ITfDocumentMgr *pDocMgr)
620980ebf06SKatayama Hirofumi MZ {
621980ebf06SKatayama Hirofumi MZ     //FIXME
622980ebf06SKatayama Hirofumi MZ }
623980ebf06SKatayama Hirofumi MZ 
624980ebf06SKatayama Hirofumi MZ HRESULT
625980ebf06SKatayama Hirofumi MZ CicBridge::SetActiveContextAlways(TLS *pTLS, HIMC hIMC, BOOL fActive, HWND hWnd, HKL hKL)
626980ebf06SKatayama Hirofumi MZ {
627980ebf06SKatayama Hirofumi MZ     auto pThreadMgr = pTLS->m_pThreadMgr;
628980ebf06SKatayama Hirofumi MZ     if (!pThreadMgr)
629980ebf06SKatayama Hirofumi MZ         return E_OUTOFMEMORY;
630980ebf06SKatayama Hirofumi MZ 
631980ebf06SKatayama Hirofumi MZ     if (fActive)
632980ebf06SKatayama Hirofumi MZ     {
633980ebf06SKatayama Hirofumi MZ         if (!hIMC)
634980ebf06SKatayama Hirofumi MZ         {
635980ebf06SKatayama Hirofumi MZ             SetAssociate(pTLS, hWnd, hIMC, pThreadMgr, m_pDocMgr);
636980ebf06SKatayama Hirofumi MZ             return S_OK;
637980ebf06SKatayama Hirofumi MZ         }
638980ebf06SKatayama Hirofumi MZ 
639980ebf06SKatayama Hirofumi MZ         CicIMCLock imcLock(hIMC);
640980ebf06SKatayama Hirofumi MZ         if (FAILED(imcLock.m_hr))
641980ebf06SKatayama Hirofumi MZ             return imcLock.m_hr;
642980ebf06SKatayama Hirofumi MZ 
643980ebf06SKatayama Hirofumi MZ         CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
644980ebf06SKatayama Hirofumi MZ         if (FAILED(imeContext.m_hr))
645980ebf06SKatayama Hirofumi MZ             return imeContext.m_hr;
646980ebf06SKatayama Hirofumi MZ 
647980ebf06SKatayama Hirofumi MZ         if (hIMC == ::ImmGetContext(hWnd))
648980ebf06SKatayama Hirofumi MZ         {
649980ebf06SKatayama Hirofumi MZ             ITfDocumentMgr *pDocMgr = GetDocumentManager(imeContext);
650980ebf06SKatayama Hirofumi MZ             if (pDocMgr)
651980ebf06SKatayama Hirofumi MZ             {
652980ebf06SKatayama Hirofumi MZ                 SetAssociate(pTLS, imcLock.get().hWnd, hIMC, pThreadMgr, pDocMgr);
653980ebf06SKatayama Hirofumi MZ                 pDocMgr->Release();
654980ebf06SKatayama Hirofumi MZ             }
655980ebf06SKatayama Hirofumi MZ         }
656980ebf06SKatayama Hirofumi MZ 
657980ebf06SKatayama Hirofumi MZ         return S_OK;
658980ebf06SKatayama Hirofumi MZ     }
659980ebf06SKatayama Hirofumi MZ 
660980ebf06SKatayama Hirofumi MZ     if (hIMC && !IsEALang(LOWORD(hKL)))
661980ebf06SKatayama Hirofumi MZ     {
662980ebf06SKatayama Hirofumi MZ         CicIMCLock imcLock(hIMC);
663980ebf06SKatayama Hirofumi MZ         if (FAILED(imcLock.m_hr))
664980ebf06SKatayama Hirofumi MZ             return imcLock.m_hr;
665980ebf06SKatayama Hirofumi MZ 
666980ebf06SKatayama Hirofumi MZ         CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
667980ebf06SKatayama Hirofumi MZ         if (FAILED(imeContext.m_hr))
668980ebf06SKatayama Hirofumi MZ             return imeContext.m_hr;
669980ebf06SKatayama Hirofumi MZ 
670980ebf06SKatayama Hirofumi MZ         CicInputContext *pCicIC = imeContext.get().m_pCicIC;
671980ebf06SKatayama Hirofumi MZ         if (!pCicIC->m_dwUnknown6_5[2] && !pCicIC->m_dwUnknown6_5[3])
672980ebf06SKatayama Hirofumi MZ             ::ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
673980ebf06SKatayama Hirofumi MZ     }
674980ebf06SKatayama Hirofumi MZ 
675980ebf06SKatayama Hirofumi MZ     if (!hIMC || (::GetFocus() != hWnd) || (hIMC != ::ImmGetContext(hWnd)))
676980ebf06SKatayama Hirofumi MZ         SetAssociate(pTLS, hWnd, hIMC, pThreadMgr, m_pDocMgr);
677980ebf06SKatayama Hirofumi MZ 
678980ebf06SKatayama Hirofumi MZ     return S_OK;
679980ebf06SKatayama Hirofumi MZ }
680980ebf06SKatayama Hirofumi MZ 
681980ebf06SKatayama Hirofumi MZ /// @unimplemented
682980ebf06SKatayama Hirofumi MZ HRESULT CicBridge::Notify(
683980ebf06SKatayama Hirofumi MZ     TLS *pTLS,
684980ebf06SKatayama Hirofumi MZ     ITfThreadMgr *pThreadMgr,
685980ebf06SKatayama Hirofumi MZ     HIMC hIMC,
686980ebf06SKatayama Hirofumi MZ     DWORD dwAction,
687980ebf06SKatayama Hirofumi MZ     DWORD dwIndex,
688980ebf06SKatayama Hirofumi MZ     DWORD_PTR dwValue)
689980ebf06SKatayama Hirofumi MZ {
690980ebf06SKatayama Hirofumi MZ     return E_NOTIMPL; // FIXME
691980ebf06SKatayama Hirofumi MZ }
692febb589eSKatayama Hirofumi MZ 
693febb589eSKatayama Hirofumi MZ /// @unimplemented
694febb589eSKatayama Hirofumi MZ BOOL CicBridge::ProcessKey(
695febb589eSKatayama Hirofumi MZ     TLS *pTLS,
696febb589eSKatayama Hirofumi MZ     ITfThreadMgr_P *pThreadMgr,
697febb589eSKatayama Hirofumi MZ     HIMC hIMC,
698febb589eSKatayama Hirofumi MZ     WPARAM wParam,
699febb589eSKatayama Hirofumi MZ     LPARAM lParam,
700febb589eSKatayama Hirofumi MZ     CONST LPBYTE lpbKeyState,
701febb589eSKatayama Hirofumi MZ     INT *pnUnknown60)
702febb589eSKatayama Hirofumi MZ {
703febb589eSKatayama Hirofumi MZ     return FALSE; // FIXME
704febb589eSKatayama Hirofumi MZ }
705febb589eSKatayama Hirofumi MZ 
706febb589eSKatayama Hirofumi MZ /// @unimplemented
707febb589eSKatayama Hirofumi MZ HRESULT
708febb589eSKatayama Hirofumi MZ CicBridge::ToAsciiEx(
709febb589eSKatayama Hirofumi MZ     TLS *pTLS,
710febb589eSKatayama Hirofumi MZ     ITfThreadMgr_P *pThreadMgr,
711febb589eSKatayama Hirofumi MZ     UINT uVirtKey,
712febb589eSKatayama Hirofumi MZ     UINT uScanCode,
713febb589eSKatayama Hirofumi MZ     CONST LPBYTE lpbKeyState,
714febb589eSKatayama Hirofumi MZ     LPTRANSMSGLIST lpTransBuf,
715febb589eSKatayama Hirofumi MZ     UINT fuState,
716febb589eSKatayama Hirofumi MZ     HIMC hIMC,
717febb589eSKatayama Hirofumi MZ     UINT *pResult)
718febb589eSKatayama Hirofumi MZ {
719febb589eSKatayama Hirofumi MZ     return E_NOTIMPL; // FIXME
720febb589eSKatayama Hirofumi MZ }
721febb589eSKatayama Hirofumi MZ 
722febb589eSKatayama Hirofumi MZ /// @unimplemented
723febb589eSKatayama Hirofumi MZ BOOL
724febb589eSKatayama Hirofumi MZ CicBridge::SetCompositionString(
725febb589eSKatayama Hirofumi MZ     TLS *pTLS,
726febb589eSKatayama Hirofumi MZ     ITfThreadMgr_P *pThreadMgr,
727febb589eSKatayama Hirofumi MZ     HIMC hIMC,
728febb589eSKatayama Hirofumi MZ     DWORD dwIndex,
729febb589eSKatayama Hirofumi MZ     LPCVOID lpComp,
730febb589eSKatayama Hirofumi MZ     DWORD dwCompLen,
731febb589eSKatayama Hirofumi MZ     LPCVOID lpRead,
732febb589eSKatayama Hirofumi MZ     DWORD dwReadLen)
733febb589eSKatayama Hirofumi MZ {
734febb589eSKatayama Hirofumi MZ     return FALSE; // FIXME
735febb589eSKatayama Hirofumi MZ }
736febb589eSKatayama Hirofumi MZ 
737febb589eSKatayama Hirofumi MZ /// @unimplemented
738febb589eSKatayama Hirofumi MZ LRESULT
739*1ee01452SKatayama Hirofumi MZ CicBridge::EscHanjaMode(TLS *pTLS, HIMC hIMC, LPVOID lpData)
740*1ee01452SKatayama Hirofumi MZ {
741*1ee01452SKatayama Hirofumi MZ     CicIMCLock imcLock(hIMC);
742*1ee01452SKatayama Hirofumi MZ     if (FAILED(imcLock.m_hr))
743*1ee01452SKatayama Hirofumi MZ         return imcLock.m_hr;
744*1ee01452SKatayama Hirofumi MZ 
745*1ee01452SKatayama Hirofumi MZ     CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
746*1ee01452SKatayama Hirofumi MZ     if (FAILED(imeContext.m_hr))
747*1ee01452SKatayama Hirofumi MZ         return imeContext.m_hr;
748*1ee01452SKatayama Hirofumi MZ 
749*1ee01452SKatayama Hirofumi MZ     CicInputContext *pCicIC = imeContext.get().m_pCicIC;
750*1ee01452SKatayama Hirofumi MZ     if (!pCicIC)
751*1ee01452SKatayama Hirofumi MZ         return TRUE;
752*1ee01452SKatayama Hirofumi MZ 
753*1ee01452SKatayama Hirofumi MZ     if (pCicIC->m_bCandidateOpen)
754*1ee01452SKatayama Hirofumi MZ         return TRUE;
755*1ee01452SKatayama Hirofumi MZ 
756*1ee01452SKatayama Hirofumi MZ     pCicIC->m_dwUnknown6_5[4] |= 0x1;
757*1ee01452SKatayama Hirofumi MZ 
758*1ee01452SKatayama Hirofumi MZ     //FIXME
759*1ee01452SKatayama Hirofumi MZ 
760*1ee01452SKatayama Hirofumi MZ     pCicIC->m_dwUnknown6_5[4] &= ~0x1;
761*1ee01452SKatayama Hirofumi MZ 
762*1ee01452SKatayama Hirofumi MZ     return TRUE;
763*1ee01452SKatayama Hirofumi MZ }
764*1ee01452SKatayama Hirofumi MZ 
765*1ee01452SKatayama Hirofumi MZ /// @implemented
766*1ee01452SKatayama Hirofumi MZ LRESULT
767febb589eSKatayama Hirofumi MZ CicBridge::EscapeKorean(TLS *pTLS, HIMC hIMC, UINT uSubFunc, LPVOID lpData)
768febb589eSKatayama Hirofumi MZ {
769*1ee01452SKatayama Hirofumi MZ     if (uSubFunc == IME_ESC_QUERY_SUPPORT)
770*1ee01452SKatayama Hirofumi MZ         return *(DWORD*)lpData == IME_ESC_HANJA_MODE;
771*1ee01452SKatayama Hirofumi MZ     if (uSubFunc == IME_ESC_HANJA_MODE)
772*1ee01452SKatayama Hirofumi MZ         return EscHanjaMode(pTLS, hIMC, lpData);
773*1ee01452SKatayama Hirofumi MZ     return 0;
774febb589eSKatayama Hirofumi MZ }
775febb589eSKatayama Hirofumi MZ 
776febb589eSKatayama Hirofumi MZ /// @implemented
777febb589eSKatayama Hirofumi MZ BOOL CicBridge::IsOwnDim(ITfDocumentMgr *pDocMgr)
778febb589eSKatayama Hirofumi MZ {
779febb589eSKatayama Hirofumi MZ     DWORD dwDimFlags = 0;
780febb589eSKatayama Hirofumi MZ     HRESULT hr = ::GetCompartmentDWORD(pDocMgr, GUID_COMPARTMENT_CTFIME_DIMFLAGS,
781febb589eSKatayama Hirofumi MZ                                        &dwDimFlags, FALSE);
782febb589eSKatayama Hirofumi MZ     if (FAILED(hr))
783febb589eSKatayama Hirofumi MZ         return FALSE;
784febb589eSKatayama Hirofumi MZ     return !!(dwDimFlags & 0x1);
785febb589eSKatayama Hirofumi MZ }
786