Reactos
1/*
2 * PROJECT: ReactOS CTF
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: ITfLangBarMgr implementation
5 * COPYRIGHT: Copyright 2010 Justin Chevrier
6 * Copyright 2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7 */
8
9#include "precomp.h"
10
11#include <wine/debug.h>
12WINE_DEFAULT_DEBUG_CHANNEL(msctf);
13
14//*****************************************************************************************
15
16class CLangBarMgr : public ITfLangBarMgr_P
17{
18public:
19 CLangBarMgr();
20 virtual ~CLangBarMgr();
21
22 // ** IUnknown interface **
23 STDMETHODIMP QueryInterface(_In_ REFIID riid, _Out_ PVOID *ppvObj) override;
24 STDMETHODIMP_(ULONG) AddRef() override;
25 STDMETHODIMP_(ULONG) Release() override;
26
27 // ** ITfLangBarMgr interface **
28 STDMETHODIMP AdviseEventSink(
29 _In_ ITfLangBarEventSink *pSink,
30 _In_ HWND hwnd,
31 _In_ DWORD dwflags,
32 _In_ DWORD *pdwCookie) override;
33 STDMETHODIMP UnAdviseEventSink(_In_ DWORD dwCookie) override;
34 STDMETHODIMP GetThreadMarshalInterface(
35 _In_ DWORD dwThreadId,
36 _In_ DWORD dwType,
37 _In_ REFIID riid,
38 _Out_ IUnknown **ppunk) override;
39 STDMETHODIMP GetThreadLangBarItemMgr(
40 _In_ DWORD dwThreadId,
41 _Out_ ITfLangBarItemMgr **pplbie,
42 _Out_ DWORD *pdwThreadid) override;
43 STDMETHODIMP GetInputProcessorProfiles(
44 _In_ DWORD dwThreadId,
45 _Out_ ITfInputProcessorProfiles **ppaip,
46 _Out_ DWORD *pdwThreadid) override;
47 STDMETHODIMP RestoreLastFocus(_Out_ DWORD *dwThreadId, _In_ BOOL fPrev) override;
48 STDMETHODIMP SetModalInput(
49 _In_ ITfLangBarEventSink *pSink,
50 _In_ DWORD dwThreadId,
51 _In_ DWORD dwFlags) override;
52 STDMETHODIMP ShowFloating(_In_ DWORD dwFlags) override;
53 STDMETHODIMP GetShowFloatingStatus(_Out_ DWORD *pdwFlags) override;
54
55 // ** ITfLangBarMgr_P interface **
56 STDMETHODIMP GetPrevShowFloatingStatus(_Inout_ DWORD* pdwStatus) override;
57
58protected:
59 LONG m_cRefs;
60
61 static BOOL CheckFloatingBits(_In_ DWORD dwBits);
62 static HRESULT s_GetShowFloatingStatus(_Out_ DWORD *pdwFlags);
63 static HRESULT s_ShowFloating(_In_ DWORD dwFlags);
64};
65
66// The groups of mutually exclusive TF_SFT_... bits
67#define TF_SFT_VISIBILITY_GROUP \
68 (TF_SFT_SHOWNORMAL | TF_SFT_DOCK | TF_SFT_MINIMIZED | TF_SFT_HIDDEN | TF_SFT_DESKBAND)
69#define TF_SFT_TRANSPARENCY_GROUP \
70 (TF_SFT_NOTRANSPARENCY | TF_SFT_LOWTRANSPARENCY | TF_SFT_HIGHTRANSPARENCY)
71#define TF_SFT_LABEL_GROUP (TF_SFT_LABELS | TF_SFT_NOLABELS)
72#define TF_SFT_EXTRA_ICON_GROUP (TF_SFT_EXTRAICONSONMINIMIZED | TF_SFT_NOEXTRAICONSONMINIMIZED)
73
74static inline BOOL
75IsSingleBitSet(DWORD dwValue)
76{
77 return (dwValue != 0) && ((dwValue & (dwValue - 1)) == 0);
78}
79
80//*****************************************************************************************
81
82CLangBarMgr::CLangBarMgr() : m_cRefs(1)
83{
84}
85
86CLangBarMgr::~CLangBarMgr()
87{
88}
89
90BOOL CLangBarMgr::CheckFloatingBits(_In_ DWORD dwBits)
91{
92 return IsSingleBitSet(dwBits & TF_SFT_VISIBILITY_GROUP) &&
93 IsSingleBitSet(dwBits & TF_SFT_TRANSPARENCY_GROUP) &&
94 IsSingleBitSet(dwBits & TF_SFT_LABEL_GROUP) &&
95 IsSingleBitSet(dwBits & TF_SFT_EXTRA_ICON_GROUP);
96}
97
98HRESULT CLangBarMgr::s_GetShowFloatingStatus(_Out_ DWORD *pdwFlags)
99{
100 return E_NOTIMPL;
101}
102
103HRESULT CLangBarMgr::s_ShowFloating(_In_ DWORD dwFlags)
104{
105 return E_NOTIMPL;
106}
107
108STDMETHODIMP
109CLangBarMgr::QueryInterface(
110 _In_ REFIID riid,
111 _Out_ PVOID *ppvObj)
112{
113 if (!ppvObj)
114 return E_INVALIDARG;
115
116 *ppvObj = NULL;
117 if (riid == IID_IUnknown || riid == IID_ITfLangBarMgr || riid == IID_ITfLangBarMgr_P)
118 *ppvObj = static_cast<ITfLangBarMgr_P *>(this);
119
120 if (*ppvObj)
121 {
122 AddRef();
123 return S_OK;
124 }
125
126 WARN("unsupported interface: %s\n", debugstr_guid(&riid));
127 return E_NOINTERFACE;
128}
129
130STDMETHODIMP_(ULONG) CLangBarMgr::AddRef()
131{
132 return ::InterlockedIncrement(&m_cRefs);
133}
134
135STDMETHODIMP_(ULONG) CLangBarMgr::Release()
136{
137 ULONG ret = ::InterlockedDecrement(&m_cRefs);
138 if (!ret)
139 delete this;
140 return ret;
141}
142
143STDMETHODIMP
144CLangBarMgr::AdviseEventSink(
145 _In_ ITfLangBarEventSink *pSink,
146 _In_ HWND hwnd,
147 _In_ DWORD dwflags,
148 _In_ DWORD *pdwCookie)
149{
150 FIXME("(%p, %p, 0x%X, %p)\n", pSink, hwnd, dwflags, pdwCookie);
151 if (!pSink)
152 return E_INVALIDARG;
153 return E_NOTIMPL;
154}
155
156STDMETHODIMP
157CLangBarMgr::UnAdviseEventSink(
158 _In_ DWORD dwCookie)
159{
160 FIXME("(0x%lX)\n", dwCookie);
161 return E_NOTIMPL;
162}
163
164STDMETHODIMP
165CLangBarMgr::GetThreadMarshalInterface(
166 _In_ DWORD dwThreadId,
167 _In_ DWORD dwType,
168 _In_ REFIID riid,
169 _Out_ IUnknown **ppunk)
170{
171 FIXME("(%lu, %lu, %s, %p)\n", dwThreadId, dwType, wine_dbgstr_guid(&riid), ppunk);
172 return E_NOTIMPL;
173}
174
175STDMETHODIMP
176CLangBarMgr::GetThreadLangBarItemMgr(
177 _In_ DWORD dwThreadId,
178 _Out_ ITfLangBarItemMgr **pplbie,
179 _Out_ DWORD *pdwThreadid)
180{
181 FIXME("(%lu, %p, %p)\n", dwThreadId, pplbie, pdwThreadid);
182 return E_NOTIMPL;
183}
184
185STDMETHODIMP
186CLangBarMgr::GetInputProcessorProfiles(
187 _In_ DWORD dwThreadId,
188 _Out_ ITfInputProcessorProfiles **ppaip,
189 _Out_ DWORD *pdwThreadid)
190{
191 FIXME("(%lu, %p, %p)\n", dwThreadId, ppaip, pdwThreadid);
192 return E_NOTIMPL;
193}
194
195STDMETHODIMP
196CLangBarMgr::RestoreLastFocus(
197 _Out_ DWORD *dwThreadId,
198 _In_ BOOL fPrev)
199{
200 FIXME("(%p, %d)\n", dwThreadId, fPrev);
201 return E_NOTIMPL;
202}
203
204STDMETHODIMP
205CLangBarMgr::SetModalInput(
206 _In_ ITfLangBarEventSink *pSink,
207 _In_ DWORD dwThreadId,
208 _In_ DWORD dwFlags)
209{
210 FIXME("(%p, %lu, 0x%lX)\n", pSink, dwThreadId, dwFlags);
211 return E_NOTIMPL;
212}
213
214STDMETHODIMP
215CLangBarMgr::ShowFloating(
216 _In_ DWORD dwFlags)
217{
218 FIXME("(0x%lX)\n", dwFlags);
219 if (!CheckFloatingBits(dwFlags))
220 return E_INVALIDARG;
221 return s_ShowFloating(dwFlags);
222}
223
224STDMETHODIMP
225CLangBarMgr::GetShowFloatingStatus(
226 _Out_ DWORD *pdwFlags)
227{
228 FIXME("(%p)\n", pdwFlags);
229
230 if (!pdwFlags)
231 return E_INVALIDARG;
232
233 return s_GetShowFloatingStatus(pdwFlags);
234}
235
236STDMETHODIMP
237CLangBarMgr::GetPrevShowFloatingStatus(_Inout_ DWORD* pdwStatus)
238{
239 FIXME("(%p)\n", pdwStatus);
240 if (!pdwStatus)
241 return E_INVALIDARG;
242 return E_NOTIMPL;
243}
244
245//*****************************************************************************************
246
247EXTERN_C HRESULT
248LangBarMgr_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
249{
250 if (pUnkOuter)
251 return CLASS_E_NOAGGREGATION;
252
253 CLangBarMgr *pLangBarMgr = new(cicNoThrow) CLangBarMgr();
254 if (!pLangBarMgr)
255 return E_OUTOFMEMORY;
256
257 HRESULT hr = pLangBarMgr->QueryInterface(IID_ITfLangBarMgr, (PVOID *)ppOut);
258 TRACE("returning %p\n", *ppOut);
259 pLangBarMgr->Release();
260 return hr;
261}