/****************************************************************************** * * File Name: hatmt.c * * - HangeulAutomata of IME for Chicago-H. * * Author: Beomseok Oh (BeomOh) * * Copyright (C) Microsoft Corp 1993-1994. All rights reserved. * ******************************************************************************/ #include "precomp.h" extern DWORD gdwSystemInfoFlags; BOOL HangeulAutomata(BYTE bCode, LPDWORD lpdwTransKey, LPCOMPOSITIONSTRING lpCompStr) { BYTE bKind; BOOL fOpen = FALSE; if (bCode > 0xE0) bKind = JongSung; else if (bCode > 0xC0) bKind = ChoSung; else if (bCode > 0xA0) bKind = MoEum; else if (bCode > 0x80) bKind = JaEum; else if (bCode == 0x80) // For Backspace handling. { if (fCurrentCompDel == FALSE) { // Simulate CHO state deletion - just clear current interim char. bState = CHO; mCho = 0; } switch (bState) { case JONG : if (mJong) { mJong = 0; if (!fComplete && uCurrentInputMethod == IDD_2BEOL) { Cho1 = Jong2Cho[Jong1]; bState = CHO; } break; } else if (fComplete) { bState = JUNG; break; } // fall through... case JUNG : if (mJung) { mJung = 0; break; } else if (fComplete) { bState = CHO; fComplete = FALSE; break; } // fall through... case CHO : if (mCho) { mCho = 0; break; } else { lpCompStr->dwCompStrLen = lpCompStr->dwCompAttrLen = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1) = 0; // Initialize all Automata Variables. bState = NUL; JohabChar.w = WansungChar.w = mCho = mJung = mJong = 0; fComplete = FALSE; if (lpdwTransKey) { // Send Empty Composition String Clear Message. lpdwTransKey += iTotalNumMsg*3 + 1; *lpdwTransKey++ = WM_IME_COMPOSITION; *lpdwTransKey++ = 0L; *lpdwTransKey++ = GCS_COMPSTR | GCS_COMPATTR | CS_INSERTCHAR | CS_NOMOVECARET; // Send Close Composition Window Message. *lpdwTransKey++ = WM_IME_ENDCOMPOSITION; *lpdwTransKey++ = 0L; *lpdwTransKey++ = 0L; iTotalNumMsg += 2; } return TRUE; } case NUL : if (lpdwTransKey) { // Put the Backspace message into return buffer. lpdwTransKey += iTotalNumMsg*3 + 1; *lpdwTransKey++ = WM_CHAR; *lpdwTransKey++ = (DWORD)VK_BACK; *lpdwTransKey++ = VKBACK_LPARAM; iTotalNumMsg++; } return FALSE; } MakeInterim(lpCompStr); // Put the interim character into return buffer. if (lpdwTransKey) { lpdwTransKey += iTotalNumMsg*3 + 1; *lpdwTransKey++ = WM_IME_COMPOSITION; *lpdwTransKey++ = (DWORD)WansungChar.w; *lpdwTransKey++ = GCS_COMPSTR | GCS_COMPATTR | CS_INSERTCHAR | CS_NOMOVECARET; iTotalNumMsg++; } return TRUE; } else bKind = Wrong; bCode &= 0x1F; // Mask out for Component code switch (bState) { case NUL : switch (bKind) { case JaEum : case ChoSung : Cho1 = bCode; bState = CHO; break; case MoEum : Cho1 = CFILL; Jung1 = bCode; bState = JUNG; break; case JongSung : Cho1 = CFILL; Jung1 = VFILL; Jong1 = bCode; bState = JONG; break; } MakeInterim(lpCompStr); fOpen = TRUE; break; case CHO : switch (bKind) { case JaEum : Jong1 = Cho2Jong[Cho1]; if (CheckMJong(Cho2Jong[bCode])) { Cho1 = CFILL; Jung1 = VFILL; Jong2 = Cho2Jong[bCode]; bState = JONG; } else { MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = bCode; bState = CHO; } break; case MoEum : Jung1 = bCode; bState = JUNG; fComplete = TRUE; break; case ChoSung : if (!mCho && CheckMCho(bCode)) { Cho2 = bCode; } else { MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = bCode; bState = CHO; } break; case JongSung : MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = CFILL; Jung1 = VFILL; Jong1 = bCode; bState = JONG; break; } if (!MakeInterim(lpCompStr))// Check whether can be WANSUNG code. { // For MoEum case only. bState = CHO; // Other case can NOT fall in here. fComplete = FALSE; MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = CFILL; Jung1 = bCode; bState = JUNG; MakeInterim(lpCompStr); } break; case JUNG : switch (bKind) { case JaEum : if (!fComplete) { MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = bCode; bState = CHO; MakeInterim(lpCompStr); } else { Jong1 = Cho2Jong[bCode]; bState = JONG; if (!MakeInterim(lpCompStr)) { bState = JUNG; MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = bCode; bState = CHO; MakeInterim(lpCompStr); } } break; case MoEum : if (!mJung && CheckMJung(bCode)) { Jung2 = bCode; if (!MakeInterim(lpCompStr)) { mJung = 0; MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = CFILL; Jung1 = bCode; bState = JUNG; MakeInterim(lpCompStr); } } else { MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = CFILL; Jung1 = bCode; bState = JUNG; MakeInterim(lpCompStr); } break; case ChoSung : MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = bCode; bState = CHO; MakeInterim(lpCompStr); break; case JongSung : if (!fComplete) { MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = CFILL; Jung1 = VFILL; Jong1 = bCode; bState = JONG; MakeInterim(lpCompStr); } else { Jong1 = bCode; bState = JONG; if (!MakeInterim(lpCompStr)) { bState = JUNG; MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = CFILL; Jung1 = VFILL; Jong1 = bCode; bState = JONG; MakeInterim(lpCompStr); } } break; } break; case JONG : switch (bKind) { case JaEum : if (!mJong && CheckMJong(Cho2Jong[bCode])) { Jong2 = Cho2Jong[bCode]; if (!MakeInterim(lpCompStr)) { mJong = 0; MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = bCode; bState = CHO; MakeInterim(lpCompStr); } } else { MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = bCode; bState = CHO; MakeInterim(lpCompStr); } break; case MoEum : if (uCurrentInputMethod == IDD_2BEOL) { JOHAB tmpJohab; WORD tmpWansung; BOOL tmpfComplete; tmpJohab.h.flag = 1; tmpJohab.h.cho = (mJong)? Jong2Cho[Jong2]: Jong2Cho[Jong1]; tmpJohab.h.jung = bCode; tmpJohab.h.jong = CFILL; tmpfComplete = fComplete; fComplete = TRUE; #ifdef JOHAB_IME tmpWansung = tmpJohab.w; #else tmpWansung = Johab2Wansung(tmpJohab.w); #endif fComplete = tmpfComplete; if (!tmpWansung) { MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = CFILL; Jung1 = bCode; bState = JUNG; } else { MakeFinal(TRUE, lpdwTransKey, FALSE, lpCompStr); Cho1 = (mJong)? Jong2Cho[Jong2]: Jong2Cho[Jong1]; Jung1 = bCode; fComplete = TRUE; bState = JUNG; mJong = 0; } } else { MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = CFILL; Jung1 = bCode; bState = JUNG; } MakeInterim(lpCompStr); break; case ChoSung : MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = bCode; bState = CHO; MakeInterim(lpCompStr); break; case JongSung : if (!mJong && CheckMJong(bCode)) { Jong2 = bCode; if (!MakeInterim(lpCompStr)) { mJong = 0; MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = CFILL; Jung1 = VFILL; Jong1 = bCode; bState = JONG; MakeInterim(lpCompStr); } } else { MakeFinal(FALSE, lpdwTransKey, FALSE, lpCompStr); Cho1 = CFILL; Jung1 = VFILL; Jong1 = bCode; bState = JONG; MakeInterim(lpCompStr); } break; } break; } if (lpdwTransKey) { lpdwTransKey += iTotalNumMsg*3 + 1; if (fOpen) { // Send Open Composition Window Message. *lpdwTransKey++ = WM_IME_STARTCOMPOSITION; *lpdwTransKey++ = 0L; *lpdwTransKey++ = 0L; iTotalNumMsg++; } // Put the interim character into return buffer. *lpdwTransKey++ = WM_IME_COMPOSITION; *lpdwTransKey++ = (DWORD)WansungChar.w; *lpdwTransKey++ = GCS_COMPSTR | GCS_COMPATTR | CS_INSERTCHAR | CS_NOMOVECARET; iTotalNumMsg++; } return FALSE; } BOOL MakeInterim(LPCOMPOSITIONSTRING lpCompStr) { JohabChar.h.flag = 1; JohabChar.h.cho = (mCho)? mCho: Cho1; switch (bState) { case CHO : JohabChar.h.jung = VFILL; JohabChar.h.jong = CFILL; break; case JUNG : JohabChar.h.jung = (mJung)? mJung: Jung1; JohabChar.h.jong = CFILL; break; case JONG : JohabChar.h.jung = (mJung)? mJung: Jung1; JohabChar.h.jong = (mJong)? mJong: Jong1; break; } #ifdef JOHAB_IME WansungChar.w = JohabChar.w; #else WansungChar.w = Johab2Wansung(JohabChar.w); #endif if (WansungChar.w) { // Update IME Context. *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset) = WansungChar.e.high; *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1) = WansungChar.e.low; lpCompStr->dwCompStrLen = 2; // AttrLen should be 2. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset + 1) = 0; lpCompStr->dwCompAttrLen = 2; return TRUE; } else return FALSE; } void MakeFinal(BOOL bCount, LPDWORD lpdwTransKey, BOOL fClose, LPCOMPOSITIONSTRING lpCompStr) { if (bCount == TRUE) if (mJong) if (fComplete) { mJong = 0; MakeInterim(lpCompStr); mJong = 1; } else { Cho1 = Jong2Cho[Jong1]; bState = CHO; MakeInterim(lpCompStr); } else { bState = JUNG; MakeInterim(lpCompStr); } else { if (!WansungChar.w) MakeInterim(lpCompStr); mJong = 0; } if (lpdwTransKey) { lpdwTransKey += iTotalNumMsg*3 + 1; if (fClose) { // Send Close Composition Window Message. *lpdwTransKey++ = WM_IME_ENDCOMPOSITION; *lpdwTransKey++ = 0L; *lpdwTransKey++ = 0L; iTotalNumMsg++; } // Put the finalized character into return buffer. *lpdwTransKey++ = WM_IME_COMPOSITION; *lpdwTransKey++ = (DWORD)WansungChar.w; *lpdwTransKey++ = GCS_RESULTSTR; iTotalNumMsg++; } // Update IME Context. lpCompStr->dwCompStrLen = lpCompStr->dwCompAttrLen = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset + 1) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1) = 0; *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset) = WansungChar.e.high; *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + 1) = WansungChar.e.low; lpCompStr->dwResultStrLen = 2; // add a null terminator *(LPTSTR)((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + sizeof(WCHAR)) = '\0'; // Initialize all Automata Variables. bState = NUL; JohabChar.w = WansungChar.w = mCho = mJung = 0; fComplete = FALSE; } void MakeFinalMsgBuf(HIMC hIMC, WPARAM VKey) { LPINPUTCONTEXT lpIMC; LPCOMPOSITIONSTRING lpCompStr; LPDWORD lpdwMsgBuf; lpIMC = ImmLockIMC(hIMC); if (lpIMC == NULL) return; lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr); if (lpCompStr == NULL) { ImmUnlockIMC(hIMC); return; } if (!WansungChar.w) MakeInterim(lpCompStr); mJong = 0; // Put the finalized character into return buffer. lpIMC->dwNumMsgBuf = (VKey)? 3: 2; lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, sizeof(DWORD)*3 * lpIMC->dwNumMsgBuf); lpdwMsgBuf = (LPDWORD)ImmLockIMCC(lpIMC->hMsgBuf); *lpdwMsgBuf++ = WM_IME_ENDCOMPOSITION; *lpdwMsgBuf++ = 0L; *lpdwMsgBuf++ = 0L; *lpdwMsgBuf++ = WM_IME_COMPOSITION; *lpdwMsgBuf++ = (DWORD)WansungChar.w; *lpdwMsgBuf++ = GCS_RESULTSTR; if (VKey) { *lpdwMsgBuf++ = WM_IME_KEYDOWN; *lpdwMsgBuf++ = VKey; *lpdwMsgBuf++ = 1L; } ImmUnlockIMCC(lpIMC->hMsgBuf); // Update IME Context. lpCompStr->dwCompStrLen = lpCompStr->dwCompAttrLen = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset + 1) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1) = 0; *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset) = WansungChar.e.high; *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + 1) = WansungChar.e.low; lpCompStr->dwResultStrLen = 2; // add a null terminator *(LPTSTR)((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + sizeof(WCHAR)) = '\0'; ImmUnlockIMCC(lpIMC->hCompStr); ImmUnlockIMC(hIMC); ImmGenerateMessage(hIMC); // Initialize all Automata Variables. bState = NUL; JohabChar.w = WansungChar.w = mCho = mJung = 0; fComplete = FALSE; } void Banja2Junja(BYTE bChar, LPDWORD lpdwTransKey, LPCOMPOSITIONSTRING lpCompStr) { if (bChar == ' ') #ifdef JOHAB_IME WansungChar.w = 0xD931; #else WansungChar.w = 0xA1A1; #endif else if (bChar == '~') #ifdef JOHAB_IME WansungChar.w = 0xD9A6; #else WansungChar.w = 0xA2A6; #endif else { #ifdef JOHAB_IME WansungChar.e.high = 0xDA; WansungChar.e.low = bChar + (BYTE)((bChar <= 'n')? 0x10: 0x22); #else WansungChar.e.high = 0xA3; WansungChar.e.low = bChar + (BYTE)0x80; #endif } // Update IME Context. lpCompStr->dwCompStrLen = lpCompStr->dwCompAttrLen = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset + 1) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset) = 0; *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1) = 0; if (lpCompStr->dwResultStrLen) { *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + 2) = WansungChar.e.high; *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + 3) = WansungChar.e.low; // add a null terminator *(LPTSTR)((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + 2 + sizeof(WCHAR)) = '\0'; } else { *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset) = WansungChar.e.high; *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + 1) = WansungChar.e.low; // add a null terminator *(LPTSTR)((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + sizeof(WCHAR)) = '\0'; if (lpdwTransKey) { // Put the finalized character into return buffer. lpdwTransKey += iTotalNumMsg*3 + 1; *lpdwTransKey++ = WM_IME_COMPOSITION; *lpdwTransKey++ = (DWORD)WansungChar.w; *lpdwTransKey++ = GCS_RESULTSTR; iTotalNumMsg++; } } lpCompStr->dwResultStrLen += 2; } BOOL CheckMCho(BYTE bCode) { int i; if (Cho1 != bCode) return FALSE; for (i = 0; i < 5; i++) if (rgbMChoTbl[i][0] == Cho1 && rgbMChoTbl[i][1] == bCode) { mCho = rgbMChoTbl[i][2]; return TRUE; } return FALSE; } BOOL CheckMJung(BYTE bCode) { int i; for (i = 0; i < 7; i++) if (rgbMJungTbl[i][0] == Jung1 && rgbMJungTbl[i][1] == bCode) { mJung = rgbMJungTbl[i][2]; return TRUE; } return FALSE; } BOOL CheckMJong(BYTE bCode) { int i; if (uCurrentInputMethod == IDD_2BEOL && Jong1 == bCode) return FALSE; for (i = 0; i < 13; i++) if (rgbMJongTbl[i][0] == Jong1 && rgbMJongTbl[i][1] == bCode) { mJong = rgbMJongTbl[i][2]; return TRUE; } return FALSE; } #ifndef JOHAB_IME #ifdef XWANSUNG_IME BOOL IsPossibleToUseUHC() { /* * No UHC support for 16-bits app. */ return (gdwSystemInfoFlags & IME_SYSINFO_WOW16) == 0; } BOOL UseXWansung(void) { #ifdef LATER DWORD idProcess; idProcess = GetCurrentProcessId(); if ((fCurrentUseXW && (!(GetProcessDword(idProcess, GPD_FLAGS) & GPF_WIN16_PROCESS) || (GetProcessDword(idProcess, GPD_EXP_WINVER) >= 0x0400))) || (IMECOMPAT_USEXWANSUNG & ImmGetAppIMECompatFlags(0L))) #else if ( fCurrentUseXW && IsPossibleToUseUHC()) #endif return TRUE; else return FALSE; } // // iXWType array is 8x3 matrix of Lead for Row, Tail for Column // static BYTE iXWType[8][3] = { XWT_EXTENDED, XWT_EXTENDED, XWT_EXTENDED, // Lead = 0x81-0xA0 XWT_EXTENDED, XWT_EXTENDED, XWT_JUNJA, // Lead = 0xA1-0xAC XWT_EXTENDED, XWT_EXTENDED, XWT_INVALID, // Lead = 0xAD-0xAF XWT_EXTENDED, XWT_EXTENDED, XWT_WANSUNG, // Lead = 0xB0-0xC5 XWT_EXTENDED, XWT_INVALID, XWT_WANSUNG, // Lead = 0xC6 XWT_INVALID, XWT_INVALID, XWT_WANSUNG, // Lead = 0xC7-0xC8 XWT_INVALID, XWT_INVALID, XWT_UDC, // Lead = 0xC9, 0xFE XWT_INVALID, XWT_INVALID, XWT_HANJA // Lead = 0xCA-0xFD }; int GetXWType( WORD wXW ) { BYTE bL = ( wXW >> 8 ) & 0xFF; BYTE bT = wXW & 0xFF; int iLType = -1, iTType = -1; if ( ( bT >= 0x41 ) && ( bT <= 0xFE ) ) { if ( bT <= 0x52 ) iTType = 0; // Tail Range 0x41-0x52 else { if ( bT >= 0xA1 ) iTType = 2; // Tail Range 0xA1-0xFE else if ( ( bT <= 0x5A ) || ( bT >= 0x81 ) || ( ( bT >= 0x61 ) && ( bT <= 0x7A ) ) ) iTType = 1; // Tail Range 0x53-0x5A, 0x61-0x7A, 0x81-0xA0 } } if ( iTType < 0 ) return( -1 ); if ( ( bL >= 0x81 ) && ( bL <= 0xFE ) ) { if ( bL < 0xB0 ) { if ( bL <= 0xA0 ) iLType = 0; // Lead Range 0x81-0xA0 else if ( bL <= 0xAC ) iLType = 1; // Lead Range 0xA1-0xAC else iLType = 2; // Lead Range 0xAD-0xAF } else { if ( bL <= 0xC8 ) { if ( bL < 0xC6 ) iLType = 3; // Lead Range 0xB0-0xC5 else if ( bL == 0xC6 ) iLType = 4; // Lead Range 0xC6 else iLType = 5; // Lead Range 0xC7-0xC8 } else { if ( ( bL == 0xC9 ) || ( bL == 0xFE ) ) iLType = 6; // Lead Range 0xC9, 0xFE else iLType = 7; // Lead Range 0xCA-0xFD } } } return( ( iLType < 0 ) ? -1 : iXWType[iLType][iTType] ); } WORD ConvXW2J( WORD wXW ) { const WORD *pTF; int iTO; BYTE bL, bT; switch ( GetXWType( wXW ) ) { case XWT_EXTENDED : bL = ( ( wXW >> 8 ) & 0xFF ) - 0x81; bT = wXW & 0xFF; if ( ( bT -= 0x41 ) > 0x19 ) if ( ( bT -= 6 ) > 0x33 ) bT -= 6; iTO = bT + iTailOffX[bL]; pTF = iTailFirstX + ( bL = iLeadMapX[bL] ); break; case XWT_WANSUNG : bL = ( ( wXW >> 8 ) & 0xFF ) - 0xB0; iTO = ( wXW & 0xFF ) - 0xA1 + iTailOff[bL]; pTF = iTailFirst + ( bL = iLeadMap[bL] ); break; default: return( 0 ); } iTO += *pTF++; while ( iTO >= *pTF++ ) bL++; return( (WORD) ( bL + 0x88 ) * 256 + bTailTable[iTO] ); } static int BinarySearch( WORD wJ, const WORD iTF[] ) { int iL; BYTE bT; int iStart, iEnd, iMiddle; iL = ( ( wJ >> 8 ) & 0xFF ) - 0x88; bT = wJ & 0xFF; iStart = iTF[iL]; iEnd = iTF[iL+1] - 1; while ( iStart <= iEnd ) { iMiddle = ( iStart + iEnd ) / 2; if ( bT == bTailTable[iMiddle] ) return( iMiddle ); else if ( bT < bTailTable[iMiddle] ) iEnd = iMiddle - 1; else iStart = iMiddle + 1; } return( -1 ); } WORD ConvJ2XW( WORD wJ ) { int iIndex; BYTE bL, bT; iIndex = BinarySearch( wJ, iTailFirst ); if ( iIndex < 0 ) { if (!UseXWansung()) return 0; iIndex = BinarySearch( wJ, iTailFirstX ) - N_WANSUNG; if ( iIndex < 5696 ) { bL = iIndex / 178 + 0x81; bT = iIndex % 178; } else { iIndex -= 5696; bL = iIndex / 84 + 0xA1; bT = iIndex % 84; } if ( ( bT += 0x41 ) > 0x5A ) if ( ( bT += 6 ) > 0x7A ) bT += 6; return( (WORD) bL * 256 + bT ); } else return( ( iIndex / 94 + 0xB0 ) * 256 + ( iIndex % 94 ) + 0xA1 ); } #endif WORD Johab2Wansung(WORD wJohab) { #ifndef XWANSUNG_IME int iHead = 0, iTail = 2349, iMid; #endif BYTE bCount, bMaxCount; WORD wWansung; PWORD pwKSCompCode; if (fComplete) { #ifdef XWANSUNG_IME wWansung = ConvJ2XW(wJohab); #else wWansung = 0; while (iHead <= iTail && !wWansung) { iMid = (iHead + iTail) / 2; if (wKSCharCode[iMid] > wJohab) iTail = iMid - 1; else if (wKSCharCode[iMid] < wJohab) iHead = iMid + 1; else wWansung = ((iMid / 94 + 0xB0) << 8) | (iMid % 94 + 0xA1); } #endif } else { if (bState == JONG) { // For 3 Beolsik only. bMaxCount = 30; pwKSCompCode = (PWORD)wKSCompCode2; } else { bMaxCount = 51; pwKSCompCode = (PWORD)wKSCompCode; } for (bCount = 0; pwKSCompCode[bCount] != wJohab && bCount < bMaxCount; bCount++) ; wWansung = (bCount == bMaxCount)? 0: bCount + 0xA4A1; } return (wWansung); } WORD Wansung2Johab(WORD wWansung) { WORD wJohab; #ifndef XWANSUNG_IME UINT uLoc; #endif if (wWansung >= (WORD)0xA4A1 && wWansung <= (WORD)0xA4D3) wJohab = wKSCompCode[wWansung - 0xA4A1]; #ifdef XWANSUNG_IME else wJohab = ConvXW2J(wWansung); #else else if (wWansung >= (WORD)0xB0A1 && wWansung <= (WORD)0xC8FE && (wWansung & 0x00FF) != (BYTE)0xFF) { uLoc = ((wWansung >> 8) - 176) * 94; uLoc += (wWansung & 0x00FF) - 161; wJohab = wKSCharCode[uLoc]; } else wJohab = 0; #endif return (wJohab); } #endif void Code2Automata(void) { int i; #ifdef JOHAB_IME JohabChar.w = WansungChar.w; #else JohabChar.w = Wansung2Johab(WansungChar.w); #endif // Initialize all Automata Variables. bState = NUL; Cho1 = Cho2 = Jung1 = Jung2 = Jong1 = Jong2 = 0; mCho = mJung = mJong = 0; fComplete = FALSE; if (JohabChar.w) { if (JohabChar.h.cho != CFILL) { if (uCurrentInputMethod == IDD_2BEOL) { Cho1 = (BYTE)JohabChar.h.cho; Cho2 = mCho = 0; } else { for (i = 0; i < 5; i++) if (rgbMChoTbl[i][2] == JohabChar.h.cho) { Cho1 = rgbMChoTbl[i][0]; Cho2 = rgbMChoTbl[i][1]; mCho = rgbMChoTbl[i][2]; break; } if (i == 5) { Cho1 = (BYTE)JohabChar.h.cho; Cho2 = mCho = 0; } } fComplete = FALSE; bState = CHO; } else { Cho1 = CFILL; Cho2 = mCho = 0; } if (JohabChar.h.jung != VFILL) { for (i = 0; i < 7; i++) if (rgbMJungTbl[i][2] == JohabChar.h.jung) { Jung1 = rgbMJungTbl[i][0]; Jung2 = rgbMJungTbl[i][1]; mJung = rgbMJungTbl[i][2]; break; } if (i == 7) { Jung1 = (BYTE)JohabChar.h.jung; Jung2 = mJung = 0; } if (bState == CHO) fComplete = TRUE; bState = JUNG; } else { Jung1 = VFILL; Jung2 = mJung = 0; } if (JohabChar.h.jong != CFILL) { for (i = 0; i < 13; i++) if (rgbMJongTbl[i][2] == JohabChar.h.jong) { if (uCurrentInputMethod == IDD_2BEOL && rgbMJongTbl[i][0] == rgbMJongTbl[i][1]) { Jong1 = (BYTE)JohabChar.h.jong; Jong2 = mJong = 0; } else { Jong1 = rgbMJongTbl[i][0]; Jong2 = rgbMJongTbl[i][1]; mJong = rgbMJongTbl[i][2]; } break; } if (i == 13) { Jong1 = (BYTE)JohabChar.h.jong; Jong2 = mJong = 0; } if (bState != JUNG) fComplete = FALSE; bState = JONG; } else { Jong1 = CFILL; Jong2 = mJong = 0; } } } void UpdateOpenCloseState(HIMC hIMC) { LPINPUTCONTEXT lpIMC; lpIMC = ImmLockIMC(hIMC); if (lpIMC != NULL) { if ((lpIMC->fdwConversion & IME_CMODE_HANGEUL) || (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE)) ImmSetOpenStatus(hIMC, TRUE); else ImmSetOpenStatus(hIMC, FALSE); ImmUnlockIMC(hIMC); } } int SearchHanjaIndex(WORD wHChar) { int iHead = 0, iTail = 490, iMid; #ifdef JOHAB_IME while (iHead < 18) if (wHanjaMap[iHead++] == wHChar) return (iHead - 1); #endif while (iHead <= iTail) { iMid = (iHead + iTail) / 2; if (wHanjaMap[iMid] > wHChar) iTail = iMid - 1; else if (wHanjaMap[iMid] < wHChar) iHead = iMid + 1; else return (iMid); } return (-1); }