mirror of
https://github.com/reactos/reactos.git
synced 2026-05-19 08:17:32 +08:00
[MSCTFIME][CICERO] Implement CicProfile::GetActiveLanguageProfile (#8869)
Supporting CTF IMEs. JIRA issue: CORE-19360 - Add base/ctf/cicero/ciciface.h to add CicInterface_RefCnt template class. - Add CicProfile:: LanguageProfilesCallback callback function. - Implement CicProfile:: GetActiveLanguageProfile and CicProfile::IsIME functions.
This commit is contained in:
committed by
GitHub
parent
01a0906924
commit
ffa1c541aa
@@ -2,11 +2,14 @@
|
||||
* PROJECT: ReactOS Cicero
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Cicero base
|
||||
* COPYRIGHT: Copyright 2023-2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
* COPYRIGHT: Copyright 2023-2026 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#define cicAssert assert
|
||||
|
||||
static inline LPVOID cicMemAlloc(SIZE_T size)
|
||||
{
|
||||
return LocalAlloc(0, size);
|
||||
|
||||
59
base/ctf/cicero/ciciface.h
Normal file
59
base/ctf/cicero/ciciface.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Cicero
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Cicero COM interface
|
||||
* COPYRIGHT: Copyright 2026 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cicbase.h"
|
||||
|
||||
template <typename T_IFACE>
|
||||
class CicInterface_RefCnt
|
||||
{
|
||||
protected:
|
||||
T_IFACE* m_ptr;
|
||||
|
||||
public:
|
||||
CicInterface_RefCnt() : m_ptr(NULL) { }
|
||||
|
||||
CicInterface_RefCnt(T_IFACE* ptr) : m_ptr(ptr)
|
||||
{
|
||||
if (m_ptr)
|
||||
m_ptr->AddRef();
|
||||
}
|
||||
|
||||
~CicInterface_RefCnt()
|
||||
{
|
||||
if (m_ptr)
|
||||
m_ptr->Release();
|
||||
}
|
||||
|
||||
void Attach(T_IFACE* ptr)
|
||||
{
|
||||
if (m_ptr)
|
||||
m_ptr->Release();
|
||||
m_ptr = ptr;
|
||||
}
|
||||
|
||||
T_IFACE* Detach()
|
||||
{
|
||||
T_IFACE* old_ptr = m_ptr;
|
||||
m_ptr = NULL;
|
||||
return old_ptr;
|
||||
}
|
||||
|
||||
operator T_IFACE*() { return m_ptr; }
|
||||
T_IFACE* operator->() { return m_ptr; }
|
||||
|
||||
T_IFACE** operator&()
|
||||
{
|
||||
cicAssert(!m_ptr);
|
||||
return &m_ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
CicInterface_RefCnt(const CicInterface_RefCnt<T_IFACE>&) = delete;
|
||||
CicInterface_RefCnt<T_IFACE>& operator=(const CicInterface_RefCnt<T_IFACE>&) = delete;
|
||||
};
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <cicbase.h>
|
||||
#include <cicarray.h>
|
||||
#include <ciciface.h>
|
||||
#include <cicimc.h>
|
||||
#include <cictf.h>
|
||||
#include <cicreg.h>
|
||||
|
||||
@@ -2,13 +2,67 @@
|
||||
* PROJECT: ReactOS msctfime.ime
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Profile of msctfime.ime
|
||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
* COPYRIGHT: Copyright 2024-2026 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#include "msctfime.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msctfime);
|
||||
|
||||
// The callback function type
|
||||
typedef HRESULT (CALLBACK *FN_LanguageProfilesCallback)(TF_LANGUAGEPROFILE profile, LPARAM lParam);
|
||||
|
||||
/// @implemented
|
||||
HRESULT
|
||||
CicProfile::LanguageProfilesCallback(
|
||||
_In_ TF_LANGUAGEPROFILE profile,
|
||||
_Inout_opt_ LPARAM lParam)
|
||||
{
|
||||
if (!profile.fActive || !memcmp(&profile.clsid, &GUID_NULL, sizeof(GUID_NULL)))
|
||||
return S_FALSE;
|
||||
PLANG_PROF_ENUM_ARG pArg = (PLANG_PROF_ENUM_ARG)lParam;
|
||||
if (!pArg)
|
||||
return S_OK;
|
||||
if (memcmp(&profile.catid, &pArg->catid, sizeof(profile.catid)) != 0)
|
||||
return S_FALSE;
|
||||
pArg->profile = profile;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
template <typename T_IFACE, typename T_DATA>
|
||||
class CicEnumValue
|
||||
{
|
||||
T_IFACE* m_iface;
|
||||
FN_LanguageProfilesCallback m_callback;
|
||||
LPARAM m_lParam;
|
||||
|
||||
public:
|
||||
CicEnumValue(T_IFACE* iface, FN_LanguageProfilesCallback callback, LPARAM lParam = 0)
|
||||
: m_iface(iface)
|
||||
, m_callback(callback)
|
||||
, m_lParam(lParam)
|
||||
{ }
|
||||
|
||||
DWORD DoEnum()
|
||||
{
|
||||
HRESULT hr;
|
||||
T_DATA data;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
hr = m_iface->Next(1, &data, NULL);
|
||||
if (hr != S_OK)
|
||||
break;
|
||||
|
||||
hr = m_callback(data, m_lParam);
|
||||
if (hr == S_OK)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
return ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
};
|
||||
|
||||
/// @implemented
|
||||
CicProfile::CicProfile()
|
||||
{
|
||||
@@ -162,19 +216,40 @@ CicProfile::InitProfileInstance(_Inout_ TLS *pTLS)
|
||||
return hr;
|
||||
}
|
||||
|
||||
/// @unimplemented
|
||||
/// @implemented
|
||||
HRESULT
|
||||
CicProfile::GetActiveLanguageProfile(
|
||||
_In_ HKL hKL,
|
||||
_In_ REFGUID rguid,
|
||||
_Out_ TF_LANGUAGEPROFILE *pProfile)
|
||||
_In_ REFGUID catid,
|
||||
_Out_ TF_LANGUAGEPROFILE* pProfile)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
CicInterface_RefCnt<IEnumTfLanguageProfiles> pEnum;
|
||||
HRESULT hr = m_pIPProfiles->EnumLanguageProfiles(LOWORD(hKL), &pEnum);
|
||||
if (FAILED(hr))
|
||||
return S_FALSE;
|
||||
|
||||
LANG_PROF_ENUM_ARG arg;
|
||||
arg.catid = catid;
|
||||
|
||||
CicEnumValue<IEnumTfLanguageProfiles, TF_LANGUAGEPROFILE>
|
||||
enumValue(pEnum, LanguageProfilesCallback, (LPARAM)&arg);
|
||||
DWORD ret = enumValue.DoEnum();
|
||||
if (ret != ERROR_SUCCESS || !pProfile)
|
||||
return S_FALSE;
|
||||
*pProfile = arg.profile;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/// The return value of CicProfile::IsIME is brain-damaged.
|
||||
/// @unimplemented
|
||||
BOOL CicProfile::IsIME(HKL hKL)
|
||||
/// @implemented
|
||||
HRESULT CicProfile::IsIME(HKL hKL)
|
||||
{
|
||||
return TRUE;
|
||||
CicInterface_RefCnt<IEnumTfLanguageProfiles> pEnum;
|
||||
HRESULT hr = m_pIPProfiles->EnumLanguageProfiles(LOWORD(hKL), &pEnum);
|
||||
if (FAILED(hr))
|
||||
return S_FALSE;
|
||||
|
||||
CicEnumValue<IEnumTfLanguageProfiles, TF_LANGUAGEPROFILE>
|
||||
enumValue(pEnum, LanguageProfilesCallback);
|
||||
DWORD ret = enumValue.DoEnum();
|
||||
return (ret == ERROR_SUCCESS) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* PROJECT: ReactOS msctfime.ime
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Profile of msctfime.ime
|
||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
* COPYRIGHT: Copyright 2024-2026 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -12,6 +12,12 @@
|
||||
class CicProfile : public IUnknown
|
||||
{
|
||||
protected:
|
||||
typedef struct tagLANG_PROF_ENUM_ARG
|
||||
{
|
||||
GUID catid;
|
||||
TF_LANGUAGEPROFILE profile;
|
||||
} LANG_PROF_ENUM_ARG, *PLANG_PROF_ENUM_ARG;
|
||||
|
||||
ITfInputProcessorProfiles *m_pIPProfiles;
|
||||
CActiveLanguageProfileNotifySink *m_pActiveLanguageProfileNotifySink;
|
||||
LANGID m_LangID1;
|
||||
@@ -42,12 +48,16 @@ public:
|
||||
HRESULT
|
||||
GetActiveLanguageProfile(
|
||||
_In_ HKL hKL,
|
||||
_In_ REFGUID rguid,
|
||||
_Out_ TF_LANGUAGEPROFILE *pProfile);
|
||||
_In_ REFGUID catid,
|
||||
_Out_ TF_LANGUAGEPROFILE* pProfile);
|
||||
HRESULT GetLangId(_Out_ LANGID *pLangID);
|
||||
HRESULT GetCodePageA(_Out_ UINT *puCodePage);
|
||||
|
||||
HRESULT InitProfileInstance(_Inout_ TLS *pTLS);
|
||||
HRESULT IsIME(HKL hKL);
|
||||
|
||||
BOOL IsIME(HKL hKL);
|
||||
static HRESULT CALLBACK
|
||||
LanguageProfilesCallback(
|
||||
_In_ TF_LANGUAGEPROFILE profile,
|
||||
_Inout_opt_ LPARAM lParam);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user