port 4-a: text input through CPythonIME (login typed, in-game chat)
- UserInterface/PythonIME(+Module) ported verbatim; ime module stubs removed, initime() after initdbg() - EterLib/IME.cpp in platform/: 40250 buffer/WMChar bodies, IMM/TSF processors no-op; committed multi-byte text via PythonBoot::UIChar emulating GCS_RESULTSTR - GameApplicationAdapter RunIME* -> CWindowManager; Godot keys -> ui_ime_key/ui_char - port.login_flow/login_live type the account through the IME; chat CG_CHAT round-trip on the fake server - python_game_render_test logs in with Godot key events Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1bda4390d6
commit
6ea0fa9889
@@ -1,381 +1,666 @@
|
||||
// Platform skeleton for EterLib/IME.h (40250 EterLib/IME.cpp), generated by platform_stub.py.
|
||||
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
|
||||
// Platform implementation of EterLib/IME.h (40250 EterLib/IME.cpp).
|
||||
// The edit buffer (m_wText, cursor, SetText/GetText, OnChar/InsertString, IsMax, the colour-tag aware cursor
|
||||
// moves) and WMChar are the 40250 bodies verbatim. What 40250 gets from Win32 IMM/TSF — composition strings,
|
||||
// the candidate list, the reading window, keyboard-layout code pages — has no counterpart under Godot: the
|
||||
// host delivers committed characters only (Metin2PythonHost.ui_char -> WMChar, or InsertString for text the
|
||||
// input code page cannot hold, which is what 40250's ResultProcess does with a GCS_RESULTSTR). Those entry
|
||||
// points keep 40250's "no IME present" behaviour: no composition, empty candidate/reading lists.
|
||||
#include "EterLib/StdAfx.h"
|
||||
#include "EterLib/IME.h"
|
||||
#include "EterLib/TextTag.h"
|
||||
#include "EterLib/GrpTextInstance.h"
|
||||
#include "EterLib/Util.h"
|
||||
|
||||
#include "../PlatformStub.h"
|
||||
#include <algorithm>
|
||||
#include <cwctype>
|
||||
|
||||
namespace
|
||||
{
|
||||
// 40250 s_aszIndicator[INDICATOR_NON_IME] (IME.cpp:67); CheckInputLocale overwrites it with the locale's
|
||||
// two-letter abbreviation, which here is the locale code page's language.
|
||||
wchar_t s_aszNonImeIndicator[3] = L"En";
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/ /* Public */
|
||||
CIME::CIME()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
ms_hWnd = NULL;
|
||||
|
||||
ms_bCandidateList = false;
|
||||
ms_bReadingInformation = false;
|
||||
|
||||
Clear();
|
||||
|
||||
m_max = 0;
|
||||
m_userMax = 0;
|
||||
|
||||
m_bOnlyNumberMode = FALSE;
|
||||
m_hOrgIMC = NULL;
|
||||
|
||||
m_bEnablePaste = false;
|
||||
m_bUseDefaultIME = false;
|
||||
}
|
||||
|
||||
CIME::~CIME()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CIME::Initialize(HWND) -> bool
|
||||
// PORT: 40250 loads imm32.dll, disables Cicero, reads the keyboard layout and sets up the TSF sinks. The
|
||||
// Godot host has no IMM context; only the part the edit buffer depends on — the input/output code page from
|
||||
// CheckInputLocale and SetSupportLevel(2) — is kept.
|
||||
bool CIME::Initialize(HWND hWnd)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
}
|
||||
if(ms_bInitialized)
|
||||
return true;
|
||||
ms_hWnd = hWnd;
|
||||
|
||||
auto CIME::Uninitialize() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
ms_bDisableIMECompletely = true;
|
||||
ms_bInitialized = true;
|
||||
|
||||
auto CIME::Clear() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
CheckInputLocale();
|
||||
ChangeInputLanguageWorker();
|
||||
SetSupportLevel(2);
|
||||
|
||||
auto CIME::SetMax(int) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
ms_bUILessMode = false;
|
||||
CheckToggleState();
|
||||
|
||||
auto CIME::SetUserMax(int) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return true;
|
||||
}
|
||||
|
||||
auto CIME::SetText(const char *, int) -> void
|
||||
void CIME::Uninitialize()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
if ( !ms_bInitialized )
|
||||
return;
|
||||
ms_hWnd = NULL;
|
||||
m_hOrgIMC = NULL;
|
||||
ms_bInitialized = false;
|
||||
}
|
||||
|
||||
auto CIME::GetText(std::string &, bool) -> int
|
||||
void CIME::UseDefaultIME()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
m_bUseDefaultIME = true;
|
||||
}
|
||||
|
||||
auto CIME::GetCodePageText() -> const char *
|
||||
bool CIME::IsIMEEnabled()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<const char *>();
|
||||
return ms_bImeEnabled;
|
||||
}
|
||||
|
||||
auto CIME::GetCodePage() -> int
|
||||
// PORT: 40250 ImmAssociateContext()s the window; ms_bDisableIMECompletely (no imm32) forces bEnable=false,
|
||||
// which is always the case here.
|
||||
void CIME::EnableIME(bool bEnable)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
if (!ms_bInitialized || !ms_hWnd)
|
||||
return;
|
||||
if (ms_bDisableIMECompletely)
|
||||
bEnable = false;
|
||||
ms_bImeEnabled = bEnable;
|
||||
if (bEnable)
|
||||
CheckToggleState();
|
||||
}
|
||||
|
||||
auto CIME::GetCandidateCount() -> int
|
||||
void CIME::DisableIME()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
EnableIME(false);
|
||||
}
|
||||
|
||||
auto CIME::GetCandidatePageCount() -> int
|
||||
void CIME::EnableCaptureInput()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
ms_bCaptureInput = true;
|
||||
}
|
||||
|
||||
auto CIME::GetCandidate(DWORD, std::string &) -> int
|
||||
void CIME::DisableCaptureInput()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
ms_bCaptureInput = false;
|
||||
}
|
||||
|
||||
auto CIME::GetCandidateSelection() -> int
|
||||
bool CIME::IsCaptureEnabled()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
return ms_bCaptureInput;
|
||||
}
|
||||
|
||||
auto CIME::GetReading(std::string &) -> int
|
||||
void CIME::Clear()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
}
|
||||
ms_lastpos = 0;
|
||||
ms_curpos = 0;
|
||||
|
||||
auto CIME::GetReadingError() -> int
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
ms_compLen = 0;
|
||||
ms_ulbegin = 0;
|
||||
ms_ulend = 0;
|
||||
}
|
||||
|
||||
auto CIME::SetInputMode(DWORD) -> void
|
||||
int CIME::GetReading(std::string & rstrText)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
char reading[IMEREADING_MAXLEN];
|
||||
|
||||
auto CIME::GetInputMode() -> DWORD
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<DWORD>();
|
||||
if(ms_wstrReading.size() == 0)
|
||||
return 0;
|
||||
int readingLen = WideCharToMultiByte(ms_uOutputCodePage, 0, &ms_wstrReading[0], ms_wstrReading.size(), reading, sizeof(reading), NULL, NULL);
|
||||
|
||||
rstrText.append(GetCodePageText());
|
||||
rstrText.append(reading, reading + readingLen);
|
||||
|
||||
return rstrText.size();
|
||||
}
|
||||
|
||||
auto CIME::IsIMEEnabled() -> bool
|
||||
int CIME::GetReadingError()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
return ms_iReadingError;
|
||||
}
|
||||
|
||||
auto CIME::EnableIME(bool) -> void
|
||||
void CIME::SetMax(int iMax)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
m_max = iMax;
|
||||
}
|
||||
|
||||
auto CIME::DisableIME() -> void
|
||||
void CIME::SetUserMax(int iMax)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
m_userMax = iMax;
|
||||
}
|
||||
|
||||
auto CIME::EnableCaptureInput() -> void
|
||||
void CIME::SetText(const char* szText, int len)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
ms_compLen = 0;
|
||||
ms_ulbegin = 0;
|
||||
ms_ulend = 0;
|
||||
|
||||
const char* begin = szText;
|
||||
const char* end = begin + len;
|
||||
const char* iter = FindToken(begin, end);
|
||||
|
||||
int m_wTextLen = sizeof(m_wText)/sizeof(wchar_t);
|
||||
|
||||
ms_lastpos = MultiByteToWideChar(ms_uInputCodePage, 0, begin, iter-begin, m_wText, m_wTextLen);
|
||||
|
||||
if (iter < end)
|
||||
ms_lastpos += MultiByteToWideChar(ReadToken(iter), 0, (iter+5), end-(iter+5), m_wText+ms_lastpos, m_wTextLen-ms_lastpos);
|
||||
|
||||
ms_curpos = std::min(ms_curpos, ms_lastpos);
|
||||
}
|
||||
|
||||
auto CIME::DisableCaptureInput() -> void
|
||||
int CIME::GetText(std::string & rstrText, bool addCodePage)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
int outCodePage = ms_uOutputCodePage;
|
||||
int dataCodePage;
|
||||
switch (outCodePage)
|
||||
{
|
||||
//case 1256: // ARABIC
|
||||
case 1268: // VIETNAM
|
||||
dataCodePage = CP_UTF8;
|
||||
break;
|
||||
default:
|
||||
dataCodePage = outCodePage;
|
||||
}
|
||||
|
||||
int len = 0;
|
||||
char text[IMESTR_MAXLEN];
|
||||
|
||||
len += WideCharToMultiByte(dataCodePage, 0, m_wText, ms_curpos, text, sizeof(text)-len, NULL, NULL);
|
||||
len += WideCharToMultiByte(dataCodePage, 0, m_wszComposition, ms_compLen, text+len, sizeof(text)-len, NULL, NULL);
|
||||
len += WideCharToMultiByte(dataCodePage, 0, m_wText+ms_curpos, ms_lastpos-ms_curpos, text+len, sizeof(text)-len, NULL, NULL);
|
||||
|
||||
int i;
|
||||
for(i=0; i<len; ++i)
|
||||
if((BYTE)text[i] > 0x7F) break;
|
||||
|
||||
if(i == len)
|
||||
{
|
||||
rstrText.append(text, text+len);
|
||||
}
|
||||
else
|
||||
{
|
||||
rstrText.append(text, text+i);
|
||||
|
||||
//if (addCodePage)
|
||||
// rstrText.append(GetCodePageText());
|
||||
|
||||
rstrText.append(text+i, text+len);
|
||||
}
|
||||
|
||||
return rstrText.size();
|
||||
}
|
||||
|
||||
auto CIME::IsCaptureEnabled() -> bool
|
||||
const char* CIME::GetCodePageText()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
static char szCodePage[16];
|
||||
|
||||
const int defCodePage = GetDefaultCodePage();
|
||||
const int outCodePage = ms_uOutputCodePage;
|
||||
|
||||
if (outCodePage != defCodePage)
|
||||
{
|
||||
sprintf(szCodePage, "@%04d", outCodePage);
|
||||
}
|
||||
else
|
||||
{
|
||||
szCodePage[0] = 0;
|
||||
}
|
||||
|
||||
return szCodePage;
|
||||
}
|
||||
|
||||
auto CIME::SetNumberMode() -> void
|
||||
int CIME::GetCodePage()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return ms_uOutputCodePage;
|
||||
}
|
||||
|
||||
auto CIME::SetStringMode() -> void
|
||||
int CIME::GetCandidatePageCount()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return ms_dwCandidatePageSize;
|
||||
}
|
||||
|
||||
auto CIME::__IsWritable(wchar_t) -> bool
|
||||
int CIME::GetCandidateCount()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
return ms_dwCandidateCount;
|
||||
}
|
||||
|
||||
auto CIME::AddExceptKey(wchar_t) -> void
|
||||
int CIME::GetCandidate(DWORD index, std::string & rstrText)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
if(index >= MAX_CANDLIST)
|
||||
return 0;
|
||||
|
||||
LPCWSTR wszText = ms_wszCandidate[index];
|
||||
if(wszText == NULL)
|
||||
return 0;
|
||||
|
||||
int wTextLen = wcslen(wszText);
|
||||
if(wTextLen == 0)
|
||||
return 0;
|
||||
|
||||
char text[IMESTR_MAXLEN];
|
||||
int len = ::WideCharToMultiByte(CP_UTF8, 0, wszText, wTextLen, text, sizeof(text), 0, 0);
|
||||
|
||||
rstrText.append("@9999");
|
||||
rstrText.append(text, text+len);
|
||||
|
||||
return wTextLen;
|
||||
}
|
||||
|
||||
auto CIME::ClearExceptKey() -> void
|
||||
int CIME::GetCandidateSelection()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return ms_dwCandidateSelection;
|
||||
}
|
||||
|
||||
auto CIME::PasteTextFromClipBoard() -> void
|
||||
// PORT: 40250 ImmSetConversionStatus / ImmGetConversionStatus. Without an IMM context the conversion mode is
|
||||
// the alphanumeric one (IME_CMODE_ALPHANUMERIC == 0) and cannot be changed.
|
||||
void CIME::SetInputMode(DWORD)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CIME::EnablePaste(bool) -> void
|
||||
DWORD CIME::GetInputMode()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto CIME::PasteString(const char *) -> void
|
||||
void CIME::SetNumberMode()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
m_bOnlyNumberMode = TRUE;
|
||||
}
|
||||
|
||||
auto CIME::FinalizeString(bool) -> void
|
||||
void CIME::SetStringMode()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
m_bOnlyNumberMode = FALSE;
|
||||
}
|
||||
|
||||
auto CIME::UseDefaultIME() -> void
|
||||
void CIME::AddExceptKey(wchar_t key)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
m_exceptKey.push_back(key);
|
||||
}
|
||||
|
||||
auto CIME::GetCurPos() -> int
|
||||
void CIME::ClearExceptKey()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
m_exceptKey.clear();
|
||||
}
|
||||
|
||||
auto CIME::GetCompLen() -> int
|
||||
bool CIME::__IsWritable(wchar_t key)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
if ( m_exceptKey.end() == std::find(m_exceptKey.begin(),m_exceptKey.end(),key) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
auto CIME::GetULBegin() -> int
|
||||
void CIME::EnablePaste(bool bFlag)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
m_bEnablePaste = bFlag;
|
||||
}
|
||||
|
||||
auto CIME::GetULEnd() -> int
|
||||
// PORT: 40250 reads CF_TEXT from the Win32 clipboard. The host clipboard is not wired to the extension yet,
|
||||
// so this pastes nothing (the same as an empty clipboard).
|
||||
void CIME::PasteTextFromClipBoard()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<int>();
|
||||
if (!m_bEnablePaste)
|
||||
return;
|
||||
}
|
||||
|
||||
auto CIME::CloseCandidateList() -> void
|
||||
// PORT: 40250 cancels the IMM composition string and closes the candidate list. There is no composition
|
||||
// here; the candidate-list close (and its event) is kept.
|
||||
void CIME::FinalizeString(bool)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
static bool s_bProcessing = false; // to avoid infinite recursion
|
||||
if ( !ms_bInitialized || s_bProcessing )
|
||||
return;
|
||||
s_bProcessing = true;
|
||||
CloseCandidateList();
|
||||
s_bProcessing = false;
|
||||
}
|
||||
|
||||
auto CIME::CloseReadingInformation() -> void
|
||||
int CIME::GetCompLen()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return ms_compLen;
|
||||
}
|
||||
|
||||
auto CIME::ChangeInputLanguage() -> void
|
||||
int CIME::GetULBegin()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return ms_ulbegin;
|
||||
}
|
||||
|
||||
auto CIME::ChangeInputLanguageWorker() -> void
|
||||
int CIME::GetULEnd()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return ms_ulend;
|
||||
}
|
||||
|
||||
auto CIME::WMInputLanguage(HWND, UINT, WPARAM, LPARAM) -> LRESULT
|
||||
void CIME::CloseCandidateList()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<LRESULT>();
|
||||
ms_bCandidateList = false;
|
||||
ms_dwCandidateCount = 0;
|
||||
memset(&ms_wszCandidate, 0, sizeof(ms_wszCandidate));
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnCloseCandidateList();
|
||||
}
|
||||
|
||||
auto CIME::WMStartComposition(HWND, UINT, WPARAM, LPARAM) -> LRESULT
|
||||
void CIME::CloseReadingInformation()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<LRESULT>();
|
||||
CIME::ms_bReadingInformation = false;
|
||||
if(CIME::ms_pEvent)
|
||||
CIME::ms_pEvent->OnCloseReadingWnd();
|
||||
}
|
||||
|
||||
auto CIME::WMComposition(HWND, UINT, WPARAM, LPARAM) -> LRESULT
|
||||
// PORT: 40250 re-reads the keyboard layout (GETLANG) and re-applies the IME support level when the language
|
||||
// changed. The host has one fixed input locale, so only the toggle check and the code-page event remain.
|
||||
void CIME::ChangeInputLanguage()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<LRESULT>();
|
||||
CheckToggleState();
|
||||
ChangeInputLanguageWorker();
|
||||
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnChangeCodePage();
|
||||
}
|
||||
|
||||
auto CIME::WMEndComposition(HWND, UINT, WPARAM, LPARAM) -> LRESULT
|
||||
void CIME::ChangeInputLanguageWorker()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<LRESULT>();
|
||||
if ( !ms_bUILessMode )
|
||||
ms_iCandListIndexBase = 1;
|
||||
SetupImeApi();
|
||||
}
|
||||
|
||||
auto CIME::WMNotify(HWND, UINT, WPARAM, LPARAM) -> LRESULT
|
||||
// PORT: 40250 forces level 3 for the Korean keyboard layout; there is no keyboard layout here.
|
||||
void CIME::SetSupportLevel( DWORD dwImeLevel )
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<LRESULT>();
|
||||
if ( dwImeLevel < 2 || 3 < dwImeLevel )
|
||||
return;
|
||||
ms_dwIMELevel = dwImeLevel;
|
||||
// cancel current composition string.
|
||||
FinalizeString();
|
||||
}
|
||||
|
||||
auto CIME::WMChar(HWND, UINT, WPARAM, LPARAM) -> LRESULT
|
||||
LRESULT CIME::WMInputLanguage(HWND, UINT, WPARAM, LPARAM)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<LRESULT>();
|
||||
ChangeInputLanguage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto CIME::IncCurPos() -> void
|
||||
LRESULT CIME::WMStartComposition(HWND, UINT, WPARAM, LPARAM)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return 1L;
|
||||
}
|
||||
|
||||
auto CIME::DecCurPos() -> void
|
||||
// PORT: 40250 pulls GCS_RESULTSTR/GCS_COMPSTR out of the IMM context. The host never sends compositions.
|
||||
LRESULT CIME::WMComposition(HWND, UINT, WPARAM, LPARAM)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto CIME::SetCurPos(int) -> void
|
||||
LRESULT CIME::WMEndComposition(HWND, UINT, WPARAM, LPARAM)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
ms_compLen = 0;
|
||||
ms_ulbegin = 0;
|
||||
ms_ulend = 0;
|
||||
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnUpdate();
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
auto CIME::DelCurPos() -> void
|
||||
// PORT: 40250 handles IMN_* candidate/reading/toggle notifications from IMM; none are sent here.
|
||||
LRESULT CIME::WMNotify(HWND, UINT, WPARAM, LPARAM)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto CIME::CheckInputLocale() -> void
|
||||
LRESULT CIME::WMChar(HWND /*hWnd*/, UINT /*uiMsg*/, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
unsigned char c = (unsigned char)(wParam & 0xff);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 8:
|
||||
if(ms_bCaptureInput == false)
|
||||
return 0;
|
||||
if (ms_curpos > 0)
|
||||
{
|
||||
DecCurPos();
|
||||
DelCurPos();
|
||||
}
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnUpdate();
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
if(ms_pEvent) {
|
||||
if (ms_pEvent->OnWM_CHAR(wParam, lParam))
|
||||
break;
|
||||
}
|
||||
if(ms_bCaptureInput == false)
|
||||
return 0;
|
||||
wchar_t w[10];
|
||||
MultiByteToWideChar(ms_uInputCodePage, 0, (char*)&c, 1, w, 1);
|
||||
|
||||
OnChar(w[0]);
|
||||
if (w[0] == L'|')
|
||||
OnChar(w[0]);
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnUpdate();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto CIME::CheckToggleState() -> void
|
||||
/*---------------------------------------------------------------------------*/ /* Protected */
|
||||
void CIME::IncCurPos()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
if (ms_curpos < ms_lastpos)
|
||||
{
|
||||
int pos = FindColorTagEndPosition(m_wText + ms_curpos, ms_lastpos - ms_curpos);
|
||||
|
||||
if (pos > 0)
|
||||
ms_curpos = std::min(ms_lastpos, std::max(0, ms_curpos + (pos + 1)));
|
||||
else
|
||||
++ms_curpos;
|
||||
//++ms_curpos;
|
||||
}
|
||||
}
|
||||
|
||||
auto CIME::SetSupportLevel(DWORD) -> void
|
||||
void CIME::DecCurPos()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
if (ms_curpos > 0)
|
||||
{
|
||||
int pos = FindColorTagStartPosition(m_wText + ms_curpos - 1, ms_curpos);
|
||||
|
||||
if (pos > 0)
|
||||
ms_curpos = std::min(ms_lastpos, std::max(0, ms_curpos - (pos + 1)));
|
||||
else
|
||||
--ms_curpos;
|
||||
//--ms_curpos;
|
||||
}
|
||||
}
|
||||
|
||||
auto CIME::InsertString(wchar_t *, int) -> void
|
||||
int CIME::GetCurPos()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
int pos = GetTextTagOutputLen(m_wText, ms_curpos);
|
||||
return pos;
|
||||
//return ms_curpos;
|
||||
}
|
||||
|
||||
auto CIME::OnChar(wchar_t) -> void
|
||||
void CIME::SetCurPos(int offset)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
if (offset < 0 || offset > ms_lastpos)
|
||||
{
|
||||
ms_curpos = ms_lastpos;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// offset is a position in the rendered text, so it has to be mapped back to the buffer.
|
||||
//ms_curpos = min(ms_lastpos, offset);
|
||||
ms_curpos = std::min(ms_lastpos, GetTextTagInternalPosFromRenderPos(m_wText, ms_lastpos, offset));
|
||||
}
|
||||
}
|
||||
|
||||
auto CIME::GetCodePageFromLang(LANGID) -> UINT
|
||||
void CIME::DelCurPos()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<UINT>();
|
||||
if (ms_curpos < ms_lastpos)
|
||||
{
|
||||
int eraseCount = FindColorTagEndPosition(m_wText + ms_curpos, ms_lastpos - ms_curpos) + 1;
|
||||
// PORT: 40250 wcscpy()s the overlapping tail down; that is undefined for overlapping buffers, and the
|
||||
// buffer is not guaranteed NUL-terminated at ms_lastpos, so move exactly the live tail.
|
||||
memmove(m_wText + ms_curpos, m_wText + ms_curpos + eraseCount, sizeof(wchar_t) * (ms_lastpos - ms_curpos - eraseCount));
|
||||
ms_lastpos -= eraseCount;
|
||||
ms_curpos = std::min(ms_lastpos, ms_curpos);
|
||||
}
|
||||
}
|
||||
|
||||
auto CIME::ResultProcess(HIMC) -> void
|
||||
void CIME::PasteString(const char * str)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
const char * begin = str;
|
||||
const char * end = str + strlen(str);
|
||||
wchar_t m_wText[IMESTR_MAXLEN];
|
||||
int wstrLen = MultiByteToWideChar(ms_uInputCodePage, 0, begin, end - begin, m_wText, IMESTR_MAXLEN);
|
||||
InsertString(m_wText, wstrLen);
|
||||
if(ms_pEvent)
|
||||
ms_pEvent->OnUpdate();
|
||||
}
|
||||
|
||||
auto CIME::CompositionProcessBuilding(HIMC) -> void
|
||||
// PORT: 40250 reads the keyboard layout's default ANSI code page (GetLocaleInfoA LOCALE_IDEFAULTANSICODEPAGE).
|
||||
// The host's input locale is the client locale, so its code page (SetDefaultCodePage from locale.cfg) is used.
|
||||
void CIME::CheckInputLocale()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
static UINT s_uPrevCodePage = 0xFFFF;
|
||||
|
||||
ms_uInputCodePage = GetDefaultCodePage();
|
||||
if ( s_uPrevCodePage == ms_uInputCodePage )
|
||||
return;
|
||||
s_uPrevCodePage = ms_uInputCodePage;
|
||||
|
||||
ms_bVerticalCandidate = false;
|
||||
ms_wszCurrentIndicator = s_aszNonImeIndicator;
|
||||
|
||||
if(ms_uOutputCodePage != 1256) {
|
||||
ms_uOutputCodePage = ms_uInputCodePage;
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
|
||||
auto CIME::CompositionProcess(HIMC) -> void
|
||||
// PORT: 40250 asks IMM whether an IME is open; there is none, so the state is IMEUI_STATE_OFF (0).
|
||||
void CIME::CheckToggleState()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
CheckInputLocale();
|
||||
ms_bChineseIME = false;
|
||||
ms_dwImeState = 0;
|
||||
}
|
||||
|
||||
auto CIME::AttributeProcess(HIMC) -> void
|
||||
/*---------------------------------------------------------------------------*/ /* Private */
|
||||
void CIME::InsertString(wchar_t* wString, int iSize)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
if (IsMax(wString, iSize))
|
||||
return;
|
||||
|
||||
if (ms_curpos < ms_lastpos)
|
||||
memmove(m_wText+ms_curpos+iSize, m_wText+ms_curpos, sizeof(wchar_t)*(ms_lastpos-ms_curpos));
|
||||
|
||||
memcpy(m_wText+ms_curpos, wString, sizeof(wchar_t)*iSize);
|
||||
|
||||
ms_curpos += iSize;
|
||||
ms_lastpos += iSize;
|
||||
}
|
||||
|
||||
auto CIME::CandidateProcess(HIMC) -> void
|
||||
void CIME::OnChar(wchar_t c)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
if (m_bOnlyNumberMode)
|
||||
if (!iswdigit(c))
|
||||
return;
|
||||
|
||||
if (!__IsWritable(c))
|
||||
return;
|
||||
|
||||
InsertString(&c, 1);
|
||||
}
|
||||
|
||||
auto CIME::ReadingProcess(HIMC) -> void
|
||||
// PORT: 40250 maps a keyboard-layout LANGID to its ANSI code page. Only CheckInputLocale's code page is used
|
||||
// here (see there), so this answers with it.
|
||||
UINT CIME::GetCodePageFromLang(LANGID)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return GetDefaultCodePage();
|
||||
}
|
||||
|
||||
auto CIME::IsMax(const wchar_t *, int) -> bool
|
||||
// PORT: the IMM composition/candidate/reading processors (40250 IME.cpp:951-1227). No IMM context exists.
|
||||
void CIME::ResultProcess(HIMC) {}
|
||||
void CIME::CompositionProcessBuilding(HIMC) {}
|
||||
void CIME::CompositionProcess(HIMC) {}
|
||||
void CIME::AttributeProcess(HIMC) {}
|
||||
void CIME::CandidateProcess(HIMC) {}
|
||||
void CIME::ReadingProcess(HIMC) {}
|
||||
|
||||
bool CIME::IsMax(const wchar_t* wInput, int len)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
if (ms_lastpos + len > IMESTR_MAXLEN)
|
||||
return true;
|
||||
|
||||
int textLen = WideCharToMultiByte(ms_uOutputCodePage, 0, m_wText, ms_lastpos, 0, 0, NULL, NULL);
|
||||
int inputLen = WideCharToMultiByte(ms_uOutputCodePage, 0, wInput, len, 0, 0, NULL, NULL);
|
||||
//return textLen + inputLen > m_max;
|
||||
|
||||
if (textLen + inputLen > m_max)
|
||||
return true;
|
||||
else if (m_userMax != 0 && m_max != m_userMax)
|
||||
{
|
||||
std::wstring str = GetTextTagOutputString(m_wText, ms_lastpos);
|
||||
std::wstring input = GetTextTagOutputString(wInput, len);
|
||||
int textLen = WideCharToMultiByte(ms_uOutputCodePage, 0, str.c_str(), str.length(), 0, 0, NULL, NULL);
|
||||
int inputLen = WideCharToMultiByte(ms_uOutputCodePage, 0, input.c_str(), input.length(), 0, 0, NULL, NULL);
|
||||
return textLen + inputLen > m_userMax;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto CIME::GetImeId(UINT) -> DWORD
|
||||
// PORT: 40250 identifies the CHT/CHS IME DLL version and the reading-window orientation. No IME DLL here.
|
||||
DWORD CIME::GetImeId(UINT)
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<DWORD>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto CIME::GetReadingWindowOrientation() -> bool
|
||||
bool CIME::GetReadingWindowOrientation()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<bool>();
|
||||
return true;
|
||||
}
|
||||
|
||||
auto CIME::SetupImeApi() -> void
|
||||
void CIME::SetupImeApi()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
_GetReadingString = NULL;
|
||||
_ShowReadingWindow = NULL;
|
||||
}
|
||||
|
||||
decltype(CIME::_ImmLockIMC) CIME::_ImmLockIMC{};
|
||||
|
||||
Reference in New Issue
Block a user