From 52ca35327ec8ee1a55c84134adfef17fac4618d1 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 2 Jun 2025 05:07:49 +0900 Subject: [PATCH] [MSCTF] Make ITfLangBarMgr C++ (#8056) Implementing missing features... JIRA issue: CORE-19361 - Delete langbarmgr.c (C) and add langbarmgr.cpp (C++). - Remove the legacy C implementation of ITfLangBarMgr. - Add CLangBarMgr class. --- base/ctf/msctf/CMakeLists.txt | 2 +- base/ctf/msctf/langbarmgr.c | 198 ---------------------- base/ctf/msctf/langbarmgr.cpp | 283 ++++++++++++++++++++++++++++++++ base/ctf/msctf/msctf_internal.h | 8 + 4 files changed, 292 insertions(+), 199 deletions(-) delete mode 100644 base/ctf/msctf/langbarmgr.c create mode 100644 base/ctf/msctf/langbarmgr.cpp diff --git a/base/ctf/msctf/CMakeLists.txt b/base/ctf/msctf/CMakeLists.txt index 6a141d9d912..6f623ede229 100644 --- a/base/ctf/msctf/CMakeLists.txt +++ b/base/ctf/msctf/CMakeLists.txt @@ -11,7 +11,6 @@ list(APPEND SOURCE displayattributemgr.c documentmgr.c inputprocessor.c - langbarmgr.c msctf.c range.c threadmgr.c @@ -19,6 +18,7 @@ list(APPEND SOURCE ${CMAKE_CURRENT_BINARY_DIR}/msctf_stubs.c) list(APPEND PCH_SKIP_SOURCE + langbarmgr.cpp mlng.cpp utils.cpp) diff --git a/base/ctf/msctf/langbarmgr.c b/base/ctf/msctf/langbarmgr.c deleted file mode 100644 index f56c130caaa..00000000000 --- a/base/ctf/msctf/langbarmgr.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * ITfLangBarMgr implementation - * - * Copyright 2010 Justin Chevrier - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#define COBJMACROS - -#include "wine/debug.h" -#include "winbase.h" -#include "winreg.h" -#include "shlwapi.h" - -#include "msctf.h" -#include "msctf_internal.h" - -WINE_DEFAULT_DEBUG_CHANNEL(msctf); - -typedef struct tagLangBarMgr { - ITfLangBarMgr ITfLangBarMgr_iface; - - LONG refCount; - -} LangBarMgr; - -static inline LangBarMgr *impl_from_ITfLangBarMgr(ITfLangBarMgr *iface) -{ - return CONTAINING_RECORD(iface, LangBarMgr, ITfLangBarMgr_iface); -} - -static void LangBarMgr_Destructor(LangBarMgr *This) -{ - TRACE("destroying %p\n", This); - - HeapFree(GetProcessHeap(),0,This); -} - -static HRESULT WINAPI LangBarMgr_QueryInterface(ITfLangBarMgr *iface, REFIID iid, LPVOID *ppvOut) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - *ppvOut = NULL; - - if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfLangBarMgr)) - { - *ppvOut = &This->ITfLangBarMgr_iface; - } - - if (*ppvOut) - { - ITfLangBarMgr_AddRef(iface); - return S_OK; - } - - WARN("unsupported interface: %s\n", debugstr_guid(iid)); - return E_NOINTERFACE; -} - -static ULONG WINAPI LangBarMgr_AddRef(ITfLangBarMgr *iface) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - return InterlockedIncrement(&This->refCount); -} - -static ULONG WINAPI LangBarMgr_Release(ITfLangBarMgr *iface) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - ULONG ret; - - ret = InterlockedDecrement(&This->refCount); - if (ret == 0) - LangBarMgr_Destructor(This); - return ret; -} - -/***************************************************** - * ITfLangBarMgr functions - *****************************************************/ - -static HRESULT WINAPI LangBarMgr_AdviseEventSink( ITfLangBarMgr* iface, ITfLangBarEventSink *pSink, HWND hwnd, DWORD dwflags, DWORD *pdwCookie) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; -} - -static HRESULT WINAPI LangBarMgr_UnAdviseEventSink( ITfLangBarMgr* iface, DWORD dwCookie) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; -} - -static HRESULT WINAPI LangBarMgr_GetThreadMarshalInterface( ITfLangBarMgr* iface, DWORD dwThreadId, DWORD dwType, REFIID riid, IUnknown **ppunk) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; -} - -static HRESULT WINAPI LangBarMgr_GetThreadLangBarItemMgr( ITfLangBarMgr* iface, DWORD dwThreadId, ITfLangBarItemMgr **pplbi, DWORD *pdwThreadid) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; -} - -static HRESULT WINAPI LangBarMgr_GetInputProcessorProfiles( ITfLangBarMgr* iface, DWORD dwThreadId, ITfInputProcessorProfiles **ppaip, DWORD *pdwThreadid) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; -} - -static HRESULT WINAPI LangBarMgr_RestoreLastFocus( ITfLangBarMgr* iface, DWORD *dwThreadId, BOOL fPrev) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; -} - -static HRESULT WINAPI LangBarMgr_SetModalInput( ITfLangBarMgr* iface, ITfLangBarEventSink *pSink, DWORD dwThreadId, DWORD dwFlags) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; -} - -static HRESULT WINAPI LangBarMgr_ShowFloating( ITfLangBarMgr* iface, DWORD dwFlags) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; -} - -static HRESULT WINAPI LangBarMgr_GetShowFloatingStatus( ITfLangBarMgr* iface, DWORD *pdwFlags) -{ - LangBarMgr *This = impl_from_ITfLangBarMgr(iface); - - FIXME("STUB:(%p)\n",This); - return E_NOTIMPL; -} - -static const ITfLangBarMgrVtbl LangBarMgr_LangBarMgrVtbl = -{ - LangBarMgr_QueryInterface, - LangBarMgr_AddRef, - LangBarMgr_Release, - - LangBarMgr_AdviseEventSink, - LangBarMgr_UnAdviseEventSink, - LangBarMgr_GetThreadMarshalInterface, - LangBarMgr_GetThreadLangBarItemMgr, - LangBarMgr_GetInputProcessorProfiles, - LangBarMgr_RestoreLastFocus, - LangBarMgr_SetModalInput, - LangBarMgr_ShowFloating, - LangBarMgr_GetShowFloatingStatus -}; - -HRESULT LangBarMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) -{ - LangBarMgr *This; - if (pUnkOuter) - return CLASS_E_NOAGGREGATION; - - This = HeapAlloc(GetProcessHeap(),0,sizeof(LangBarMgr)); - if (This == NULL) - return E_OUTOFMEMORY; - - This->ITfLangBarMgr_iface.lpVtbl = &LangBarMgr_LangBarMgrVtbl; - This->refCount = 1; - - *ppOut = (IUnknown *)&This->ITfLangBarMgr_iface; - TRACE("returning %p\n", *ppOut); - return S_OK; -} diff --git a/base/ctf/msctf/langbarmgr.cpp b/base/ctf/msctf/langbarmgr.cpp new file mode 100644 index 00000000000..7a38017d618 --- /dev/null +++ b/base/ctf/msctf/langbarmgr.cpp @@ -0,0 +1,283 @@ +/* + * PROJECT: ReactOS CTF + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: ITfLangBarMgr implementation + * COPYRIGHT: Copyright 2010 Justin Chevrier + * Copyright 2025 Katayama Hirofumi MZ + */ + +#include +#include +#include +#include +#include +#include + +// Cicero +#include +#include +#include + +#include "msctf_internal.h" + +#include +WINE_DEFAULT_DEBUG_CHANNEL(msctf); + +//***************************************************************************************** + +class CLangBarMgr : public ITfLangBarMgr_P +{ +public: + CLangBarMgr(); + virtual ~CLangBarMgr(); + + // ** IUnknown interface ** + STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ PVOID *ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // ** ITfLangBarMgr interface ** + STDMETHODIMP AdviseEventSink( + _In_ ITfLangBarEventSink *pSink, + _In_ HWND hwnd, + _In_ DWORD dwflags, + _In_ DWORD *pdwCookie) override; + STDMETHODIMP UnAdviseEventSink(_In_ DWORD dwCookie) override; + STDMETHODIMP GetThreadMarshalInterface( + _In_ DWORD dwThreadId, + _In_ DWORD dwType, + _In_ REFIID riid, + _Out_ IUnknown **ppunk) override; + STDMETHODIMP GetThreadLangBarItemMgr( + _In_ DWORD dwThreadId, + _Out_ ITfLangBarItemMgr **pplbie, + _Out_ DWORD *pdwThreadid) override; + STDMETHODIMP GetInputProcessorProfiles( + _In_ DWORD dwThreadId, + _Out_ ITfInputProcessorProfiles **ppaip, + _Out_ DWORD *pdwThreadid) override; + STDMETHODIMP RestoreLastFocus(_Out_ DWORD *dwThreadId, _In_ BOOL fPrev) override; + STDMETHODIMP SetModalInput( + _In_ ITfLangBarEventSink *pSink, + _In_ DWORD dwThreadId, + _In_ DWORD dwFlags) override; + STDMETHODIMP ShowFloating(_In_ DWORD dwFlags) override; + STDMETHODIMP GetShowFloatingStatus(_Out_ DWORD *pdwFlags) override; + + // ** ITfLangBarMgr_P interface ** + STDMETHODIMP GetPrevShowFloatingStatus(_Inout_ DWORD* pdwStatus) override; + +protected: + LONG m_cRefs; + + static BOOL CheckFloatingBits(_In_ DWORD dwBits); + static HRESULT s_GetShowFloatingStatus(_Out_ DWORD *pdwFlags); + static HRESULT s_ShowFloating(_In_ DWORD dwFlags); +}; + +// The groups of mutually exclusive TF_SFT_... bits +#define TF_SFT_VISIBILITY_GROUP \ + (TF_SFT_SHOWNORMAL | TF_SFT_DOCK | TF_SFT_MINIMIZED | TF_SFT_HIDDEN | TF_SFT_DESKBAND) +#define TF_SFT_TRANSPARENCY_GROUP \ + (TF_SFT_NOTRANSPARENCY | TF_SFT_LOWTRANSPARENCY | TF_SFT_HIGHTRANSPARENCY) +#define TF_SFT_LABEL_GROUP (TF_SFT_LABELS | TF_SFT_NOLABELS) +#define TF_SFT_EXTRA_ICON_GROUP (TF_SFT_EXTRAICONSONMINIMIZED | TF_SFT_NOEXTRAICONSONMINIMIZED) + +static inline BOOL +IsSingleBitSet(DWORD dwValue) +{ + return (dwValue != 0) && ((dwValue & (dwValue - 1)) == 0); +} + +//***************************************************************************************** + +CLangBarMgr::CLangBarMgr() : m_cRefs(1) +{ +} + +CLangBarMgr::~CLangBarMgr() +{ +} + +BOOL CLangBarMgr::CheckFloatingBits(_In_ DWORD dwBits) +{ + return IsSingleBitSet(dwBits & TF_SFT_VISIBILITY_GROUP) && + IsSingleBitSet(dwBits & TF_SFT_TRANSPARENCY_GROUP) && + IsSingleBitSet(dwBits & TF_SFT_LABEL_GROUP) && + IsSingleBitSet(dwBits & TF_SFT_EXTRA_ICON_GROUP); +} + +HRESULT CLangBarMgr::s_GetShowFloatingStatus(_Out_ DWORD *pdwFlags) +{ + return E_NOTIMPL; +} + +HRESULT CLangBarMgr::s_ShowFloating(_In_ DWORD dwFlags) +{ + return E_NOTIMPL; +} + +//***************************************************************************************** +// ** IUnknown interface ** + +STDMETHODIMP +CLangBarMgr::QueryInterface( + _In_ REFIID riid, + _Out_ PVOID *ppvObj) +{ + if (!ppvObj) + return E_INVALIDARG; + + if (!IsEqualIID(riid, IID_IUnknown) && + !IsEqualIID(riid, IID_ITfLangBarMgr) && + !IsEqualIID(riid, IID_ITfLangBarMgr_P)) + { + *ppvObj = NULL; + return E_NOINTERFACE; + } + + *ppvObj = this; + AddRef(); + return S_OK; +} + +STDMETHODIMP_(ULONG) CLangBarMgr::AddRef() +{ + return ++m_cRefs; +} + +STDMETHODIMP_(ULONG) CLangBarMgr::Release() +{ + if (!--m_cRefs) + { + delete this; + return 0; + } + return m_cRefs; +} + +//***************************************************************************************** +// ** ITfLangBarMgr interface ** + +STDMETHODIMP +CLangBarMgr::AdviseEventSink( + _In_ ITfLangBarEventSink *pSink, + _In_ HWND hwnd, + _In_ DWORD dwflags, + _In_ DWORD *pdwCookie) +{ + FIXME("(%p, %p, 0x%X, %p)\n", pSink, hwnd, dwflags, pdwCookie); + if (!pSink) + return E_INVALIDARG; + return E_NOTIMPL; +} + +STDMETHODIMP +CLangBarMgr::UnAdviseEventSink( + _In_ DWORD dwCookie) +{ + FIXME("(0x%lX)\n", dwCookie); + return E_NOTIMPL; +} + +STDMETHODIMP +CLangBarMgr::GetThreadMarshalInterface( + _In_ DWORD dwThreadId, + _In_ DWORD dwType, + _In_ REFIID riid, + _Out_ IUnknown **ppunk) +{ + FIXME("(%lu, %lu, %s, %p)\n", dwThreadId, dwType, wine_dbgstr_guid(&riid), ppunk); + return E_NOTIMPL; +} + +STDMETHODIMP +CLangBarMgr::GetThreadLangBarItemMgr( + _In_ DWORD dwThreadId, + _Out_ ITfLangBarItemMgr **pplbie, + _Out_ DWORD *pdwThreadid) +{ + FIXME("(%lu, %p, %p)\n", dwThreadId, pplbie, pdwThreadid); + return E_NOTIMPL; +} + +STDMETHODIMP +CLangBarMgr::GetInputProcessorProfiles( + _In_ DWORD dwThreadId, + _Out_ ITfInputProcessorProfiles **ppaip, + _Out_ DWORD *pdwThreadid) +{ + FIXME("(%lu, %p, %p)\n", dwThreadId, ppaip, pdwThreadid); + return E_NOTIMPL; +} + +STDMETHODIMP +CLangBarMgr::RestoreLastFocus( + _Out_ DWORD *dwThreadId, + _In_ BOOL fPrev) +{ + FIXME("(%p, %d)\n", dwThreadId, fPrev); + return E_NOTIMPL; +} + +STDMETHODIMP +CLangBarMgr::SetModalInput( + _In_ ITfLangBarEventSink *pSink, + _In_ DWORD dwThreadId, + _In_ DWORD dwFlags) +{ + FIXME("(%p, %lu, 0x%lX)\n", pSink, dwThreadId, dwFlags); + return E_NOTIMPL; +} + +STDMETHODIMP +CLangBarMgr::ShowFloating( + _In_ DWORD dwFlags) +{ + FIXME("(0x%lX)\n", dwFlags); + if (!CheckFloatingBits(dwFlags)) + return E_INVALIDARG; + return s_ShowFloating(dwFlags); +} + +STDMETHODIMP +CLangBarMgr::GetShowFloatingStatus( + _Out_ DWORD *pdwFlags) +{ + FIXME("(%p)\n", pdwFlags); + + if (!pdwFlags) + return E_INVALIDARG; + + return s_GetShowFloatingStatus(pdwFlags); +} + +//***************************************************************************************** +// ** ITfLangBarMgr_P interface ** + +STDMETHODIMP +CLangBarMgr::GetPrevShowFloatingStatus(_Inout_ DWORD* pdwStatus) +{ + FIXME("(%p)\n", pdwStatus); + if (!pdwStatus) + return E_INVALIDARG; + return E_NOTIMPL; +} + +//***************************************************************************************** + +EXTERN_C HRESULT +LangBarMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut) +{ + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + CLangBarMgr *pLangBarMgr = new(cicNoThrow) CLangBarMgr(); + if (!pLangBarMgr) + return E_OUTOFMEMORY; + + HRESULT hr = pLangBarMgr->QueryInterface(IID_ITfLangBarMgr, (PVOID *)ppOut); + TRACE("returning %p\n", *ppOut); + pLangBarMgr->Release(); + return hr; +} diff --git a/base/ctf/msctf/msctf_internal.h b/base/ctf/msctf/msctf_internal.h index 9d60e18e6f3..d26567849c1 100644 --- a/base/ctf/msctf/msctf_internal.h +++ b/base/ctf/msctf/msctf_internal.h @@ -23,6 +23,10 @@ #include "wine/list.h" +#if defined(__REACTOS__) && defined(__cplusplus) +extern "C" { +#endif + #define COOKIE_MAGIC_TMSINK 0x0010 #define COOKIE_MAGIC_CONTEXTSINK 0x0020 #define COOKIE_MAGIC_GUIDATOM 0x0030 @@ -98,4 +102,8 @@ void free_sinks(struct list *sink_list) DECLSPEC_HIDDEN; extern const WCHAR szwSystemTIPKey[] DECLSPEC_HIDDEN; extern const WCHAR szwSystemCTFKey[] DECLSPEC_HIDDEN; +#if defined(__REACTOS__) && defined(__cplusplus) +} // extern "C" +#endif + #endif /* __WINE_MSCTF_I_H */