Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

915 lines
31 KiB

/*++
Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
Module Name:
compose.c
++*/
#include <windows.h>
#include <immdev.h>
#include <imedefs.h>
void PASCAL XGBAddCodeIntoCand(LPCANDIDATELIST, WORD);
#if defined(COMBO_IME)
void PASCAL UnicodeAddCodeIntoCand(LPCANDIDATELIST, WORD);
#endif
#if defined(COMBO_IME)
/**********************************************************************/
/* UnicodeEngine() */
/* Description: */
/* Conv GBcode */
/**********************************************************************/
WORD PASCAL UnicodeEngine(LPPRIVCONTEXT lpImcP)
{
if (lpImcP->bSeq[3] || lpImcP->bSeq[2] == TEXT('?') || lpImcP->bSeq[2] == TEXT(' ')) {
if (lpImcP->bSeq[2] == TEXT('?') || lpImcP->bSeq[2] == TEXT(' ')){
lpImcP->bSeq[2] = TEXT('0');
lpImcP->bSeq[3] = TEXT('0');
}
return (AsciiToGB(lpImcP));
} else {
return (0);
}
}
#endif //COMBO_IME
/**********************************************************************/
/* XGBEngine() */
/* Description: */
/* Conv GBcode */
/**********************************************************************/
WORD PASCAL XGBEngine(LPPRIVCONTEXT lpImcP)
{
WORD wCode;
if (lpImcP->bSeq[3] ||(lpImcP->bSeq[2] == TEXT('?'))) {
if (lpImcP->bSeq[2] == TEXT('?')){ //add 626
lpImcP->bSeq[2] = TEXT('4');
lpImcP->bSeq[3] = TEXT('0');
}
wCode = AsciiToGB(lpImcP);
return wCode;
} else {
return ((WORD)NULL);
}
}
/**********************************************************************/
/* XGBSpcEng() */
/* Description: */
/* Conv GBcode for Space */
/**********************************************************************/
WORD PASCAL XGBSpcEng(LPPRIVCONTEXT lpImcP)
{
WORD wCode;
lpImcP->bSeq[2] = TEXT('4');
lpImcP->bSeq[3] = TEXT('0');
wCode = AsciiToGB(lpImcP);
return wCode;
}
/**********************************************************************/
/* GBEngine() */
/* Description: */
/* Conv GBcode */
/**********************************************************************/
WORD PASCAL GBEngine(LPPRIVCONTEXT lpImcP)
{
WORD wCode;
if (lpImcP->bSeq[3] ||(lpImcP->bSeq[2] == TEXT('?'))) {
if (lpImcP->bSeq[0] >=TEXT('0') && lpImcP->bSeq[0] <=TEXT('9')) { //Area mode
if (lpImcP->bSeq[2] == TEXT('?')){
lpImcP->bSeq[2] = TEXT('0');
lpImcP->bSeq[3] = TEXT('1');
}
return (AsciiToArea(lpImcP));
}
else if (lpImcP->bSeq[0] >=TEXT('a') && lpImcP->bSeq[0] <=TEXT('f')) { //GB mode
if (lpImcP->bSeq[2] == TEXT('?')){
lpImcP->bSeq[2] = TEXT('a');
lpImcP->bSeq[3] = TEXT('1');
}
wCode = AsciiToGB(lpImcP);
return wCode;
} else {
return ((WORD)NULL);
}
} else
return ((WORD)NULL);
}
/**********************************************************************/
/* GBSpcEng() */
/* Description: */
/* Conv GBcode for Space */
/**********************************************************************/
WORD PASCAL GBSpcEng(LPPRIVCONTEXT lpImcP)
{
if (lpImcP->bSeq[0] >=TEXT('0') && lpImcP->bSeq[0] <=TEXT('9')) { //Area mode
lpImcP->bSeq[2] = TEXT('0');
lpImcP->bSeq[3] = TEXT('1');
return (AsciiToArea(lpImcP));
} else if (lpImcP->bSeq[0] >=TEXT('a') && lpImcP->bSeq[0] <=TEXT('f')) { //GB mode
lpImcP->bSeq[2] = TEXT('a');
lpImcP->bSeq[3] = TEXT('1');
return (AsciiToGB(lpImcP));
} else {
return ((WORD)NULL);
}
}
/**********************************************************************/
/* AsciiToGB */
/* Description: */
/**********************************************************************/
WORD PASCAL AsciiToGB(LPPRIVCONTEXT lpImcP)
{
WORD GBCode;
GBCode = (CharToHex(lpImcP->bSeq[2]) << 4) + CharToHex(lpImcP->bSeq[3]);
GBCode = GBCode * 256;
GBCode = (CharToHex(lpImcP->bSeq[0]) << 4) + CharToHex(lpImcP->bSeq[1]) + GBCode;
return (GBCode);
}
/**********************************************************************/
/* AsciiToArea */
/* Description: */
/**********************************************************************/
WORD PASCAL AsciiToArea(LPPRIVCONTEXT lpImcP)
{
WORD AreaCode;
AreaCode = (CharToHex(lpImcP->bSeq[2]) * 10) + CharToHex(lpImcP->bSeq[3]) + 0xa0;
AreaCode = AreaCode * 256;
AreaCode = (CharToHex(lpImcP->bSeq[0]) * 10) + CharToHex(lpImcP->bSeq[1]) + AreaCode + 0xa0;
return (AreaCode);
}
WORD PASCAL CharToHex(
TCHAR cChar)
{
if (cChar >= TEXT('0') && cChar <= TEXT('9'))
return((WORD)(cChar - TEXT('0')));
else if (cChar >= TEXT('a') && cChar <= TEXT('f'))
return((WORD)(cChar-TEXT('a')+ 0x0a));
else
return ((WORD)NULL);
}
/**********************************************************************/
/* Engine() */
/* Description: */
/* search MB and fill lpCompStr and lpCandList */
/**********************************************************************/
int PASCAL Engine(
LPCOMPOSITIONSTRING lpCompStr,
LPCANDIDATELIST lpCandList,
LPPRIVCONTEXT lpImcP,
LPINPUTCONTEXT lpIMC,
WORD wCharCode)
{
if(lpCompStr->dwCursorPos < 4
&& (lpImcP->bSeq[2] != TEXT('?'))
&& (wCharCode != TEXT(' '))) {
return (ENGINE_COMP);
} else if((lpCompStr->dwCursorPos==4)
||(lpImcP->bSeq[2] == TEXT('?'))
||((wCharCode == TEXT(' ')) && (lpCompStr->dwCursorPos == 2))) {
if (!lpCompStr) {
MessageBeep((UINT)-1);
return -1;
}
if (!lpImcP) {
MessageBeep((UINT)-1);
return -1;
}
#if defined(COMBO_IME)
if(sImeL.dwRegImeIndex == INDEX_GB)
{
// GB
DWORD i;
WORD wCode;
TCHAR ResaultStr[3];
if((lpImcP->bSeq[2] == TEXT('?'))) {
wCode = GBEngine(lpImcP);
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < IME_MAXCAND; i++, wCode++) {
AddCodeIntoCand(lpCandList, wCode);
}
return (ENGINE_COMP);
} else if(wCharCode == TEXT(' ')) {
wCode = GBSpcEng(lpImcP);
lpImcP->bSeq[2] = 0;
lpImcP->bSeq[3] = 0;
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < IME_MAXCAND; i++, wCode++) {
AddCodeIntoCand(lpCandList, wCode);
}
return (ENGINE_COMP);
} else {
InitCompStr(lpCompStr);
// the result string = the selected candidate;
wCode = GBEngine(lpImcP);
#ifdef UNICODE
MultiByteToWideChar(NATIVE_ANSI_CP, 0, (LPCSTR)&wCode, 2, ResaultStr, sizeof(ResaultStr)/sizeof(TCHAR));
ResaultStr[1] = TEXT('\0');
#else
ResaultStr[0] = LOBYTE(wCode);
ResaultStr[1] = HIBYTE(wCode);
ResaultStr[2] = 0x00;
#endif
lstrcpy((LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset),ResaultStr);
// calculate result string length
lpCompStr->dwResultStrLen = lstrlen(ResaultStr);
return (ENGINE_RESAULT);
}
}else if(sImeL.dwRegImeIndex == INDEX_GBK)
{
// XGB
DWORD i;
WORD wCode;
TCHAR ResaultStr[3];
if((lpImcP->bSeq[2] == TEXT('?'))) {
wCode = XGBEngine(lpImcP);
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < (0x7e-0x40+1); i++, wCode++) {
XGBAddCodeIntoCand(lpCandList, wCode);
}
wCode ++;
for (i = 0; i < (0xfe-0x80+1); i++, wCode++) {
XGBAddCodeIntoCand(lpCandList, wCode);
}
return (ENGINE_COMP);
} else if(wCharCode == TEXT(' ')) {
wCode = XGBSpcEng(lpImcP);
lpImcP->bSeq[2] = 0;
lpImcP->bSeq[3] = 0;
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < (0x7e-0x40+1); i++, wCode++) {
XGBAddCodeIntoCand(lpCandList, wCode);
}
wCode ++;
for (i = 0; i < (0xfe-0x80+1); i++, wCode++) {
XGBAddCodeIntoCand(lpCandList, wCode);
}
return (ENGINE_COMP);
} else {
InitCompStr(lpCompStr);
// the result string = the selected candidate;
wCode = XGBEngine(lpImcP);
#ifdef UNICODE
MultiByteToWideChar(NATIVE_ANSI_CP, 0, (LPCSTR)&wCode, 2, ResaultStr, sizeof(ResaultStr)/sizeof(TCHAR));
ResaultStr[1] = TEXT('\0');
#else
ResaultStr[0] = LOBYTE(wCode);
ResaultStr[1] = HIBYTE(wCode);
ResaultStr[2] = 0x00;
#endif
lstrcpy((LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset),ResaultStr);
// calculate result string length
lpCompStr->dwResultStrLen = lstrlen(ResaultStr);
return (ENGINE_RESAULT);
}
}else if(sImeL.dwRegImeIndex == INDEX_UNICODE)
{
// UNICODE
DWORD i;
WORD wCode, xCode;
TCHAR ResaultStr[3];
memset(ResaultStr, 0, sizeof(ResaultStr));
if((lpImcP->bSeq[2] == TEXT('?') || wCharCode == TEXT(' '))) {
lpImcP->bSeq[2] = TEXT('0');
lpImcP->bSeq[3] = TEXT('0');
lpImcP->bSeq[4] = TEXT('\0');
wCode = UnicodeEngine(lpImcP);
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
lpCandList->dwCount = 0;
for (i = 0; i < IME_UNICODE_MAXCAND; i++, wCode++) {
#ifdef UNICODE
// add this string into candidate list
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount]) = wCode;
#else
WideCharToMultiByte(NATIVE_ANSI_CP, NULL, &wCode, 1, &xCode, 2, NULL, NULL);
// add this string into candidate list
*(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount]) = xCode;
#endif
// null terminator
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + sizeof(WORD)) = TEXT('\0');
lpCandList->dwOffset[lpCandList->dwCount + 1] =
lpCandList->dwOffset[lpCandList->dwCount] +
sizeof(WORD) + sizeof(TCHAR);
lpCandList->dwCount++;
}
return (ENGINE_COMP);
} else {
InitCompStr(lpCompStr);
// the result string = the selected candidate;
wCode = UnicodeEngine(lpImcP);
{
WCHAR UniStr[2];
UniStr[0] = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
UniStr[1] = 0;
lstrcpy((LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset),UniStr);
// calculate result string length
lpCompStr->dwResultStrLen = lstrlen(UniStr);
}
return (ENGINE_RESAULT);
}
}
#else //COMBO_IME
#ifdef GB
{
// GB
DWORD i;
WORD wCode;
TCHAR ResaultStr[3];
if((lpImcP->bSeq[2] == TEXT('?'))) {
wCode = GBEngine(lpImcP);
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < IME_MAXCAND; i++, wCode++) {
AddCodeIntoCand(lpCandList, wCode);
}
return (ENGINE_COMP);
} else if(wCharCode == TEXT(' ')) {
wCode = GBSpcEng(lpImcP);
lpImcP->bSeq[2] = 0;
lpImcP->bSeq[3] = 0;
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < IME_MAXCAND; i++, wCode++) {
AddCodeIntoCand(lpCandList, wCode);
}
return (ENGINE_COMP);
} else {
InitCompStr(lpCompStr);
// the result string = the selected candidate;
wCode = GBEngine(lpImcP);
#ifdef UNICODE
// change CP_ACP to 936, so that it can work under Multilingul Env.
MultiByteToWideChar(NATIVE_ANSI_CP, NULL, &wCode, 2, ResaultStr, sizeof(ResaultStr)/sizeof(TCHAR));
ResaultStr[1] = TEXT('\0');
#else
ResaultStr[0] = LOBYTE(wCode);
ResaultStr[1] = HIBYTE(wCode);
ResaultStr[2] = 0x00;
#endif
lstrcpy((LPTSTR)lpCompStr + lpCompStr->dwResultStrOffset,ResaultStr);
// calculate result string length
lpCompStr->dwResultStrLen = lstrlen(ResaultStr);
return (ENGINE_RESAULT);
}
}
#else
{
// XGB
DWORD i;
WORD wCode;
TCHAR ResaultStr[3];
if((lpImcP->bSeq[2] == TEXT('?'))) {
wCode = XGBEngine(lpImcP);
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < (0x7e-0x40+1); i++, wCode++) {
XGBAddCodeIntoCand(lpCandList, wCode);
}
wCode ++;
for (i = 0; i < (0xfe-0x80+1); i++, wCode++) {
XGBAddCodeIntoCand(lpCandList, wCode);
}
return (ENGINE_COMP);
} else if(wCharCode == TEXT(' ')) {
wCode = XGBSpcEng(lpImcP);
lpImcP->bSeq[2] = 0;
lpImcP->bSeq[3] = 0;
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
for (i = 0; i < (0x7e-0x40+1); i++, wCode++) {
XGBAddCodeIntoCand(lpCandList, wCode);
}
wCode ++;
for (i = 0; i < (0xfe-0x80+1); i++, wCode++) {
XGBAddCodeIntoCand(lpCandList, wCode);
}
return (ENGINE_COMP);
} else {
InitCompStr(lpCompStr);
// the result string = the selected candidate;
wCode = XGBEngine(lpImcP);
#ifdef UNICODE
// change CP_ACP to 936, so that it can work under Multilingul Env.
MultiByteToWideChar(NATIVE_ANSI_CP, NULL, &wCode, 2, ResaultStr, sizeof(ResaultStr)/sizeof(TCHAR));
ResaultStr[1] = TEXT('\0');
#else
ResaultStr[0] = LOBYTE(wCode);
ResaultStr[1] = HIBYTE(wCode);
ResaultStr[2] = 0x00;
#endif
lstrcpy((LPTSTR)lpCompStr + lpCompStr->dwResultStrOffset,ResaultStr);
// calculate result string length
lpCompStr->dwResultStrLen = lstrlen(ResaultStr);
return (ENGINE_RESAULT);
}
}
#endif //GB
#endif //COMBO_IME
}
MessageBeep((UINT)-1);
return (ENGINE_COMP);
}
/**********************************************************************/
/* AddCodeIntoCand() */
/**********************************************************************/
void PASCAL AddCodeIntoCand(
LPCANDIDATELIST lpCandList,
WORD wCode)
{
WORD wInCode;
if (lpCandList->dwCount >= IME_MAXCAND) {
return;
}
wInCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
#ifdef UNICODE
{
TCHAR wUnicode;
// change CP_ACP to 936, so that it can work under Multilingul Env.
MultiByteToWideChar(NATIVE_ANSI_CP, 0, (LPCSTR) &wInCode, 2, &wUnicode, 1);
*(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount]) = wUnicode;
}
#else
// add GB string into candidate list
*(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount]) = wInCode;
#endif
// null terminator
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + sizeof(WORD)) = TEXT('\0');
lpCandList->dwOffset[lpCandList->dwCount + 1] =
lpCandList->dwOffset[lpCandList->dwCount] +
sizeof(WORD) + sizeof(TCHAR);
lpCandList->dwCount++;
return;
}
#if defined(COMBO_IME)
/**********************************************************************/
/* UnicodeAddCodeIntoCand() */
/**********************************************************************/
void PASCAL UnicodeAddCodeIntoCand(
LPCANDIDATELIST lpCandList,
WORD wCode)
{
if (lpCandList->dwCount >= IME_UNICODE_MAXCAND) {
return;
}
// add this string into candidate list
*(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount]) = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
// null terminator
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + sizeof(WORD)) = TEXT('\0');
lpCandList->dwOffset[lpCandList->dwCount + 1] =
lpCandList->dwOffset[lpCandList->dwCount] +
sizeof(WORD) + sizeof(TCHAR);
lpCandList->dwCount++;
return;
}
#endif //COMBO_IME
/**********************************************************************/
/* XGBAddCodeIntoCand() */
/**********************************************************************/
void PASCAL XGBAddCodeIntoCand(
LPCANDIDATELIST lpCandList,
WORD wCode)
{
WORD wInCode;
if (lpCandList->dwCount >= IME_XGB_MAXCAND) {
return;
}
wInCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
#ifdef UNICODE
{
TCHAR wUnicode;
// change CP_ACP to 936, so that it can work under Multilingul Env.
MultiByteToWideChar(NATIVE_ANSI_CP, 0, (LPCSTR) &wInCode, 2, &wUnicode, 1);
*(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount]) = wUnicode;
}
#else
// add GB string into candidate list
*(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount]) = wInCode;
#endif
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + sizeof(WORD)) = TEXT('\0');
lpCandList->dwOffset[lpCandList->dwCount + 1] =
lpCandList->dwOffset[lpCandList->dwCount] +
sizeof(WORD) + sizeof(TCHAR);
lpCandList->dwCount++;
return;
}
/**********************************************************************/
/* CompEscapeKey() */
/**********************************************************************/
void PASCAL CompEscapeKey(
LPINPUTCONTEXT lpIMC,
LPCOMPOSITIONSTRING lpCompStr,
LPGUIDELINE lpGuideLine,
LPPRIVCONTEXT lpImcP)
{
if (!lpGuideLine) {
MessageBeep((UINT)-1);
} else if (lpGuideLine->dwLevel != GL_LEVEL_NOGUIDELINE) {
lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
lpGuideLine->dwIndex = GL_ID_UNKNOWN;
lpGuideLine->dwStrLen = 0;
lpImcP->fdwImeMsg |= MSG_GUIDELINE;
}
if (lpImcP->iImeState != CST_CHOOSE) {
if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_END_COMPOSITION) &
~(MSG_START_COMPOSITION);
}
}
lpImcP->iImeState = CST_INIT;
*(LPDWORD)lpImcP->bSeq = 0;
if (lpCompStr) {
InitCompStr(lpCompStr);
lpImcP->fdwImeMsg |= MSG_COMPOSITION;
lpImcP->dwCompChar = VK_ESCAPE;
lpImcP->fdwGcsFlag |= (GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|
GCS_DELTASTART);
}
return;
}
/**********************************************************************/
/* CompBackSpaceKey() */
/**********************************************************************/
void PASCAL CompBackSpaceKey(
LPINPUTCONTEXT lpIMC,
LPCOMPOSITIONSTRING lpCompStr,
LPPRIVCONTEXT lpImcP)
{
if (lpCompStr->dwCursorPos < sizeof(BYTE)) {
lpCompStr->dwCursorPos = sizeof(BYTE);
}
lpImcP->bSeq[3] = 0;
// go back a compsoition char
lpCompStr->dwCursorPos -= sizeof(BYTE);
// clean the sequence code
lpImcP->bSeq[lpCompStr->dwCursorPos] = 0;
lpImcP->fdwImeMsg |= MSG_COMPOSITION;
lpImcP->dwCompChar = TEXT('\b');
lpImcP->fdwGcsFlag |= (GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|
GCS_DELTASTART);
if (!lpCompStr->dwCursorPos) {
if (lpImcP->fdwImeMsg & (MSG_ALREADY_OPEN)) {
ClearCand(lpIMC);
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
~(MSG_OPEN_CANDIDATE);
}
if(lpImcP->iImeState != CST_INIT) {
lpImcP->iImeState = CST_INIT;
lpCompStr->dwCompReadStrLen = lpCompStr->dwCompStrLen =
lpCompStr->dwDeltaStart = lpCompStr->dwCursorPos;
Finalize(lpIMC, lpCompStr, lpImcP, TEXT('\b'));
return;
}
if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
InitCompStr(lpCompStr);
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_END_COMPOSITION) &
~(MSG_START_COMPOSITION);
return;
}
}
// reading string is composition string for some simple IMEs
// delta start is the same as cursor position for backspace
lpCompStr->dwCompReadStrLen = lpCompStr->dwCompStrLen =
lpCompStr->dwDeltaStart = lpCompStr->dwCursorPos;
Finalize(lpIMC, lpCompStr, lpImcP, TEXT('\b'));
return;
}
/**********************************************************************/
/* CompStrInfo() */
/**********************************************************************/
void PASCAL CompStrInfo(
LPCOMPOSITIONSTRING lpCompStr,
LPPRIVCONTEXT lpImcP,
LPGUIDELINE lpGuideLine,
WORD wCharCode)
{
register DWORD dwCursorPos;
//
dwCursorPos = lpCompStr->dwCursorPos;
// dwCrusorPos limit
if (dwCursorPos >= lpImeL->nMaxKey) {
// exceed the max input key limitation
lpGuideLine->dwLevel = GL_LEVEL_ERROR;
lpGuideLine->dwIndex = GL_ID_TOOMANYSTROKE;
lpImcP->fdwImeMsg |= MSG_GUIDELINE;
return;
}
// set MSG_START_COMPOSITION
if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_START_COMPOSITION) &
~(MSG_END_COMPOSITION);
}
if (lpImcP->iImeState == CST_INIT) {
// clean the 4 bytes in one time
*(LPDWORD)lpImcP->bSeq = 0;
}
lpImcP->bSeq[dwCursorPos] = (BYTE)wCharCode;
// composition/reading string - UsedCode(Full Shape)
lpImcP->dwCompChar = (DWORD)wCharCode;
// set reading string for lpCompStr
*((LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset +
dwCursorPos*sizeof(TCHAR))) = (BYTE)lpImcP->dwCompChar;
*((LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadAttrOffset +
dwCursorPos*sizeof(TCHAR))) = ((ATTR_TARGET_CONVERTED << 8)|ATTR_TARGET_CONVERTED);
// set reading string lenght for lpCompStr
if (lpCompStr->dwCompReadStrLen <= dwCursorPos) {
lpCompStr->dwCompReadStrLen += sizeof(BYTE);
}
// composition string is reading string for some simple IMEs
lpCompStr->dwCompStrLen = lpCompStr->dwCompReadStrLen;
// composition/reading attribute length is equal to reading string length
lpCompStr->dwCompReadAttrLen = lpCompStr->dwCompReadStrLen;
lpCompStr->dwCompAttrLen = lpCompStr->dwCompStrLen;
// delta start from previous cursor position
lpCompStr->dwDeltaStart = lpCompStr->dwCursorPos;
// set new cursor with next to the composition string
lpCompStr->dwCursorPos = lpCompStr->dwCompStrLen;
// set lpImcp->iImeState
lpImcP->iImeState = CST_INPUT;
// tell app, there is a composition char generated
lpImcP->fdwImeMsg |= MSG_COMPOSITION;
// set lpImeP->fdwGcsFlag
lpImcP->fdwGcsFlag |= GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|GCS_DELTASTART;
return;
}
/**********************************************************************/
/* Finalize() */
/* Return vlaue */
/* Engine Flag */
/* Description: */
/* Call Engine finalize Chinese word(s) by searching table */
/* (Set lpCompStr and lpCandList) */
/* Set lpImeP(iImeState, fdwImeMsg, fdwGcsFlag) */
/**********************************************************************/
UINT PASCAL Finalize(
LPINPUTCONTEXT lpIMC,
LPCOMPOSITIONSTRING lpCompStr,
LPPRIVCONTEXT lpImcP,
WORD wCharCode)
{
LPCANDIDATEINFO lpCandInfo;
LPCANDIDATELIST lpCandList;
UINT fEngine;
if (!lpIMC->hCandInfo) {
return (0);
}
// get lpCandInfo
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
if (!lpCandInfo) {
return (0);
}
// get lpCandList and init dwCount & dwSelection
lpCandList = (LPCANDIDATELIST)
((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]);
lpCandList->dwCount = 0;
lpCandList->dwSelection = 0;
// search the IME tables
fEngine =Engine(lpCompStr, lpCandList, lpImcP, lpIMC, wCharCode);
if (fEngine == ENGINE_COMP) {
lpCandInfo->dwCount = 1;
if (((lpCompStr->dwCursorPos < 3) && (wCharCode != TEXT(' ')))
|| ((lpCompStr->dwCursorPos == 3)
&& (wCharCode != TEXT(' ')) && (wCharCode != TEXT('?')))) {
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
~(MSG_OPEN_CANDIDATE);
ImmUnlockIMCC(lpIMC->hCandInfo);
return (fEngine);
}
if(lpCandList->dwCount != 0x0000) {
// open composition candidate UI window for the string(s)
if ((lpImcP->fdwImeMsg & (MSG_ALREADY_OPEN|MSG_CLOSE_CANDIDATE)) ==
(MSG_ALREADY_OPEN|MSG_CLOSE_CANDIDATE)) {
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CHANGE_CANDIDATE) &
~(MSG_CLOSE_CANDIDATE);
} else if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
} else {
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_OPEN_CANDIDATE) &
~(MSG_CLOSE_CANDIDATE);
}
}
if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
lpImcP->fdwImeMsg |= MSG_COMPOSITION;
}
} else if (fEngine == ENGINE_ASCII) {
} else if (fEngine == ENGINE_RESAULT) {
// Set lpImep! and tell application, there is a reslut string
lpImcP->fdwImeMsg |= MSG_COMPOSITION;
lpImcP->dwCompChar = (DWORD)0;
lpImcP->fdwGcsFlag |= GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|
GCS_DELTASTART|GCS_RESULTREAD|GCS_RESULT;
if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
~(MSG_OPEN_CANDIDATE);
}
// clear candidate now
lpCandList->dwCount = 0;
// set iImeState with CST_INIT
lpImcP->iImeState = CST_INIT;
*(LPDWORD)lpImcP->bSeq = 0;
#ifdef CROSSREF
CrossReverseConv(lpIMC, lpCompStr, lpImcP, lpCandList);
#endif
}
ImmUnlockIMCC(lpIMC->hCandInfo);
return fEngine;
}
/**********************************************************************/
/* CompWord() */
/**********************************************************************/
void PASCAL CompWord( // compose the Chinese word(s) according to
// input key
WORD wCharCode,
LPINPUTCONTEXT lpIMC,
LPCOMPOSITIONSTRING lpCompStr,
LPPRIVCONTEXT lpImcP,
LPGUIDELINE lpGuideLine)
{
// lpComStr=NULL?
if (!lpCompStr) {
MessageBeep((UINT)-1);
return;
}
// escape key
if (wCharCode == VK_ESCAPE) { // not good to use VK as char, but...
CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP);
return;
}
// GuideLine
if (!lpGuideLine) {
} else if (lpGuideLine->dwLevel == GL_LEVEL_NOGUIDELINE) {
lpGuideLine->dwStrLen = 0;
} else {
// previous input error cause us trancate some chars
if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) {
lpImcP->bSeq[lpCompStr->dwCursorPos / 2] = 0;
lpCompStr->dwCompReadStrLen = lpCompStr->dwCompStrLen =
lpCompStr->dwCursorPos;
lpCompStr->dwCompReadAttrLen = lpCompStr->dwCompReadStrLen;
lpCompStr->dwCompAttrLen = lpCompStr->dwCompStrLen;
}
lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
lpGuideLine->dwIndex = GL_ID_UNKNOWN;
lpGuideLine->dwStrLen = 0;
lpImcP->fdwImeMsg |= MSG_GUIDELINE;
}
// backspace key
if (wCharCode == TEXT('\b')) {
CompBackSpaceKey(lpIMC, lpCompStr, lpImcP);
return;
}
if(wCharCode == TEXT(' ')) {
} else {
// build up composition string info
CompStrInfo(lpCompStr, lpImcP, lpGuideLine, wCharCode);
}
Finalize(lpIMC, lpCompStr, lpImcP, wCharCode); // compsition
return;
}