Reactos
at master 180 lines 3.8 kB view raw
1/* 2 * PROJECT: ReactOS msctfime.ime 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Profile of msctfime.ime 5 * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 8#include "msctfime.h" 9 10WINE_DEFAULT_DEBUG_CHANNEL(msctfime); 11 12/// @implemented 13CicProfile::CicProfile() 14{ 15 m_dwFlags &= 0xFFFFFFF0; 16 m_cRefs = 1; 17 m_pIPProfiles = NULL; 18 m_pActiveLanguageProfileNotifySink = NULL; 19 m_LangID1 = 0; 20 m_nCodePage = CP_ACP; 21 m_LangID2 = 0; 22 m_dwUnknown1 = 0; 23} 24 25/// @implemented 26CicProfile::~CicProfile() 27{ 28 if (m_pIPProfiles) 29 { 30 if (m_LangID1) 31 m_pIPProfiles->ChangeCurrentLanguage(m_LangID1); 32 33 m_pIPProfiles->Release(); 34 m_pIPProfiles = NULL; 35 } 36 37 if (m_pActiveLanguageProfileNotifySink) 38 { 39 m_pActiveLanguageProfileNotifySink->_Unadvise(); 40 m_pActiveLanguageProfileNotifySink->Release(); 41 m_pActiveLanguageProfileNotifySink = NULL; 42 } 43} 44 45/// @implemented 46STDMETHODIMP CicProfile::QueryInterface(REFIID riid, LPVOID* ppvObj) 47{ 48 *ppvObj = NULL; 49 return E_NOINTERFACE; 50} 51 52/// @implemented 53STDMETHODIMP_(ULONG) CicProfile::AddRef() 54{ 55 return ::InterlockedIncrement(&m_cRefs); 56} 57 58/// @implemented 59STDMETHODIMP_(ULONG) CicProfile::Release() 60{ 61 if (::InterlockedDecrement(&m_cRefs) == 0) 62 { 63 delete this; 64 return 0; 65 } 66 return m_cRefs; 67} 68 69/// @implemented 70INT CALLBACK 71CicProfile::ActiveLanguageProfileNotifySinkCallback( 72 REFGUID rguid1, 73 REFGUID rguid2, 74 BOOL fActivated, 75 LPVOID pUserData) 76{ 77 CicProfile *pThis = (CicProfile *)pUserData; 78 pThis->m_dwFlags &= ~0xE; 79 return 0; 80} 81 82/// @implemented 83HRESULT CicProfile::GetCodePageA(_Out_ UINT *puCodePage) 84{ 85 if (!puCodePage) 86 return E_INVALIDARG; 87 88 if (m_dwFlags & 2) 89 { 90 *puCodePage = m_nCodePage; 91 return S_OK; 92 } 93 94 *puCodePage = 0; 95 96 LANGID LangID; 97 HRESULT hr = GetLangId(&LangID); 98 if (FAILED(hr)) 99 return E_FAIL; 100 101 WCHAR szBuff[12]; 102 INT cch = ::GetLocaleInfoW(LangID, LOCALE_IDEFAULTANSICODEPAGE, szBuff, _countof(szBuff)); 103 if (cch) 104 { 105 szBuff[cch] = 0; 106 m_nCodePage = *puCodePage = wcstoul(szBuff, NULL, 10); 107 m_dwFlags |= 2; 108 } 109 110 return S_OK; 111} 112 113/// @implemented 114HRESULT CicProfile::GetLangId(_Out_ LANGID *pLangID) 115{ 116 *pLangID = 0; 117 118 if (!m_pIPProfiles) 119 return E_FAIL; 120 121 if (m_dwFlags & 4) 122 { 123 *pLangID = m_LangID2; 124 return S_OK; 125 } 126 127 HRESULT hr = m_pIPProfiles->GetCurrentLanguage(pLangID); 128 if (SUCCEEDED(hr)) 129 { 130 m_dwFlags |= 4; 131 m_LangID2 = *pLangID; 132 } 133 134 return hr; 135} 136 137/// @implemented 138HRESULT 139CicProfile::InitProfileInstance(_Inout_ TLS *pTLS) 140{ 141 HRESULT hr = TF_CreateInputProcessorProfiles(&m_pIPProfiles); 142 if (FAILED(hr)) 143 return hr; 144 145 if (!m_pActiveLanguageProfileNotifySink) 146 { 147 CActiveLanguageProfileNotifySink *pSink = 148 new(cicNoThrow) CActiveLanguageProfileNotifySink( 149 CicProfile::ActiveLanguageProfileNotifySinkCallback, this); 150 if (!pSink) 151 { 152 m_pIPProfiles->Release(); 153 m_pIPProfiles = NULL; 154 return E_FAIL; 155 } 156 m_pActiveLanguageProfileNotifySink = pSink; 157 } 158 159 if (pTLS->m_pThreadMgr) 160 m_pActiveLanguageProfileNotifySink->_Advise(pTLS->m_pThreadMgr); 161 162 return hr; 163} 164 165/// @unimplemented 166HRESULT 167CicProfile::GetActiveLanguageProfile( 168 _In_ HKL hKL, 169 _In_ REFGUID rguid, 170 _Out_ TF_LANGUAGEPROFILE *pProfile) 171{ 172 return E_NOTIMPL; 173} 174 175/// The return value of CicProfile::IsIME is brain-damaged. 176/// @unimplemented 177BOOL CicProfile::IsIME(HKL hKL) 178{ 179 return TRUE; 180}