-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
minimal TSF impl that commits 哈 on key down (#5)
- Loading branch information
1 parent
cfccfb0
commit 14a8694
Showing
12 changed files
with
458 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
add_library(tsf STATIC | ||
tsf.cpp | ||
TextInputProcessorEx.cpp | ||
ThreadMgrEventSink.cpp | ||
TextEditSink.cpp | ||
KeyEventSink.cpp | ||
EditSession.cpp | ||
CompositionSink.cpp | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#include "tsf.h" | ||
|
||
namespace fcitx { | ||
STDMETHODIMP Tsf::OnCompositionTerminated(TfEditCookie ecWrite, | ||
ITfComposition *pComposition) { | ||
return S_OK; | ||
} | ||
} // namespace fcitx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "tsf.h" | ||
|
||
namespace fcitx { | ||
STDMETHODIMP Tsf::DoEditSession(TfEditCookie ec) { | ||
CComPtr<ITfInsertAtSelection> insertAtSelection; | ||
if (textEditSinkContext_->QueryInterface( | ||
IID_ITfInsertAtSelection, (LPVOID *)&insertAtSelection) != S_OK) { | ||
return E_FAIL; | ||
} | ||
CComPtr<ITfRange> range; | ||
if (insertAtSelection->InsertTextAtSelection(ec, TF_IAS_QUERYONLY, nullptr, | ||
0, &range) != S_OK) { | ||
return E_FAIL; | ||
} | ||
CComPtr<ITfContextComposition> contextComposition; | ||
if (textEditSinkContext_->QueryInterface( | ||
IID_ITfContextComposition, (void **)&contextComposition) != S_OK) { | ||
return E_FAIL; | ||
} | ||
CComPtr<ITfComposition> composition; | ||
if (contextComposition->StartComposition(ec, range, this, &composition) != | ||
S_OK || | ||
composition == nullptr) { | ||
return E_FAIL; | ||
} | ||
|
||
range->SetText(ec, 0, L"哈", 1); | ||
|
||
composition->EndComposition(ec); | ||
|
||
return S_OK; | ||
} | ||
} // namespace fcitx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#include "tsf.h" | ||
|
||
namespace fcitx { | ||
bool Tsf::initKeyEventSink() { | ||
CComPtr<ITfKeystrokeMgr> keystrokeMgr; | ||
if (threadMgr_->QueryInterface(&keystrokeMgr) != S_OK) { | ||
return false; | ||
} | ||
return keystrokeMgr->AdviseKeyEventSink(clientId_, (ITfKeyEventSink *)this, | ||
TRUE) == S_OK; | ||
} | ||
|
||
void Tsf::uninitKeyEventSink() { | ||
CComPtr<ITfKeystrokeMgr> keystrokeMgr; | ||
if (threadMgr_->QueryInterface(&keystrokeMgr) != S_OK) { | ||
return; | ||
} | ||
keystrokeMgr->UnadviseKeyEventSink(clientId_); | ||
} | ||
|
||
BOOL Tsf::processKey(WPARAM wParam, LPARAM lParam) { | ||
HRESULT phrSession; | ||
textEditSinkContext_->RequestEditSession( | ||
clientId_, this, TF_ES_ASYNCDONTCARE | TF_ES_READWRITE, &phrSession); | ||
return TRUE; | ||
} | ||
|
||
STDMETHODIMP Tsf::OnSetFocus(BOOL fForeground) { return S_OK; } | ||
|
||
STDMETHODIMP Tsf::OnTestKeyDown(ITfContext *pContext, WPARAM wParam, | ||
LPARAM lParam, BOOL *pfEaten) { | ||
if (keyDownHandled_) { | ||
*pfEaten = TRUE; | ||
} else { | ||
*pfEaten = keyDownHandled_ = processKey(wParam, lParam); | ||
} | ||
return S_OK; | ||
} | ||
|
||
STDMETHODIMP Tsf::OnKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, | ||
BOOL *pfEaten) { | ||
if (keyDownHandled_) { | ||
keyDownHandled_ = FALSE; | ||
*pfEaten = TRUE; | ||
} else { | ||
*pfEaten = keyDownHandled_ = processKey(wParam, lParam); | ||
} | ||
return S_OK; | ||
} | ||
|
||
STDMETHODIMP Tsf::OnTestKeyUp(ITfContext *pContext, WPARAM wParam, | ||
LPARAM lParam, BOOL *pfEaten) { | ||
return S_OK; | ||
} | ||
|
||
STDMETHODIMP Tsf::OnKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, | ||
BOOL *pfEaten) { | ||
return S_OK; | ||
} | ||
|
||
STDMETHODIMP Tsf::OnPreservedKey(ITfContext *pContext, REFGUID rguid, | ||
BOOL *pfEaten) { | ||
return S_OK; | ||
} | ||
} // namespace fcitx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#include "tsf.h" | ||
|
||
namespace fcitx { | ||
bool Tsf::initTextEditSink(CComPtr<ITfDocumentMgr> documentMgr) { | ||
CComPtr<ITfSource> source; | ||
// clear out any previous sink first | ||
if (textEditSinkCookie_ != TF_INVALID_COOKIE) { | ||
if (SUCCEEDED(textEditSinkContext_->QueryInterface(IID_ITfSource, | ||
(void **)&source))) { | ||
source->UnadviseSink(textEditSinkCookie_); | ||
} | ||
textEditSinkContext_ = nullptr; | ||
textEditSinkCookie_ = TF_INVALID_COOKIE; | ||
} | ||
if (documentMgr == nullptr) { | ||
return true; // caller just wanted to clear the previous sink | ||
} | ||
if (FAILED(documentMgr->GetTop(&textEditSinkContext_))) { | ||
return false; | ||
} | ||
if (textEditSinkContext_ == nullptr) { | ||
return true; // empty document, no sink possible | ||
} | ||
source.Release(); | ||
bool ret = false; | ||
if (SUCCEEDED(textEditSinkContext_->QueryInterface(IID_ITfSource, | ||
(void **)&source))) { | ||
if (SUCCEEDED(source->AdviseSink(IID_ITfTextEditSink, | ||
(ITfTextEditSink *)this, | ||
&textEditSinkCookie_))) { | ||
ret = true; | ||
} else { | ||
textEditSinkCookie_ = TF_INVALID_COOKIE; | ||
} | ||
} | ||
if (!ret) { | ||
textEditSinkContext_ = nullptr; | ||
} | ||
return ret; | ||
} | ||
|
||
STDMETHODIMP Tsf::OnEndEdit(ITfContext *pic, TfEditCookie ecReadOnly, | ||
ITfEditRecord *pEditRecord) { | ||
return S_OK; | ||
} | ||
} // namespace fcitx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#include "tsf.h" | ||
|
||
namespace fcitx { | ||
STDAPI Tsf::Activate(ITfThreadMgr *pThreadMgr, TfClientId tfClientId) { | ||
return ActivateEx(pThreadMgr, tfClientId, 0U); | ||
} | ||
|
||
STDAPI Tsf::Deactivate() { | ||
initTextEditSink(CComPtr<ITfDocumentMgr>()); | ||
uninitThreadMgrEventSink(); | ||
uninitKeyEventSink(); | ||
threadMgr_ = nullptr; | ||
clientId_ = TF_CLIENTID_NULL; | ||
return S_OK; | ||
} | ||
|
||
STDAPI Tsf::ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClientId, | ||
DWORD dwFlags) { | ||
CComPtr<ITfDocumentMgr> documentMgr; | ||
threadMgr_ = pThreadMgr; | ||
clientId_ = tfClientId; | ||
if (!initThreadMgrEventSink()) { | ||
goto ActivateExError; | ||
} | ||
|
||
if ((threadMgr_->GetFocus(&documentMgr) == S_OK) && | ||
(documentMgr != nullptr)) { | ||
initTextEditSink(documentMgr); | ||
} | ||
|
||
if (!initKeyEventSink()) { | ||
goto ActivateExError; | ||
} | ||
|
||
return S_OK; | ||
|
||
ActivateExError: | ||
Deactivate(); | ||
return E_FAIL; | ||
} | ||
} // namespace fcitx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include "tsf.h" | ||
|
||
namespace fcitx { | ||
bool Tsf::initThreadMgrEventSink() { | ||
CComPtr<ITfSource> source; | ||
if (threadMgr_->QueryInterface(IID_ITfSource, (void **)&source) != S_OK) { | ||
return false; | ||
} | ||
if (source->AdviseSink(IID_ITfThreadMgrEventSink, | ||
(ITfThreadMgrEventSink *)this, | ||
&threadMgrEventSinkCookie_) != S_OK) { | ||
threadMgrEventSinkCookie_ = TF_INVALID_COOKIE; | ||
} | ||
return threadMgrEventSinkCookie_ != TF_INVALID_COOKIE; | ||
} | ||
|
||
void Tsf::uninitThreadMgrEventSink() { | ||
CComPtr<ITfSource> source; | ||
if (threadMgrEventSinkCookie_ == TF_INVALID_COOKIE) { | ||
return; | ||
} | ||
if (SUCCEEDED( | ||
threadMgr_->QueryInterface(IID_ITfSource, (void **)&source))) { | ||
source->UnadviseSink(threadMgrEventSinkCookie_); | ||
} | ||
threadMgrEventSinkCookie_ = TF_INVALID_COOKIE; | ||
} | ||
|
||
STDMETHODIMP Tsf::OnInitDocumentMgr(ITfDocumentMgr *pDocMgr) { return S_OK; } | ||
|
||
STDMETHODIMP Tsf::OnUninitDocumentMgr(ITfDocumentMgr *pDocMgr) { return S_OK; } | ||
|
||
STDMETHODIMP Tsf::OnSetFocus(ITfDocumentMgr *pDocMgrFocus, | ||
ITfDocumentMgr *pDocMgrPrevFocus) { | ||
initTextEditSink(pDocMgrFocus); | ||
return S_OK; | ||
} | ||
|
||
STDMETHODIMP Tsf::OnPushContext(ITfContext *pContext) { return S_OK; } | ||
|
||
STDMETHODIMP Tsf::OnPopContext(ITfContext *pContext) { return S_OK; } | ||
} // namespace fcitx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#include "tsf.h" | ||
#include <cassert> | ||
|
||
extern void DllAddRef(); | ||
extern void DllRelease(); | ||
|
||
namespace fcitx { | ||
Tsf::Tsf() { DllAddRef(); } | ||
|
||
Tsf::~Tsf() { DllRelease(); } | ||
|
||
// Windows also queries ITfDisplayAttributeCollectionProvider | ||
// {3977526D-1A0A-435A-8D06-ECC9516B484F} which is internal and we simply | ||
// ignore. | ||
STDAPI Tsf::QueryInterface(REFIID riid, void **ppvObject) { | ||
if (ppvObject == nullptr) { | ||
return E_INVALIDARG; | ||
} | ||
*ppvObject = nullptr; | ||
|
||
if (IsEqualIID(riid, IID_IUnknown) || | ||
IsEqualIID(riid, IID_ITfTextInputProcessor)) | ||
*ppvObject = (ITfTextInputProcessor *)this; | ||
else if (IsEqualIID(riid, IID_ITfTextInputProcessorEx)) | ||
*ppvObject = (ITfTextInputProcessorEx *)this; | ||
else if (IsEqualIID(riid, IID_ITfThreadMgrEventSink)) | ||
*ppvObject = (ITfThreadMgrEventSink *)this; | ||
else if (IsEqualIID(riid, IID_ITfTextEditSink)) | ||
*ppvObject = (ITfTextEditSink *)this; | ||
else if (IsEqualIID(riid, IID_ITfKeyEventSink)) | ||
*ppvObject = (ITfKeyEventSink *)this; | ||
else if (IsEqualIID(riid, IID_ITfEditSession)) | ||
*ppvObject = (ITfEditSession *)this; | ||
|
||
if (*ppvObject) { | ||
AddRef(); | ||
return S_OK; | ||
} | ||
return E_NOINTERFACE; | ||
} | ||
|
||
STDAPI_(ULONG) Tsf::AddRef() { return ++refCount_; } | ||
|
||
STDAPI_(ULONG) Tsf::Release() { | ||
LONG ret = --refCount_; | ||
assert(refCount_ >= 0); | ||
if (refCount_ == 0) { | ||
delete this; | ||
} | ||
return ret; | ||
} | ||
} // namespace fcitx |
Oops, something went wrong.