aboutsummaryrefslogtreecommitdiffhomepage
path: root/win32/ScintillaWin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'win32/ScintillaWin.cxx')
-rw-r--r--win32/ScintillaWin.cxx135
1 files changed, 133 insertions, 2 deletions
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx
index 67fddd1cb..1f2c354f5 100644
--- a/win32/ScintillaWin.cxx
+++ b/win32/ScintillaWin.cxx
@@ -205,6 +205,9 @@ class ScintillaWin :
static HINSTANCE hInstance;
+ int tmpCaretStyle;
+ bool compstrExist;
+
#if defined(USE_D2D)
ID2D1HwndRenderTarget *pRenderTarget;
bool renderTargetValid;
@@ -236,6 +239,8 @@ class ScintillaWin :
virtual void StartDrag();
sptr_t WndPaint(uptr_t wParam);
sptr_t HandleComposition(uptr_t wParam, sptr_t lParam);
+ static bool KoreanIME();
+ sptr_t HandleCompositionKoreanIME(uptr_t wParam, sptr_t lParam);
UINT CodePageOfDocument();
virtual bool ValidCodePage(int codePage) const;
virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
@@ -343,6 +348,9 @@ ScintillaWin::ScintillaWin(HWND hwnd) {
TrackMouseEventFn = 0;
SetCoalescableTimerFn = 0;
+ tmpCaretStyle = 0;
+ compstrExist = false;
+
linesPerScroll = 0;
wheelDelta = 0; // Wheel delta from roll
@@ -703,6 +711,105 @@ sptr_t ScintillaWin::HandleComposition(uptr_t wParam, sptr_t lParam) {
return ::DefWindowProc(MainHWND(), WM_IME_COMPOSITION, wParam, lParam);
}
+bool ScintillaWin::KoreanIME() {
+ const int codePage = InputCodePage();
+ return codePage == 949 || codePage == 1361;
+}
+
+sptr_t ScintillaWin::HandleCompositionKoreanIME(uptr_t, sptr_t lParam) {
+
+ // copy & paste by johnsonj
+ // Great thanks to
+ // jiniya from http://www.jiniya.net/tt/494 for DBCS input with AddCharUTF()
+ // BLUEnLIVE from http://zockr.tistory.com/1118 for UNDO and inOverstrike
+
+ HIMC hIMC = ::ImmGetContext(MainHWND());
+ if (!hIMC) {
+ return 0;
+ }
+
+ const int maxLenInputIME = 4;
+ wchar_t wcs[maxLenInputIME];
+ int wides = 0;
+
+ // for avoiding inOverstrike condition in AddCharUTF()
+ bool tmpOverstrike = inOverstrike;
+
+ if (pdoc->TentativeActive()) {
+ pdoc->TentativeUndo();
+ } else {
+ // No tentative undo means start of this composition so
+ // fill in any virtual spaces.
+ AddCharUTF("", 0, false);
+ }
+
+ if (lParam & GCS_COMPSTR) {
+ long bytes = ::ImmGetCompositionStringW
+ (hIMC, GCS_COMPSTR, wcs, maxLenInputIME);
+ wides = bytes / 2;
+ inOverstrike = inOverstrike && (!compstrExist);
+ compstrExist = (wides != 0);
+ } else if (lParam & GCS_RESULTSTR) {
+ long bytes = ::ImmGetCompositionStringW
+ (hIMC, GCS_RESULTSTR, wcs, maxLenInputIME);
+ wides = bytes / 2;
+ compstrExist = (wides == 0);
+ inOverstrike = inOverstrike && (wides >= 2);
+ }
+
+ if (wides >= 1) {
+
+ char hanval[maxLenInputIME];
+ unsigned int hanlen = 0;
+
+ if (IsUnicodeMode()) {
+ hanlen = UTF8Length(wcs, wides);
+ UTF8FromUTF16(wcs, wides, hanval, hanlen);
+ hanval[hanlen] = '\0';
+ } else {
+ hanlen = ::WideCharToMultiByte(InputCodePage(), 0,
+ wcs, wides, hanval, sizeof(hanval) - 1, 0, 0);
+ hanval[hanlen] = '\0';
+ }
+
+ if (compstrExist) {
+ vs.caretStyle = CARETSTYLE_BLOCK;
+
+ bool tmpRecordingMacro = recordingMacro;
+ recordingMacro = false;
+ pdoc->TentativeStart();
+ AddCharUTF(hanval, hanlen, true);
+ recordingMacro = tmpRecordingMacro;
+
+ //NotifyChar() in AddCharUTF() may not know comprStr is deleted by undo.
+ Editor::NotifyChar((static_cast<unsigned char>(hanval[0]) << 8) |
+ static_cast<unsigned char>(hanval[1]));
+
+ for (size_t r = 0; r < sel.Count(); r++) { // for block caret
+ int positionInsert = sel.Range(r).Start().Position();
+ sel.Range(r).caret.SetPosition(positionInsert - hanlen);
+ sel.Range(r).anchor.SetPosition(positionInsert - hanlen);
+ }
+ } else {
+ AddCharUTF(hanval, hanlen, true);
+ }
+ }
+
+ // set the candidate window position for HANJA while composing.
+ Point pos = PointMainCaret();
+ CANDIDATEFORM CandForm;
+ CandForm.dwIndex = 0;
+ CandForm.dwStyle = CFS_CANDIDATEPOS;
+ CandForm.ptCurrentPos.x = static_cast<int>(pos.x);
+ CandForm.ptCurrentPos.y = static_cast<int>(pos.y + vs.lineHeight);
+ ::ImmSetCandidateWindow(hIMC, &CandForm);
+
+ ShowCaretAtCurrentPosition();
+ inOverstrike = tmpOverstrike;
+ ::ImmReleaseContext(MainHWND(), hIMC);
+ return 0;
+}
+
// Translate message IDs from WM_* and EM_* to SCI_* so can partly emulate Windows Edit control
static unsigned int SciMessageFromEM(unsigned int iMessage) {
switch (iMessage) {
@@ -1140,15 +1247,30 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
break;
case WM_IME_STARTCOMPOSITION: // dbcs
+ if (KoreanIME()) {
+ tmpCaretStyle = vs.caretStyle;
+ if (vs.caretStyle > CARETSTYLE_BLOCK) {
+ vs.caretStyle= CARETSTYLE_LINE;
+ }
+ return 0;
+ }
ImeStartComposition();
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case WM_IME_ENDCOMPOSITION: // dbcs
+ if (KoreanIME()) {
+ vs.caretStyle = tmpCaretStyle;
+ return 0;
+ }
ImeEndComposition();
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case WM_IME_COMPOSITION:
- return HandleComposition(wParam, lParam);
+ if (KoreanIME()) {
+ return HandleCompositionKoreanIME(wParam, lParam);
+ } else {
+ return HandleComposition(wParam, lParam);
+ }
case WM_IME_CHAR: {
AddCharBytes(HIBYTE(wParam), LOBYTE(wParam));
@@ -1184,6 +1306,16 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
capturedMouse = false;
return 0;
+ case WM_IME_SETCONTEXT:
+ if (KoreanIME()) {
+ if (wParam) {
+ LPARAM NoImeWin = lParam;
+ NoImeWin = NoImeWin & (~ISC_SHOWUICOMPOSITIONWINDOW);
+ return ::DefWindowProc(MainHWND(), iMessage, wParam, NoImeWin);
+ }
+ }
+ return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
+
// These are not handled in Scintilla and its faster to dispatch them here.
// Also moves time out to here so profile doesn't count lots of empty message calls.
@@ -1194,7 +1326,6 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
case WM_NCPAINT:
case WM_NCMOUSEMOVE:
case WM_NCLBUTTONDOWN:
- case WM_IME_SETCONTEXT:
case WM_IME_NOTIFY:
case WM_SYSCOMMAND:
case WM_WINDOWPOSCHANGING: