Back to index

im-sdk  12.3.91
OnKeySym.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 #include "PYIM.h"
00043 
00044 extern  JWORD     *pwNewpySym[];
00045 
00046 /* KeysymType.c */
00047 JINT    IsWantedKeysym(JINT *pks);
00048 JINT    IsQuitKeysym(JINT *pks);
00049 JINT    IsQpSpSwitchKeysym(JINT *pks);
00050 JINT    IsEditKeysym(JINT *pks);
00051 JINT    IsPageKeysym(JINT *pks);
00052 JINT    IsSelectKeysym(JINT *pks);
00053 
00054 /* Jword.c */
00055 VOID    GetAsciiFromJword(JWORD* pwJwordArray, CHAR* szAsciiArray, JINT nLen);
00056 JINT    JwordValidLen(JWORD* pwJwordArray, JINT nMaxLen);
00057 JINT    JwordStrStrReplace(JWORD* pwDst, JWORD* pwSrc1, JWORD* pwSrc2, JINT nLenSrc2);
00058 JWORD*  StrToJword(CHAR* szStr);
00059 VOID    JwordInfo(JWORD* pwJwordArray, JINT nMaxLen);
00060 VOID    Jword2Uchar(JWORD* pwJword, UCHAR* szUch, JINT nMaxLen);
00061 UCHAR*  RecovDyz2244(UCHAR *szDyz2244);
00062 JWORD*  RecovDyzNWord2244(JWORD* pwDyz2244, JINT nMaxLen);
00063 
00064 /* ParsePreedit.c */
00065 VOID    DecompPeIntArray(JINT *pnOutPreedit, CHAR* szDspPreedit);
00066 VOID    ParseRawInputStr(char* szPreedit, int* pnOutPreedit);
00067 
00068 /* Cmso.c */
00069 VOID    InitSge(SesGuiElement* pSgeStruct);
00070 
00071 JINT    IMPinyinTrans(JINT* pKsThis, SesGuiElement* pSge);  
00072 JINT    OnEditKeysym(JINT* pNextKeysym, SesGuiElement* pSge);
00073 JINT    OnPageKeysym(JINT* pNextKeysym, SesGuiElement* pSge);
00074 JINT    OnSelectKeysym(JINT* pNextKeysym, SesGuiElement* pSge);
00075 JINT    PixWidBetween (JWORD* pwPrsStr, JINT nFrom, JINT nTo);
00076 JINT    PixWidBetween_SP (JWORD* pwPrsStr, JINT nFrom, JINT nTo);
00077 VOID    GetDspPEandCaretPos (SesGuiElement* pSge);
00078 VOID    GetDspPEandCaretPos_PS (SesGuiElement* pSge);
00079 JINT    RestoreHzToPy(SesGuiElement* pSge, JINT nResFlag);
00080 JINT    YjCodeToYjStr(JINT nYjCode, CHAR* szYjStr);
00081 JINT    IsIntArrayEqual (JINT *pnIntArray1, JINT *pnIntArray2, JINT nLen);
00082 VOID    PraseMixRawPe(SesGuiElement* pSge);
00083 JINT    QpCaretToPrsCaret(JWORD* pwPrsStr, JINT nQpCaret);
00084 
00085 VOID    GetFirst9Yj(JINT* pnPrsYj, JINT* pnF9Yj, JINT* pnLen, JINT* pnMatchMode);
00086 JINT    LookupCiku(JINT* pnOrgYj, JINT nLenYj, JINT nMatchMode, SysCandi* psc, UdcCandi* puc);
00087 
00088 JINT    GetXrdCandi(SysCandi* psc, UdcCandi* puc, JINT nXrd, JWORD* pwOneCandi, JINT nGBKSupport);
00089 VOID    ScrollViewCandiPage(SysCandi* psc, UdcCandi* puc, SesGuiElement* pSge);
00090 VOID    ListCandiInfo(SysCandi *psc, UdcCandi *puc);
00091 JWORD   RecovDyzWord2244(JWORD wDyz2244);
00092 
00093 JINT    TypeOfSpMixWord(JWORD *pwSpMix, JINT nPos, JINT nKeyLayMode);
00094 JINT    OnSelectKeysym_SP(JINT* pNextKeysym, SesGuiElement* pSge);
00095 JINT    RestoreHzToPy_SP(SesGuiElement* pSge, JINT nResFlag);
00096 VOID    SpMix2QpMix(JWORD* pwSpMix, JWORD* pwMix, JINT nSpCaret, JINT *pnCaret, JINT nKeyLayMode);
00097 JINT    OnEditKeysym_SP(JINT* pNextKeysym, SesGuiElement* pSge, JINT nKeyLayMode);
00098 
00099 /* PyBasic.c */
00100 JINT    TypeOfSpChar(CHAR *pszOrgSp, JINT nPos, JINT nKeyLayMode);
00101 JINT    IsValidSpSuite(CHAR chSM, CHAR chYM, JINT nKeyLayMode);
00102 
00103 VOID    GetIehFromSge(ImToXSun *pIeh, SesGuiElement* pSge);
00104 VOID    ProcSymbIMKey(SesGuiElement* pSge, JINT nSymbType, JINT *pNextKeysym, ImToXSun *pIeh);
00105 JINT    PrepareSymbolSge(SesGuiElement* pSge, JINT nSymbType);
00106 
00107 VOID ProcAllKeysym(JINT* pKsThis, SesGuiElement* pSge)
00108 {
00109        JINT    i;
00110        JINT    nKsLen;
00111        
00112        nKsLen = 0;
00113        /* for (i = 0; (i < SUN_NUM_KEYSYM) && (pKsThis[i] != 0x0L); i++) */
00114        for (i = 0; (i < 1) && (pKsThis[i] != 0x0L); i++)
00115               nKsLen ++;
00116        if (nKsLen >= 1) 
00117        {
00118               if ((pKsThis[0] == IMXK_Shift_L) || (pKsThis[0] == IMXK_Shift_R))
00119                      bShiftIsPressed = (JSHORT)(1 - bShiftIsPressed);
00120               else if (pKsThis[0] == IMXK_Caps_Lock)
00121                      bCapsIsPressed  = (JSHORT)(1 - bCapsIsPressed);
00122                      
00123               else if ((pKsThis[0] == IMXK_Alt_L) ||
00124                       (pKsThis[0] == IMXK_Alt_L) )
00125                      bAltIsPressed = (JSHORT)(1 - bAltIsPressed);
00126                      
00127               /* The Following Key is used as Switcher of Ime Window */
00128               else if ((pKsThis[0] == IMXK_Control_L) || 
00129                       (pKsThis[0] == IMXK_Control_R) )
00130                      bCtrlIsPressed = (JSHORT)(1 - bCtrlIsPressed);
00131                      
00132               else if ((pKsThis[0] == IMXK_Meta_L) ||
00133                       (pKsThis[0] == IMXK_Meta_R) )
00134                      bMetaIsPressed = (JSHORT)(1 - bMetaIsPressed);
00135                      
00136               else if ((pKsThis[0] == IMSunXK_AltGraph) ||
00137                       (pKsThis[0] == IMXK_Mode_switch) )
00138                      bAltGrIsPressed = (JSHORT)(1 - bAltGrIsPressed);
00139                      
00140               else if ((pKsThis[0] == IMSunXK_Compose) ||
00141                       (pKsThis[0] == IMXK_Multi_key) )
00142                      bCompIsPressed = (JSHORT)(1 - bCompIsPressed);
00143                      
00144               /* 
00145               ** If some other key is combined with the above switcher(s),
00146               ** These switcher is turn Off and be send as a fully key
00147               ** to application. (Committed)
00148               */
00149               else if ((bCtrlIsPressed == 1 ) || (bMetaIsPressed == 1) ||
00150                       (bAltGrIsPressed == 1) || (bCompIsPressed == 1))
00151               {
00152               }
00153               
00154               /*
00155               ** Alt is used to Switch IM (QuanPin, ShuangPin, WuBi...)
00156               ** Other combination besides IM switcher is committed out.
00157               ** To avoid conflict with Application, Alt + 1, 2, 3, 4 is preferred.
00158               */
00159               else if (bAltIsPressed == 1)
00160               {
00161               }
00162                      
00163               /*
00164               **  Normal single Key is transferred to IM_trans.
00165               */
00166               else if ((bShiftIsPressed == 0) && (bCapsIsPressed == 0))
00167               {
00168                      if ((pKsThis[0] >= IMXK_A) && (pKsThis[0] <= IMXK_Z))
00169                             pKsThis[0] += (IMXK_a - IMXK_A);
00170 
00171                      IMPinyinTrans(pKsThis, pSge);  
00172               }
00173               
00174               else if ((bShiftIsPressed == 1) && (bCapsIsPressed == 1))
00175               {
00176                      /* Bounce Keyevent directly back application */
00177                      if ((pKsThis[0] >= IMXK_A) && (pKsThis[0] <= IMXK_Z))
00178                             pKsThis[0] += (IMXK_a - IMXK_A);
00179               }
00180               else if ((bShiftIsPressed == 0) && (bCapsIsPressed == 1))
00181               {
00182                      if (nKsLen > 1)
00183                             pKsThis[0] = pKsThis[1];
00184               }
00185               else if ((bShiftIsPressed == 1) && (bCapsIsPressed == 0))
00186               {
00187                      if (nKsLen > 1)
00188                             pKsThis[0] = pKsThis[1];
00189               }
00190        }
00191 }
00192 
00193 
00194 JINT IMPinyinTrans(JINT* pNextKeysym, SesGuiElement* pSge)
00195 {
00196        JINT    i, nTmpRes, nTmp;
00197        JINT    nF9Yj[9], nYjLen, nMatchMode;
00198        /*  The following 3 lines were commented to Fix BugID 4165549
00199        static JINT  nPrevMatchMode = -1;
00200        static JINT  pnCurChoiceYjNew[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
00201        static JINT  pnCurChoiceYjOld[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
00202        */
00203 
00204        nTmpRes = FALSE;
00205        if (IsEditKeysym(pNextKeysym) == TRUE)
00206        {
00207               if (pSge->nPinyinType == KEYLAYMODE_NEWPY)
00208                      nTmpRes     = OnEditKeysym(pNextKeysym, pSge);
00209               else if ((pSge->nPinyinType >= 0) && (pSge->nPinyinType <= 2))
00210                      nTmpRes     = OnEditKeysym_SP(pNextKeysym, pSge, pSge->nPinyinType);
00211               else
00212               {
00213                      fprintf(stderr, "Error nPinyinType Invalid.\n");
00214                      return FALSE;
00215               }
00216               
00217               /*
00218               **  Get first nine Yinjie AND 
00219               **  Process ['a' 'e' 'm' 'n' 'o'] in (nF9Yj[0] ~ nF9Yj[8])
00220               */
00221               GetFirst9Yj(pSge->nPrsPyYjCode, nF9Yj, &nYjLen, &nMatchMode);
00222 
00223               for(i = 0; i < nYjLen; i++)
00224               {
00225                      if ((nF9Yj[i] & 0x000001FF) == 0)
00226                             nF9Yj[i] += (450 - 0);
00227                      else if ((nF9Yj[i] & 0x000001FF) == 80)
00228                             nF9Yj[i] += (455 - 80);
00229                      else if ((nF9Yj[i] & 0x000001FF) == 191)
00230                             nF9Yj[i] += (462 - 191);
00231                      else if ((nF9Yj[i] & 0x000001FF) == 211)
00232                             nF9Yj[i] += (463 - 211);
00233                      else if ((nF9Yj[i] & 0x000001FF) == 237)
00234                             nF9Yj[i] += (464 - 237);
00235 
00236               }
00237               for(i = nYjLen; i < 9; i++)
00238                      nF9Yj[i] = 0;
00239 
00240               /*
00241               **  NOTICE: pnCurChoiceYjOld[] & pnCurChoiceNew[] start from 0x0800 to avoid confliction
00242               **          with YinJie Code 0 (a).
00243               */
00244               for(i = 0; i < 9; i++)
00245                      pSge->pnCurChoiceYjNew[i] = 0x0800 + nF9Yj[i];
00246 
00247               /* Must compare nMatchMode also. ...!!! */
00248               if ((IsIntArrayEqual(pSge->pnCurChoiceYjNew, pSge->pnCurChoiceYjOld, 9) != TRUE) || 
00249                      (pSge->nPrevMatchMode != nMatchMode))
00250               {
00251                      for (i = 0; i < 9; i++)
00252                             pSge->pnCurChoiceYjOld[i] = pSge->pnCurChoiceYjNew[i];
00253                      pSge->nPrevMatchMode  = nMatchMode;
00254                      
00255                      LookupCiku(nF9Yj, nYjLen, nMatchMode, &(pSge->scSysCandi), &(pSge->ucUdcCandi));
00256                      
00257                      pSge->nViewCandiStart   = 0;
00258                      pSge->nViewCandiEnd     = 0;
00259                      pSge->nViewPage         = 0;
00260                      ScrollViewCandiPage(&(pSge->scSysCandi), &(pSge->ucUdcCandi), pSge);
00261 
00262                      if (pSge->nViewCandiStart == 0)
00263                             pSge->nIconFlag &= (~F_PREVPAGE);
00264                      else
00265                             pSge->nIconFlag |= F_PREVPAGE;
00266 
00267                      nTmp  = pSge->scSysCandi.nNumMhCandi   + pSge->scSysCandi.nNumDhCandi  +
00268                              pSge->scSysCandi.nNumShCandi   + 
00269                             pSge->ucUdcCandi.nNumSpecCandi + pSge->ucUdcCandi.nNumUdc28Candi;
00270                      if(pSge->nGBKMode == GBK_SUPPORTED) nTmp += pSge->scSysCandi.nNumGbkCandi;
00271                      if (pSge->nViewCandiEnd < nTmp)
00272                             pSge->nIconFlag |= F_NEXTPAGE;
00273                      else
00274                             pSge->nIconFlag &= (~F_NEXTPAGE);
00275               }
00276        }
00277        
00278        else if (IsPageKeysym(pNextKeysym) == TRUE)
00279               nTmpRes = OnPageKeysym(pNextKeysym, pSge);
00280               
00281        else if (IsSelectKeysym(pNextKeysym) == TRUE)
00282        {
00283               if (pSge->nPinyinType == KEYLAYMODE_NEWPY)
00284                      nTmpRes     = OnSelectKeysym(pNextKeysym, pSge);
00285               else if ((pSge->nPinyinType >= 0) && (pSge->nPinyinType <= 2))
00286                      nTmpRes     = OnSelectKeysym_SP(pNextKeysym, pSge);
00287               else
00288               {
00289                      fprintf(stderr, "Error pSge->nPinyinType Invalid.\n");
00290                      return FALSE;
00291               }
00292        }
00293 
00294        return nTmpRes;
00295 }
00296 
00297 
00298 JINT OnEditKeysym(JINT* pNextKeysym, SesGuiElement* pSge)
00299 {
00300        JINT    nLen, nLenRaw, i, j, k, nTmp;
00301 
00302        JINT    nViewPixWid, nTmpWid;
00303        nViewPixWid = WIN_W - 61;   /* Here 59? 61? Is Accurate, with 9 indent in left!!! */
00304        
00305        nLen    = JwordValidLen (pSge->pwMixPeStr, 256);
00306        nLenRaw = JwordValidLen (pSge->pwRawPyStr, 256);
00307 
00308        nTmpWid = 0;
00309 
00310        if (pNextKeysym[0] == IMXK_Escape)
00311        {
00312               InitSge(pSge);
00313               goto LABEL0002;
00314        }
00315 
00316        else if( (pNextKeysym[0] == IMXK_quoteright) && 
00317               ( (pSge->pwMixPeStr[pSge->nRawCaretPos] == IMVXK_QUOTER) || 
00318               ( (pSge->nRawCaretPos > 0) && (pSge->pwMixPeStr[pSge->nRawCaretPos - 1] == IMVXK_QUOTER) )))
00319        {
00320 #ifdef _DRAW_IM_WIN_H
00321               XBell (pDspIme, 100);
00322 #endif
00323               goto LABEL0002;
00324        }
00325 
00326        else if (((pNextKeysym[0] >= IMXK_a) && (pNextKeysym[0] <= IMXK_z)) || (pNextKeysym[0] == IMXK_quoteright))
00327        {
00328               if ( (nLen >= 222) || (nLenRaw >= 222)  ||
00329                    ((nLen == 0) && 
00330                     ((pNextKeysym[0] == IMXK_i) || (pNextKeysym[0] == IMXK_u) || (pNextKeysym[0] == IMXK_v))) )
00331               {
00332 #ifdef _DRAW_IM_WIN_H
00333                      XBell (pDspIme, 100);
00334 #endif
00335                      goto LABEL0002;
00336               }
00337               
00338               for (i = (nLen - 1); i >= pSge->nRawCaretPos; i--)
00339                      pSge->pwMixPeStr[i + 1] = pSge->pwMixPeStr[i];
00340                      
00341               pSge->pwMixPeStr[pSge->nRawCaretPos] = (JWORD)pNextKeysym[0];
00342               pSge->pwMixPeStr[nLen + 1] = 0x0000;
00343               (pSge->nRawCaretPos)++;
00344               nLen += 1;
00345               
00346               goto LABEL0001;
00347        }
00348 
00349        else if (pNextKeysym[0] == IMXK_Delete)
00350        {
00351               if (pSge->nRawCaretPos == nLen)
00352               {
00353 #ifdef _DRAW_IM_WIN_H
00354                      XBell (pDspIme, 100);
00355 #endif
00356                      goto LABEL0002;
00357               }
00358               else
00359               {
00360                      for (i = pSge->nRawCaretPos; i < nLen; i++)
00361                             pSge->pwMixPeStr[i] = pSge->pwMixPeStr[i + 1];
00362                      pSge->pwMixPeStr[nLen] = 0;
00363                      for (k = nLen; k < UONE; k++)
00364                             pSge->pwMixPeStr[k] = 0x0000;
00365                      nLen -= 1;
00366                      
00367                      /* TWO [']['] connected! */
00368                      j = pSge->nRawCaretPos;
00369                      if ((j > 0) && (pSge->pwMixPeStr[j - 1] == pSge->pwMixPeStr[j]) && (pSge->pwMixPeStr[j] == '\''))
00370                      {
00371                             for (i = (pSge->nRawCaretPos) - 1; i < nLen; i++)
00372                                    pSge->pwMixPeStr[i] = pSge->pwMixPeStr[i + 1];
00373                             pSge->pwMixPeStr[nLen] = 0;
00374                             for (k = nLen; k < 256; k++)
00375                                    pSge->pwMixPeStr[k] = 0;
00376                             nLen -= 1;
00377                      }
00378                      
00379                      /* pSge->nRawCaretPos remain previous value */
00380                      goto LABEL0001;
00381               }
00382        }
00383 
00384        else if (pNextKeysym[0] == IMXK_BackSpace)
00385        {
00386               if ((pSge->nRawCaretPos == 0) || (nLen == 0))
00387               {
00388 #ifdef _DRAW_IM_WIN_H
00389                      XBell (pDspIme, 100);
00390 #endif
00391                      goto LABEL0002;
00392               }
00393               else if (pSge->pwMixPeStr[(pSge->nRawCaretPos) - 1] >= 0x8140)   /* Chracter before Caret is Hanzi */
00394               {
00395                      RestoreHzToPy(pSge, PYIM_RESTORE_LAST);
00396                      nLen = JwordValidLen(pSge->pwMixPeStr, 256);
00397                      
00398                      j = 0;
00399                      for (i = 0; i < nLen; i++)
00400                             if (pSge->pwMixPeStr[i] >= 0x8140)
00401                                    j ++;
00402                      pSge->nRawCaretPos = j;
00403                      
00404                      if (pSge->nRawCaretPos <= pSge->nViewPeStart)
00405                             pSge->nViewPeStart = pSge->nRawCaretPos - _MIN(3, pSge->nRawCaretPos);
00406 
00407                      goto LABEL0001;
00408               }
00409               else
00410               {
00411                      for (i = (pSge->nRawCaretPos) - 1; i < (nLen - 1); i++)
00412                             pSge->pwMixPeStr[i] = pSge->pwMixPeStr[i + 1];
00413                      pSge->pwMixPeStr[nLen - 1] = 0;
00414                      nLen -= 1;
00415                      for (k = nLen; k < 256; k++)
00416                             pSge->pwMixPeStr[k] = 0;
00417                      (pSge->nRawCaretPos)--;
00418 
00419                      /* TWO [']['] connected! */
00420                      j = pSge->nRawCaretPos;
00421                      if ((j > 0) && (pSge->pwMixPeStr[j - 1] == pSge->pwMixPeStr[j]) 
00422                          && (pSge->pwMixPeStr[j] == '\''))
00423                      {
00424                             for (i = (pSge->nRawCaretPos) - 1; i < nLen; i++)
00425                                    pSge->pwMixPeStr[i] = pSge->pwMixPeStr[i + 1];
00426                             pSge->pwMixPeStr[nLen] = 0;
00427                             for (k = nLen; k < 256; k++)
00428                                    pSge->pwMixPeStr[k] = 0;
00429                             nLen -= 1;
00430                      }
00431 
00432                      if (pSge->nRawCaretPos <= pSge->nViewPeStart)
00433                             pSge->nViewPeStart = pSge->nRawCaretPos - _MIN(3, pSge->nRawCaretPos);
00434 
00435                      goto LABEL0001;
00436               }
00437        }
00438 
00439        else if (pNextKeysym[0] == IMXK_Left)
00440        {
00441               if ((pSge->nRawCaretPos == 0) || (nLen == 0))
00442               {
00443 #ifdef _DRAW_IM_WIN_H
00444                      XBell (pDspIme, 100);
00445 #endif
00446                      goto LABEL0002;
00447               }
00448               else if (pSge->pwMixPeStr[(pSge->nRawCaretPos) - 1] >= 0x8140)
00449               {
00450                      RestoreHzToPy(pSge, PYIM_RESTORE_LAST);
00451                      nLen = JwordValidLen(pSge->pwMixPeStr, 256);
00452                             
00453                      j = 0;
00454                      for (i = 0; i < nLen; i++)
00455                             if (pSge->pwMixPeStr[i] >= 0x8140)
00456                                    j ++;
00457                      pSge->nRawCaretPos = j;
00458                      
00459                      if (pSge->nRawCaretPos <= pSge->nViewPeStart)
00460                             pSge->nViewPeStart = pSge->nRawCaretPos - _MIN(3, pSge->nRawCaretPos);
00461                                    
00462                      goto LABEL0001;
00463               }
00464               else 
00465               {
00466                      (pSge->nRawCaretPos)--;
00467                      if (pSge->nRawCaretPos <= pSge->nViewPeStart)
00468                             pSge->nViewPeStart = pSge->nRawCaretPos - _MIN(3, pSge->nRawCaretPos);
00469                                    
00470                      goto LABEL0001;
00471               }
00472        }
00473 
00474        else if (pNextKeysym[0] == IMXK_Right)
00475        {
00476               if (pSge->nRawCaretPos == nLen)
00477               {
00478 #ifdef _DRAW_IM_WIN_H
00479                      XBell (pDspIme, 100);
00480 #endif
00481                      goto LABEL0002;
00482               }
00483               else
00484               {
00485                      (pSge->nRawCaretPos)++;
00486                      goto LABEL0001;                    
00487               }
00488        }
00489 
00490        else if (pNextKeysym[0] == IMXK_Home)
00491        {
00492               RestoreHzToPy(pSge, PYIM_RESTORE_ALL);
00493               nLen = JwordValidLen(pSge->pwMixPeStr, 256);
00494 
00495               pSge->nRawCaretPos  = 0;
00496               pSge->nViewCaretPos = 0;
00497               pSge->nViewPeStart  = 0;
00498               
00499               goto LABEL0001;
00500        }
00501 
00502        else if (pNextKeysym[0] == IMXK_End)
00503        {
00504               pSge->nRawCaretPos = nLen;
00505               goto LABEL0001;
00506        }
00507        
00508        /*
00509        ** This judgement is added to process Selection Action or 
00510        ** Backspace/Home/LeftArrow to existing Hanzi 
00511        */
00512        else if (pNextKeysym[0] == IMXK_REDRAW_INTERNAL)
00513        {
00514               nTmp = JwordValidLen(pSge->pwSlctHz, 512);
00515               k = 0;
00516               for (i = 0; i < nTmp; i++)
00517                      if (pSge->pwSlctHz[i] >= 0x8140)
00518                             k++;
00519               
00520               pSge->nViewPeStart = _MAX(0, k - 8);
00521 
00522               goto LABEL0001;
00523        }
00524        
00525        else
00526               goto LABEL0002;
00527 
00528 LABEL0001:
00529        {
00530               /* Prase pwMixPeStr and fill other related pSge field */
00531               PraseMixRawPe(pSge);
00532               
00533               nTmpWid = PixWidBetween (pSge->pwPrsMixStr, pSge->nViewPeStart, pSge->nRawCaretPos);
00534               if (nTmpWid > nViewPixWid)
00535               {
00536                      for (i = pSge->nViewPeStart; nTmpWid > nViewPixWid; i++)
00537                             nTmpWid = PixWidBetween (pSge->pwPrsMixStr, i, pSge->nRawCaretPos);
00538                      
00539                      pSge->nViewPeStart = i - 1;
00540                      pSge->nViewPeEnd   = pSge->nRawCaretPos;
00541               }
00542               
00543               nTmpWid = 0;
00544               for (i = pSge->nViewPeStart; (i <= nLen) && (nTmpWid <= nViewPixWid); i++)
00545                      nTmpWid = PixWidBetween (pSge->pwPrsMixStr, pSge->nViewPeStart, i);
00546               
00547               pSge->nViewPeEnd = i - 1;
00548               GetDspPEandCaretPos (pSge);
00549        }
00550 
00551 LABEL0002:    
00552        return TRUE;
00553 }
00554 
00555 
00556 JINT OnPageKeysym(JINT* pNextKeysym, SesGuiElement* pSge)
00557 {
00558        JINT    nTmp;
00559        JINT    nPageSh, nPageGbk, nCurPage, nTargetPage;
00560        
00561        /* Prev Page */
00562        if ((pNextKeysym[0] == IMXK_minus) || (pNextKeysym[0] == IMXK_bracketleft) 
00563               || (pNextKeysym[0] == IMXK_comma) || (pNextKeysym[0] == IMXK_MOUSEPREV))
00564        {
00565               if (pSge->nViewCandiStart > 0)
00566               {
00567                      pSge->nViewPage --;
00568                      ScrollViewCandiPage(&(pSge->scSysCandi), &(pSge->ucUdcCandi), pSge);
00569                      goto LABEL0003;
00570               }
00571               else
00572               {
00573 #ifdef _DRAW_IM_WIN_H
00574                      XBell (pDspIme, 100);
00575 #endif
00576                      goto LABEL0004;
00577               }
00578        }
00579        /* Next Page */
00580        else if ((pNextKeysym[0] == IMXK_equal) || (pNextKeysym[0] == IMXK_bracketright) 
00581               || (pNextKeysym[0] == IMXK_period) || (pNextKeysym[0] == IMXK_MOUSENEXT))
00582        {
00583               nTmp  = pSge->scSysCandi.nNumMhCandi   + pSge->scSysCandi.nNumDhCandi  +
00584                       pSge->scSysCandi.nNumShCandi +
00585                       pSge->ucUdcCandi.nNumSpecCandi + pSge->ucUdcCandi.nNumUdc28Candi;
00586               if(pSge->nGBKMode == GBK_SUPPORTED) nTmp += pSge->scSysCandi.nNumGbkCandi;
00587 
00588               if (pSge->nViewCandiEnd < nTmp)
00589               {
00590                      pSge->nViewPage ++;
00591                      ScrollViewCandiPage(&(pSge->scSysCandi), &(pSge->ucUdcCandi), pSge);
00592                      goto LABEL0003;
00593               }
00594               else
00595               {
00596 #ifdef _DRAW_IM_WIN_H
00597                      XBell (pDspIme, 100);
00598 #endif
00599                      goto LABEL0004;
00600               }
00601        }
00602        else if (pNextKeysym[0] == IMXK_Return)
00603        {
00604               nTmp     = pSge->scSysCandi.nNumMhCandi   + pSge->scSysCandi.nNumDhCandi  +
00605                          pSge->scSysCandi.nNumShCandi   + pSge->scSysCandi.nNumGbkCandi +
00606                          pSge->ucUdcCandi.nNumSpecCandi + pSge->ucUdcCandi.nNumUdc28Candi;
00607                          
00608               nPageSh  = pSge->ucUdcCandi.nNumSpecCandi + pSge->ucUdcCandi.nNumUdc28Candi +
00609                          pSge->scSysCandi.nNumMhCandi   + pSge->scSysCandi.nNumDhCandi;
00610                          
00611               nPageGbk = nPageSh + pSge->scSysCandi.nNumShCandi;
00612               nCurPage = pSge->nViewCandiStart;
00613               
00614               if ((nCurPage < nPageSh) && (pSge->scSysCandi.nNumShCandi + pSge->scSysCandi.nNumGbkCandi > 0))
00615                      nTargetPage = nPageSh;
00616               else if ((nCurPage >= nPageSh) && (nCurPage < nPageGbk) && (pSge->scSysCandi.nNumGbkCandi > 0))
00617                      nTargetPage = nPageGbk;
00618               else                           /* (nCurPage >= nPageGbk) */
00619                      nTargetPage = 0;
00620               
00621               pSge->nViewCandiStart   = 0;
00622               pSge->nViewCandiEnd     = 0;
00623               pSge->nViewPage         = 0;
00624               for ( ; ;  )
00625               {
00626                      ScrollViewCandiPage(&(pSge->scSysCandi), &(pSge->ucUdcCandi), pSge);
00627                      if ((pSge->nViewCandiEnd < nTmp) && (pSge->nViewCandiStart < nTargetPage))
00628                             pSge->nViewPage ++;
00629                      else
00630                             break;
00631               }
00632               
00633               goto LABEL0003;
00634        }
00635        
00636        /* 以下LABEL0003代码可被组合到函数ScrollViewCandiPage中去. MXL 97.11.28 04:15 */
00637 LABEL0003:
00638        {      
00639                      if (pSge->nViewCandiStart == 0)
00640                             pSge->nIconFlag &= (~F_PREVPAGE);
00641                      else
00642                             pSge->nIconFlag |= F_PREVPAGE;
00643                      
00644                      nTmp  = pSge->scSysCandi.nNumMhCandi   + pSge->scSysCandi.nNumDhCandi  +
00645                              pSge->scSysCandi.nNumShCandi   + 
00646                              pSge->ucUdcCandi.nNumSpecCandi + pSge->ucUdcCandi.nNumUdc28Candi;
00647                      if(pSge->nGBKMode == GBK_SUPPORTED)
00648                             nTmp += pSge->scSysCandi.nNumGbkCandi;
00649 
00650                      if (pSge->nViewCandiEnd < nTmp)
00651                             pSge->nIconFlag |= F_NEXTPAGE;
00652                      else
00653                             pSge->nIconFlag &= (~F_NEXTPAGE);
00654        }
00655 
00656 LABEL0004:
00657        return TRUE;
00658 }
00659 
00660 JINT OnSelectKeysym(JINT* pNextKeysym, SesGuiElement* pSge)
00661 {
00662        JINT   i, j, nTmp, nTmpLen, nTmpRes, nRes;
00663        JINT   nCurCandiNum;
00664        JINT   nChoiceMark;    /* nChoiceMark start from 1 to nCurCandiNum */
00665        CHAR   szYjStr[80];    /* Yinjie String (including [']) corressponding to current Selection */
00666        JINT   nLenThisSel;
00667        JWORD  wThisSel[9];
00668        JINT   nXrd;
00669        JINT   nYj, nYjLen;
00670        
00671        nCurCandiNum = pSge->nViewCandiEnd - pSge->nViewCandiStart;
00672        
00673        if ((pNextKeysym[0] == IMXK_space) && (nCurCandiNum >= 1))
00674               pNextKeysym[0] = IMXK_1;
00675        else if ((pNextKeysym[0] == IMXK_space) && (nCurCandiNum == 0))
00676        {
00677 #ifdef _DRAW_IM_WIN_H
00678               XBell (pDspIme, 100);
00679 #endif
00680               return TRUE;
00681        }
00682        
00683        if ((pNextKeysym[0] > IMXK_0) && (pNextKeysym[0] <= (IMXK_0 + nCurCandiNum)))
00684        {
00685               for(i = 0; i < 9; i++)
00686                      wThisSel[i] = 0x0000;
00687               nChoiceMark     = pNextKeysym[0] - IMXK_0;
00688               nXrd            = pSge->nViewCandiStart + nChoiceMark - 1;
00689               nLenThisSel     = GetXrdCandi(&(pSge->scSysCandi), &(pSge->ucUdcCandi), nXrd, wThisSel, pSge->nGBKMode);
00690 
00691               for(i = 0; i < 80; i++)
00692                      szYjStr[i]  = '\0';
00693 
00694               /* 考虑 XIAN 问题, 如果nXrd指示是在SingleHanzi, 则只取第一个音节串 */
00695               if (nXrd >= (pSge->ucUdcCandi.nNumSpecCandi + pSge->ucUdcCandi.nNumUdc28Candi + 
00696                            pSge->scSysCandi.nNumMhCandi   + pSge->scSysCandi.nNumDhCandi))
00697                      nTmp = 1;
00698               else       /* 是双字或多字选择 */
00699                      nTmp = nLenThisSel;
00700               
00701               /*
00702               **  BUG FIXED: nTmp May be 7, more example, "中华人民共和国",
00703               **             But OrgYj String is "zh h r m g". [0, 1, 2, 3, 4]
00704               **             nOrgYj[5] & nOrgYj[6] have been set to 0 in GetF9Yj,
00705               **             So, change the judgement condition
00706               **             FROM (j < nTmp) TO (j < nTmp) && (j < nLenYj) !!
00707               **                  ^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^^^^^^^^^
00708               **             MXL, 97-12-06.
00709               */
00710               for(j = 0; (j < nTmp) && (j < pSge->scSysCandi.nLenYj); j++)
00711               {
00712                      if ((pSge->scSysCandi.nOrgYj[j] & 0xFFFD0000) == 0xFFFD0000)    /* There is a ['] aheader */
00713                             strcat(szYjStr, "'");
00714 
00715                      /****  Aha,  ShuangPin's Parse Algorigthm has changed it!!!  - Scott Ma 
00716                      if (pSge->scSysCandi.nOrgYj[j] >= 0x00010000)
00717                             strcat(szYjStr, "'");
00718                      */
00719 
00720                      nYj = pSge->scSysCandi.nOrgYj[j] & 0x01FF;
00721                      if ((nYj >= 0) && (nYj < NUM_YINJIE))
00722                             strcat(szYjStr, YINJIESTR_CSZ[nYj]);
00723                      else if ((nYj >= 450) && (nYj <= 475))
00724                             strcat(szYjStr, SHENGMUSTR[nYj - 450]);
00725               }
00726 
00727 #ifdef _DEBUG
00728               printf("TO BE REPLACED: [%s], nLenYj is %d\n", szYjStr, pSge->scSysCandi.nLenYj);
00729 #endif
00730               
00731               nRes = nTmpLen = JwordValidLen(pSge->pwSlctHz, 512);
00732               
00733               for(i = 0; i < nLenThisSel; i++)
00734                      pSge->pwSlctHz[nTmpLen + i]        = wThisSel[i];
00735               pSge->pwSlctHz[nTmpLen + nLenThisSel]  = 0x0009;        /* Horizonal Tab Key */
00736               (pSge->nSlctSteps)++;
00737 
00738               /* Calc new pSge->nRawCaretPos */
00739               nTmp    = 0;
00740               nTmpLen = JwordValidLen(pSge->pwSlctHz, 512);
00741               for (i = 0; i < nTmpLen; i++)
00742                      if (pSge->pwSlctHz[i] != 0x0009)
00743                             nTmp++;
00744               pSge->nRawCaretPos = nTmp;
00745 
00746               nTmpRes  = JwordStrStrReplace(pSge->pwMixPeStr, StrToJword(szYjStr), (JWORD*)RecovDyz2244((UCHAR*)wThisSel), nLenThisSel);
00747               if (nTmpRes == FALSE)
00748                      fprintf (stderr, "Failed in OnSelectKeysym(): JwordStrStrReplace\n");
00749               
00750               nTmpLen  = JwordValidLen(pSge->pwSlctRawPy, 512);
00751               nYjLen   = strlen(szYjStr);
00752               for (i = nTmpLen; i < (nTmpLen + nYjLen); i++)
00753                      pSge->pwSlctRawPy[i] = (JWORD)szYjStr[i - nTmpLen];
00754               pSge->pwSlctRawPy[nTmpLen + nYjLen] = 0x0009;    /* Horizonal Tab Key */
00755               
00756               /* Recycle call to IMPinyinTrans() !!!! */
00757               pNextKeysym[0] = IMXK_REDRAW_INTERNAL;
00758               IMPinyinTrans(pNextKeysym, pSge);
00759        }
00760        else
00761        {
00762 #ifdef _DRAW_IM_WIN_H
00763               XBell (pDspIme, 100);
00764 #endif
00765               ;
00766        }
00767 
00768        return TRUE;
00769 }
00770 
00771 
00772 JINT QpCaretToPrsCaret(JWORD* pwPrsStr, JINT nQpCaret)
00773 {
00774        JINT    nPrsCaret;
00775        JINT    nTotLen, i, j;
00776        
00777        nTotLen = JwordValidLen(pwPrsStr, UTWO);
00778        assert((nQpCaret <= nTotLen) && (nQpCaret >= 0));
00779        
00780        nPrsCaret = 0;
00781        j = 0;
00782        for (i = 0; i <= nTotLen; i++)
00783        {
00784               if (pwPrsStr[i] != (JWORD)' ')
00785               {
00786                      if (j == nQpCaret)
00787                             nPrsCaret = i;
00788                      j++;
00789               }
00790        }
00791        return nPrsCaret;
00792 }
00793 
00794 
00795 /*
00796 **  Range of nFrom and nTo here IS: [0] ~ [JwordValidLen(pSge->pwMixPeStr, 256)], 
00797 **  NOT [0] ~ [JwordValidLen(szRawPeStr, 256) - 1] !!!!
00798 */
00799 JINT PixWidBetween (JWORD* pwPrsStr, JINT nFrom, JINT nTo)
00800 {
00801        JINT    nTotLen, i, j, t1, t2, nt1;
00802        
00803        assert(nTo >= nFrom);
00804        nTotLen = JwordValidLen(pwPrsStr, UTWO);
00805 
00806        t1 = t2 = j = 0;
00807        for (i = 0; i <= nTotLen; i++)
00808        {
00809               if (pwPrsStr[i] != (JWORD)' ')
00810               {
00811                      if (j == nFrom)
00812                             t1 = i;
00813                      if (j == nTo)
00814                             t2 = i;
00815                      j++;
00816               }
00817        }
00818 
00819        nt1 = 0;
00820        for (i = t1; i < t2; i++)
00821        {
00822               /* REVIEW:  pwPrsStr[nTotLen] is 0 !!! */
00823               if ((pwPrsStr[i] != 0) && (pwPrsStr[i] >= 0x8140))
00824                      nt1 += HZPIXWID;
00825               else if ((pwPrsStr[i] != 0) && (pwPrsStr[i] < 0x0080))
00826                      nt1 += wAlphaIconWid[pwPrsStr[i] - 0x20];
00827        }
00828        return nt1;
00829 }
00830 
00831 
00832 /*
00833 **  Range of nFrom and nTo here IS: [0] ~ [JwordValidLen(pSge->pwMixPeStr, 256)], 
00834 **  NOT [0] ~ [JwordValidLen(szRawPeStr, 256) - 1] !!!!
00835 */
00836 JINT PixWidBetween_SP (JWORD* pwPrsStr, JINT nFrom, JINT nTo)
00837 {
00838        JINT    nTotLen, i, j, nt1;
00839        
00840        assert(nTo >= nFrom);
00841        nTotLen = JwordValidLen(pwPrsStr, UTWO);
00842 
00843        nt1 = 0;
00844        for (i = nFrom; i < nTo; i++)
00845        {
00846               /* REVIEW:  pwPrsStr[nTotLen] is 0 !!! */
00847               if ((pwPrsStr[i] != 0) && (pwPrsStr[i] >= 0x8140))
00848                      nt1 += HZPIXWID;
00849               else if ((pwPrsStr[i] != 0) && (pwPrsStr[i] < 0x0080))
00850                      nt1 += wAlphaIconWid[pwPrsStr[i] - 0x20];
00851        }
00852        return nt1;
00853 }
00854 
00855 
00856 
00857 
00858 VOID GetDspPEandCaretPos_SP (SesGuiElement* pSge)
00859 {
00860        JINT    nTotLen, i, j, t1, t2, t3;
00861        
00862        JINT    nFrom, nTo, nRawCaret, nPrsCaretPos;
00863        
00864        nFrom     = pSge->nViewPeStart;
00865        nTo       = pSge->nViewPeEnd;
00866        nRawCaret = pSge->nRawCaretPos;
00867        
00868 /*
00869        ==>[szOrgSp]>>vs#hw#rf#mn#gs#he#go#mz#tm#bu [29]
00870        ==>[  szQp ]>>zhong#hua#ren#min#gong#he#guo#mei#tian#bu [41]
00871        pwPrsMixStr >>zhong# hua# ren# min# gong# he# guo# mei# tian# bu [50]
00872        nLenSp is 29 nSpRawCaretPos[29], nLenQp is 41 nRawCaretPos[41]
00873        [nViewPeStart][ 0]  [nViewPeEnd][50]  [nRawCaretPos][41]
00874 */
00875 
00876        nTotLen      = JwordValidLen(pSge->pwPrsMixStr, UTWO);
00877        nPrsCaretPos = QpCaretToPrsCaret(pSge->pwPrsMixStr, pSge->nRawCaretPos);
00878        
00879        t1 = t2 = t3 = j = 0;
00880        for (i = 0; i <= nTotLen; i++)
00881        {
00882               if (i == nFrom)
00883                      t1 = i;
00884               if (i == nTo)
00885                      t2 = i;
00886               if (i == nPrsCaretPos)
00887                      t3 = i;
00888        }
00889        
00890        assert((t3 <= t2) && (t3 >= t1));
00891 
00892        pSge->nViewCaretPos = t3 - t1;
00893 
00894        for (i = t1; i < t2; i++)
00895               pSge->pwViewPe[i - t1] = pSge->pwPrsMixStr[i];
00896        pSge->pwViewPe[t2 - t1] = 0;
00897        
00898        if (t1 == 0)
00899               pSge->nIconFlag &= (~F_LEFTARROW);
00900        else
00901               pSge->nIconFlag |= F_LEFTARROW;
00902               
00903        if ( t2 >= (nTotLen - 1))
00904               pSge->nIconFlag &= (~F_RIGHTARROW);
00905        else
00906               pSge->nIconFlag |= F_RIGHTARROW;
00907 
00908 }
00909 
00910 
00911 
00912 VOID GetDspPEandCaretPos (SesGuiElement* pSge)
00913 {
00914        JINT    nTotLen, i, j, t1, t2, t3;
00915        
00916        JINT    nFrom, nTo, nRawCaret;
00917        
00918        nFrom     = pSge->nViewPeStart;
00919        nTo       = pSge->nViewPeEnd;
00920        nRawCaret = pSge->nRawCaretPos;
00921        
00922        /***** Above is a PATCH  MXL For ShuangPin 98-02-23 ******/
00923        
00924        assert((nRawCaret <= nTo) && (nRawCaret >= nFrom));
00925        
00926        nTotLen   = JwordValidLen(pSge->pwPrsMixStr, UTWO);
00927        
00928        t1 = t2 = t3 = j = 0;
00929        for (i = 0; i <= nTotLen; i++)
00930        {
00931               if (pSge->pwPrsMixStr[i] != (JWORD)' ')
00932               {
00933                      if (j == nFrom)
00934                             t1 = i;
00935                      if (j == nTo)
00936                             t2 = i;
00937                      if (j == nRawCaret)
00938                             t3 = i;
00939                      j++;
00940               }
00941        }
00942        
00943        pSge->nViewCaretPos = t3 - t1;
00944 
00945        for (i = t1; i < t2; i++)
00946               pSge->pwViewPe[i - t1] = pSge->pwPrsMixStr[i];
00947        pSge->pwViewPe[t2 - t1] = 0;
00948 
00949        if (t1 == 0)
00950               pSge->nIconFlag &= (~F_LEFTARROW);
00951        else
00952               pSge->nIconFlag |= F_LEFTARROW;
00953               
00954        if ( t2 >= (nTotLen - 1))
00955               pSge->nIconFlag &= (~F_RIGHTARROW);
00956        else
00957               pSge->nIconFlag |= F_RIGHTARROW;
00958 }
00959 
00960 
00961 
00962 /*
00963 **  nResFlag: PYIM_RESTORE_ALL  PYIM_RESTORE_LAST
00964 **  Conside only "HHHHHHHeeeeeee", Not include "HHHHHHeeeeHeeeeHHeee"
00965 */
00966 JINT RestoreHzToPy(SesGuiElement* pSge, JINT nResFlag)
00967 {
00968        JINT   nSelectHzLen, nSelectRawEngLen, nTotRawLen;
00969        JWORD  waHz[256], waEng[256];
00970        JINT   i, j, k, nTmp;
00971        JINT   nLenHz, nLenEng, nFirstAddr;
00972        
00973        nSelectHzLen     = JwordValidLen(pSge->pwSlctHz, 512);
00974        nSelectRawEngLen = JwordValidLen(pSge->pwSlctRawPy, 512);
00975        nTotRawLen       = JwordValidLen(pSge->pwMixPeStr, 256);
00976        
00977        for (i = 0; i < 256; i++)
00978        {
00979               waHz[i]  = 0x0000;
00980               waEng[i] = 0x0000;
00981        }
00982 
00983        if (nResFlag == PYIM_RESTORE_ALL)
00984        {
00985               i = j = 0;
00986               for (i = 0; i < nSelectHzLen; i++)
00987                      if (pSge->pwSlctHz[i] >= 0x8140)
00988                             waHz[j++] = pSge->pwSlctHz[i];
00989               nLenHz = j;
00990 
00991               i = j = 0;
00992               for (i = 0; i < nSelectRawEngLen; i++)
00993                      if (pSge->pwSlctRawPy[i] >= 0x0020)
00994                             waEng[j++] = pSge->pwSlctRawPy[i];
00995               nLenEng = j;
00996 
00997               for (i = 0; i < 512; i++)
00998               {
00999                      pSge->pwSlctRawPy[i] = 0x0000;
01000                      pSge->pwSlctHz[i]    = 0x0000;
01001               }
01002               pSge->nSlctSteps = 0;
01003        }
01004 
01005        else if (nResFlag == PYIM_RESTORE_LAST)
01006        {
01007               i = j = k = 0;
01008               for (i = 0; i < nSelectRawEngLen; i++)
01009               {
01010                      if (pSge->pwSlctRawPy[i] == 0x0009)
01011                             j++;
01012                      
01013                      if ((j == (pSge->nSlctSteps - 1)) && (pSge->pwSlctRawPy[i] != 0x0009))
01014                      {
01015                             waEng[k++] = pSge->pwSlctRawPy[i];
01016                             pSge->pwSlctRawPy[i] = 0x0000;
01017                      }
01018                      if (j == pSge->nSlctSteps)
01019                             pSge->pwSlctRawPy[i] = 0x0000;
01020               }
01021               nLenEng = k;
01022                             
01023               i = j = k = 0;
01024               for (i = 0; i < nSelectHzLen; i++)
01025               {
01026                      if (pSge->pwSlctHz[i] == 0x0009)
01027                             j++;
01028                      
01029                      if ((j == (pSge->nSlctSteps - 1)) && (pSge->pwSlctHz[i] != 0x0009))
01030                      {
01031                             waHz[k++] = pSge->pwSlctHz[i];
01032                             pSge->pwSlctHz[i] = 0x0000;
01033                      }
01034                      if (j == pSge->nSlctSteps)
01035                             pSge->pwSlctHz[i] = 0x0000;
01036               }
01037               nLenHz = k;
01038               
01039               (pSge->nSlctSteps)--;
01040 
01041        }
01042        else
01043               return FALSE;
01044 
01045        if (nResFlag == PYIM_RESTORE_ALL)
01046               nFirstAddr = 0;
01047        else    /* nResFlag == PYIM_RESTORE_LAST */
01048        {
01049               nTmp = 0;
01050               for (i = 0; i < nTotRawLen; i++)
01051                      if (pSge->pwMixPeStr[i] >= 0x8140)
01052                             nTmp++;
01053               
01054               nFirstAddr = nTmp - nLenHz;
01055        }
01056        
01057        if (nLenHz >= nLenEng)
01058        {
01059               for (i = nFirstAddr; i < (nFirstAddr + nLenEng); i++)
01060                      *(pSge->pwMixPeStr + i) = waEng[i - nFirstAddr];
01061                      
01062               for (i = (nFirstAddr + nLenEng); i < (nTotRawLen - (nLenHz - nLenEng)); i++)
01063                      *(pSge->pwMixPeStr + i) = *(pSge->pwMixPeStr + i + (nLenHz - nLenEng));
01064                      
01065               for (i = (nTotRawLen - (nLenHz - nLenEng)); i < 256; i++)
01066                      *(pSge->pwMixPeStr + i) = 0x0000;
01067        }
01068        else if (nLenHz < nLenEng)
01069        {
01070               for (i == (nTotRawLen + (nLenEng - nLenHz)); i < 256; i++)
01071                      *(pSge->pwMixPeStr + i) = 0x0000;
01072                      
01073               /* To be rewriten TO: i++ MXL: 1997-12-27 */
01074               for (i = nTotRawLen + (nLenEng - nLenHz) - 1; i >= (nFirstAddr + nLenEng); i--)
01075                      *(pSge->pwMixPeStr + i) = *(pSge->pwMixPeStr + i - nLenEng + nLenHz);
01076                      
01077               for (i = nFirstAddr; i < (nFirstAddr + nLenEng); i++)
01078                      *(pSge->pwMixPeStr + i) = waEng[i - nFirstAddr];
01079        }
01080        
01081        /*******
01082        PraseMixRawPe(pSge);
01083        *******/
01084        return TRUE;
01085 }
01086 
01087 /*
01088 **  nYjCode is bewteen 0~414, 450~475. Else, return FALSE.
01089 */
01090 JINT YjCodeToYjStr(JINT nYjCode, CHAR* szYjStr)
01091 {
01092        if ((nYjCode >= 0) && (nYjCode < NUM_YINJIE))
01093               strcpy(szYjStr, YINJIESTR_CSZ[nYjCode]);
01094        else if ((nYjCode >= 450) && (nYjCode <= 475))
01095               strcpy(szYjStr, SHENGMUSTR[nYjCode - 450]);
01096        else
01097               return FALSE;
01098        
01099        return TRUE;
01100 }
01101 
01102 
01103 JINT IsIntArrayEqual (JINT *pnInt1, JINT *pnInt2, JINT nLen)
01104 {
01105        JINT   i, nFlag;
01106        
01107        nFlag = TRUE;
01108        for(i = 0; i < nLen; i++)
01109        {
01110               if(pnInt1[i] != pnInt2[i])
01111               {
01112                      nFlag = FALSE;
01113                      break;
01114               }
01115        }
01116        
01117        return nFlag;
01118 }
01119 
01120 
01121 VOID PraseMixRawPe(SesGuiElement* pSge)
01122 {
01123        JINT    nMixRawLen, nHzPartLen, nEngLen, i;
01124        CHAR    szEngRawPeStr[256];
01125        CHAR    szTmpParsedPE[512];
01126        JINT    nSpaceFlag;
01127        
01128        nHzPartLen = 0;
01129        nMixRawLen = JwordValidLen(pSge->pwMixPeStr, UONE);
01130        
01131        for (i = 0; (i < nMixRawLen) && (pSge->pwMixPeStr[i] >= 0x8140); i++)
01132               nHzPartLen++;
01133        
01134        for (i = 0; i < 256; i++)
01135               szEngRawPeStr[i] = '\0';
01136        for (i = 0; i < 512; i++)
01137               szTmpParsedPE[i] = '\0';
01138               
01139        for (i = nHzPartLen; (i < nMixRawLen) && (pSge->pwMixPeStr[i] < 0x0080); i++)
01140               szEngRawPeStr[i - nHzPartLen] = (CHAR)pSge->pwMixPeStr[i];
01141 
01142        ParseRawInputStr (szEngRawPeStr, pSge->nPrsPyYjCode);
01143        DecompPeIntArray (pSge->nPrsPyYjCode, szTmpParsedPE);
01144        nEngLen = strlen(szTmpParsedPE);
01145        
01146        for (i = 0; i < nHzPartLen; i++)
01147               pSge->pwPrsMixStr[i] = pSge->pwMixPeStr[i];
01148               
01149        /*
01150        **  By Wendy's Suggestion, 
01151        **  为美化显示, 特意在汉字和英文之间加一空格
01152        */
01153        nSpaceFlag = 0;
01154        if (nHzPartLen > 0)
01155        {
01156               pSge->pwPrsMixStr[nHzPartLen] = (JWORD)' ';
01157               pSge->pwPrsPyStr[0] = (JWORD)' ';
01158               i++;
01159               nSpaceFlag = 1;
01160        }
01161        
01162        for (i = 0; i < nEngLen; i++)
01163        {
01164               pSge->pwPrsMixStr[i + nHzPartLen + nSpaceFlag] = (JWORD)szTmpParsedPE[i];
01165               pSge->pwPrsPyStr[i + nSpaceFlag] = (JWORD)szTmpParsedPE[i];
01166        }
01167 
01168        for (i = nEngLen + nHzPartLen + nSpaceFlag; i < 512; i++)
01169               pSge->pwPrsMixStr[i] = 0x0000;
01170 }
01171 
01172 
01173 /*
01174 **  Parse Current SysCandi, Set pSge->pwViewCandi, pSge->nViewCandiStart, pSge->nViewCandiEnd.
01175 **  Notice:  pSge->nViewCandiEnd means the first candi in NEXT page.
01176 **           nViewCandiStart and nViewCandiEnd are only used to specify whether to display
01177 **              the NEXT and PREV candidates Flag << & >> and determine how a select key
01178 **              corressponding to a Candidates Hanzi String.
01179 **           Really important Page Flag is defined in parameter pSge->nViewPage.
01180 **              Each time that when is a PageDown or PageUp key, judge from nViewCandiStart
01181 **              and nViewCandiEnd to determine whether it is PageDownable or PageUpable.
01182 **              If yes, (pSge->nViewPage)-- or (pSge->nViewPage)++ first, and then call
01183 **              the function.
01184 **           For the function, the minimum nViewPage is 0. Get the corressponding 
01185 **              pSge->pwViewCandi of the certain nViewPage by calculate from the 
01186 **              first candidate.
01187 */
01188 VOID ScrollViewCandiPage(SysCandi* psc, UdcCandi* puc, SesGuiElement* pSge)
01189 {
01190        JINT    i, j, k, m;
01191 
01192        JINT    nNumMark;              /* Digital Alpha. 1. 2. 3. 4.*** to mark Candi Number */ 
01193        JINT    nTotCandi;
01194        JINT    nMAXPIX, nTmpPix;
01195        JINT    nWantPage, nCurPage;
01196        JWORD   wNextCandi[9];
01197        JINT    nPixOfNext;            /* Width of wNextCandi[9] */
01198        JINT    nLenOfNext;            /* Hanzi Number in wNextCandi[9] after GetXrdCandi() */
01199        JINT    nPageSh, nPageGbk;
01200 
01201        nTotCandi = psc->nNumMhCandi  + psc->nNumDhCandi   + psc->nNumShCandi + 
01202                    psc->nNumGbkCandi + puc->nNumSpecCandi + puc->nNumUdc28Candi;  /* Candi Number */
01203        /* To Assure Max Candi Num is 7, so minus 20 !! */
01204        nMAXPIX   = WIN_W - 61 - 20;   /* Same as nViewPixWid in Preedit Area */
01205        nWantPage = pSge->nViewPage;   /* Page Number want to be displayed */
01206 
01207        /*
01208        **  在这里暂且不管词的频率, 按先后顺序显示. 单字最多7个. 
01209        **  象素点的数量与Preedit中的相同: 
01210        **  1.象素  2.XXXX  3.**
01211        **  必须保证: 任何一个Candidates的长度加上nNumMark的长度不会超过 nMAXPIX
01212        **
01213        **  [** TO IMPROVE: In SortSysCandi(), Rearrange XIAN candies to proper position **] 97.11.28.
01214        */
01215        for (m = 0; m < UHLF; m++)
01216               pSge->pwViewCandi[m] = 0x0000;
01217 
01218        nCurPage  = 0;
01219        nTmpPix   = 0;
01220        nNumMark  = 1;
01221        j = k = m = 0;
01222        
01223        nPageSh   = puc->nNumSpecCandi + puc->nNumUdc28Candi + psc->nNumMhCandi + psc->nNumDhCandi;
01224        nPageGbk  = nPageSh + psc->nNumShCandi;
01225        
01226        pSge->nViewCandiStart = 0;
01227        /* No i++ in this FOR sentence */
01228        for (i = 0; i < nTotCandi;  )
01229        {
01230               if (nCurPage == nWantPage)
01231               {
01232                      nLenOfNext   = GetXrdCandi(psc, puc, i, wNextCandi, pSge->nGBKMode);
01233                      /* Width of Hanzies PLUS [1.SS], S indicates SPACE ' '(0x20) */
01234                      nPixOfNext   = (nLenOfNext * HZPIXWID) + wAlphaIconWid[nNumMark + '0' - 0x20]  + 
01235                                      wAlphaIconWid['.' - 0x20] + (2 * wAlphaIconWid[' ' - 0x20]);
01236 
01237                      /*
01238                      **  If not beyond nMAXPIX, Write wNextCandi[] to pSge->nViewCandi 
01239                      **  and set pSge->nViewCandiEnd to i+1
01240                      */
01241                      if ( ((nTmpPix + nPixOfNext) >= nMAXPIX) || ((i == nPageSh || i == nPageGbk) && (nNumMark > 1) ))
01242                             break;        /* BREAK of FOR_i sentence */
01243                      else 
01244                      {
01245                             nTmpPix  += nPixOfNext;
01246                             pSge->nViewCandiEnd = i + 1;
01247 
01248                             pSge->pwViewCandi[m++]     = (JWORD)(nNumMark + '0');
01249                             pSge->pwViewCandi[m++]     = (JWORD)'.';
01250                             for (k = 0; k < nLenOfNext; )
01251                             {
01252                                    pSge->pwViewCandi[m]   = RecovDyzWord2244(wNextCandi[k]);
01253                                    m++;
01254                                    k++;
01255                             }
01256                             pSge->pwViewCandi[m++]     = 0x20;    /* SPACE: Add two SPACE after each candi */
01257                             pSge->pwViewCandi[m++]     = 0x20;    /* SPACE */
01258 
01259                             nNumMark += 1;
01260                             i++;
01261                      }
01262               }
01263 
01264               else   /* (nCurPage < nWantPage) */
01265               {
01266                      nLenOfNext   = GetXrdCandi(psc, puc, i, wNextCandi, pSge->nGBKMode);
01267                      /* Width of Hanzies PLUS [1.  ] */
01268                      nPixOfNext   = (nLenOfNext * HZPIXWID) + wAlphaIconWid[nNumMark + '0' - 0x20]    + 
01269                                      wAlphaIconWid['.' - 0x20] + (2 * wAlphaIconWid[' ' - 0x20]);
01270 
01271                      /*
01272                      **  Reset nTmpPix & nNumMark to 0 & 1, Increase nCurPage by 1.
01273                      **  Don't increase i to let it recalulate again.
01274                      */
01275                      if ( ((nTmpPix + nPixOfNext) >= nMAXPIX) || ((i == nPageSh || i == nPageGbk) && (nNumMark > 1) ))
01276                      {
01277                             nTmpPix   = 0;
01278                             nNumMark  = 1;
01279                             nCurPage += 1;
01280 
01281                             pSge->nViewCandiStart = i;
01282                      }
01283                      /* If not beyond nMAXPIX */
01284                      else
01285                      {
01286                             nTmpPix  += nPixOfNext;
01287                             nNumMark += 1;
01288                             i++;
01289                      }
01290               }
01291        } /* End of FOR_i */
01292 
01293 }
01294 
01295 
01296 /*
01297 **  Get the Xrd Candidates which store in structure psc. The content is to be
01298 **  store to pwOneCandi.
01299 **  Notice:  Range of nXrd is between [0 ~ (nTmp - 1)]. 
01300 **           Spec -> Udc28 -> Mh -> Dh -> Sh -> Gbk
01301 **  Return:  Valid Length of this candidate in JWORD.
01302 */
01303 JINT GetXrdCandi(SysCandi* psc, UdcCandi* puc, JINT nXrd, JWORD* pwOneCandi, JINT nGBKSupport)
01304 {
01305        JINT    i, k, m, nTmp;
01306        JINT    nRet;
01307        JINT    nNumSpec, nNumUdc28, nNumMh, nNumDh, nNumSh, nNumGbk;
01308        
01309        nRet  = 0;
01310        nNumSpec  = puc->nNumSpecCandi;
01311        nNumUdc28 = puc->nNumUdc28Candi;
01312        nNumMh    = psc->nNumMhCandi;
01313        nNumDh    = psc->nNumDhCandi;
01314        nNumSh    = psc->nNumShCandi;
01315        nNumGbk   = psc->nNumGbkCandi;
01316 
01317        nTmp  = nNumSpec + nNumUdc28 + nNumMh + nNumDh + nNumSh;       
01318        if(nGBKSupport == GBK_SUPPORTED) nTmp += nNumGbk;
01319        
01320        if ((nXrd < 0) || (nXrd > (nTmp - 1)))
01321               return nRet;
01322        
01323        /* SpecHz */
01324        if (nXrd < nNumSpec)                       /* [0 ~ (nNumSpecCandi - 1)] */
01325        {
01326               pwOneCandi[0] = puc->pwSpecCandi[nXrd];
01327               nRet = 1;
01328               return nRet;
01329        }
01330        /* Udc28 */
01331        else if ((nXrd >= nNumSpec) && (nXrd < (nNumSpec + nNumUdc28)))
01332        {
01333               m = nNumSpec;
01334               for (k = 0; k < puc->nSizUdc28Candi; k++)
01335               {
01336                      if (m == nXrd)
01337                      {
01338                             k++;
01339                             for(i = 0; puc->pwUdc28Candi[k] != 0x0000;  )
01340                                    pwOneCandi[i++] = puc->pwUdc28Candi[k++];
01341                             nRet = i;
01342                             break;           /* 退出k++的BREAK, NOT i++ */
01343                      }
01344                      else if (puc->pwUdc28Candi[k] == 0x0000)
01345                             m++;
01346               }
01347        }
01348        /* Mh */
01349        else if ( (nXrd >= (nNumSpec + nNumUdc28)) && 
01350                (nXrd < (nNumSpec + nNumUdc28 + nNumMh)) )
01351        {
01352               m = nNumSpec + nNumUdc28;
01353               for (k = 0; k < psc->nSizMhCandi; k++)
01354               {
01355                      if (m == nXrd)
01356                      {
01357                             k++;
01358                             for(i = 0; psc->pwMhCandi[k] != 0x0000;  )
01359                                    pwOneCandi[i++] = psc->pwMhCandi[k++];
01360                             nRet = i;
01361 
01362                             break;           /* 退出k++的BREAK, NOT i++ */
01363                      }
01364                      else if (psc->pwMhCandi[k] == 0x0000)
01365                             m++;
01366               }
01367        }
01368        /* Dh */
01369        else if ( (nXrd >= (nNumSpec + nNumUdc28 + nNumMh)) && 
01370                (nXrd < (nNumSpec + nNumUdc28 + nNumMh + nNumDh)) )
01371        {
01372               m = nNumSpec + nNumUdc28 + nNumMh;
01373               for (k = 0; k < psc->nSizDhCandi; k++)
01374               {
01375                      if (m == nXrd)
01376                      {
01377                             k++;
01378                             for (i = 0; psc->pwDhCandi[k] != 0x0000;  )
01379                                    pwOneCandi[i++] = psc->pwDhCandi[k++];
01380                             nRet = i;
01381                             break;           /* 退出k++的BREAK, NOT i++ */
01382                      }
01383                      else if (psc->pwDhCandi[k] == 0x0000)
01384                             m++;
01385               }
01386               nRet  = 2;
01387        }
01388        /*
01389        **  Sh
01390        **  Special Consideration for Single Hanzi Area: Because there is 'Xian' Question
01391        **  Here!!!! nRet may be 2.
01392        */
01393        else if ((nXrd >= (nNumSpec + nNumUdc28 + nNumMh + nNumDh)) && 
01394                (nXrd < (nNumSpec + nNumUdc28 + nNumMh + nNumDh + nNumSh)) )
01395        {
01396               m = nNumSpec + nNumUdc28 + nNumMh + nNumDh;
01397               for (k = 0; k < psc->nSizShCandi; k++)
01398               {
01399                      if (m == nXrd)
01400                      {
01401                             for (i = 0; psc->pwShCandi[k] != 0x0000;  )
01402                                    pwOneCandi[i++] = psc->pwShCandi[k++];
01403                             nRet = i;
01404                             break;           /* 退出k++的BREAK, NOT i++ */
01405                      }
01406                      else if (psc->pwShCandi[k] == 0x0000)
01407                             m++;
01408               }
01409        }
01410        /*Gbk */
01411        else if ((nXrd >= (nNumSpec + nNumUdc28 + nNumMh + nNumDh + nNumSh)) && 
01412                (nXrd < (nNumSpec + nNumUdc28 + nNumMh + nNumDh + nNumSh + nNumGbk)) )
01413        {
01414               m = nNumSpec + nNumUdc28 + nNumMh + nNumDh + nNumSh;
01415               for (k = 0; k < psc->nSizGbkCandi; k++)
01416               {
01417                      if (m == nXrd)
01418                      {
01419                             for (i = 0; psc->pwGbkCandi[k] != 0x0000;  )
01420                                    pwOneCandi[i++] = psc->pwGbkCandi[k++];
01421                             nRet = i;
01422                             break;           /* 退出k++的BREAK, NOT i++ */
01423                      }
01424                      else if (psc->pwGbkCandi[k] == 0x0000)
01425                             m++;
01426               }
01427        }
01428        else
01429        {
01430               fprintf(stderr, "nXrd is too Large!! in function GetXrdCandi().\n");
01431               nRet = 0;
01432        }
01433        
01434        return nRet;
01435 }
01436 
01437 
01438 /*
01439 **  List All Those Information in Struct SysCandi.
01440 **  This function is designed for DEBUG only. MXL 97.12.27
01441 */
01442 VOID ListCandiInfo(SysCandi *psc, UdcCandi *puc)
01443 {
01444        JINT    i, k, m;
01445        JWORD   wCandi[10];
01446        UCHAR   szCandi[20];
01447        
01448        for(i = 0; i < psc->nLenYj; i++)
01449        {
01450               if ((psc->nOrgYj[i] >= 450) && (psc->nOrgYj[i] <= 475) )
01451                      printf("%s ", SHENGMUSTR[psc->nOrgYj[i] - 450]);
01452               else if ((psc->nOrgYj[i] >= 0) && (psc->nOrgYj[i] < 415) )
01453                      printf("%s ", YINJIESTR_CSZ[psc->nOrgYj[i]]);
01454        }
01455        printf("\n\n");
01456 
01457        memset (wCandi,  '\0', 10 * sizeof(JWORD));
01458        memset (szCandi, '\0', 20);
01459        
01460        /* SpecCandi */
01461        printf("[SpecCandi]\n");
01462        i = m = 0;
01463        for (k = 0; k < puc->nNumSpecCandi; k++)
01464        {
01465               m = 1;
01466               Jword2Uchar(RecovDyzNWord2244(&(puc->pwSpecCandi[k]), m), szCandi, m);
01467               printf("%s\n", szCandi);
01468 
01469               memset (szCandi, '\0', 20);
01470        }
01471        printf("\n");
01472 
01473        /* Udc28Candi */
01474        printf("[Udc28Candi]\n");
01475        i = m = 0;
01476        for (k = 1; k < puc->nNumUdc28Candi; k++)
01477        {
01478               if (puc->pwUdc28Candi[k] == 0x0000)
01479               {
01480                      Jword2Uchar(RecovDyzNWord2244(wCandi, m), szCandi, m);
01481                      printf("%s\n", szCandi);
01482 
01483                      i++;
01484                      k++;
01485                      m = 0;
01486                      memset (wCandi, '\0', 10 * sizeof(JWORD));
01487                      memset (szCandi, '\0', 20);
01488               }
01489               else
01490                      wCandi[m++] = puc->pwUdc28Candi[k];
01491        }
01492        printf("\n");
01493        
01494        /* MhCandi */
01495        printf("[MhCandi]\n");
01496        i = m = 0;
01497        for(k = 1; i < psc->nNumMhCandi; k++)
01498        {
01499               if (psc->pwMhCandi[k] == 0x0000)
01500               {
01501                      Jword2Uchar(RecovDyzNWord2244(wCandi, m), szCandi, m);
01502                      printf("%s\n", szCandi);
01503 
01504                      i++;
01505                      k++;
01506                      m = 0;
01507                      memset (wCandi, '\0', 10 * sizeof(JWORD));
01508                      memset (szCandi, '\0', 20);
01509               }
01510               else
01511                      wCandi[m++] = psc->pwMhCandi[k];
01512        }
01513        printf("\n");
01514        
01515        /* DhCandi */
01516        printf("[DhCandi]\n");
01517        i = m = 0;
01518        for(k = 1; i < psc->nNumDhCandi; k++)
01519        {
01520               if (psc->pwDhCandi[k] == 0x0000)
01521               {
01522                      Jword2Uchar(RecovDyzNWord2244(wCandi, m), szCandi, m);
01523                      printf("%s\n", szCandi);
01524 
01525                      i++;
01526                      k++;
01527                      m = 0;
01528                      memset (wCandi, '\0', 10 * sizeof(JWORD));
01529                      memset (szCandi, '\0', 20);
01530               }
01531               else
01532                      wCandi[m++] = psc->pwDhCandi[k];
01533        }
01534        printf("\n");
01535        
01536        /* ShCandi */
01537        printf("[ShCandi]\n");
01538        i = m = 0;
01539        for(k = 0; i < psc->nNumShCandi; k++)
01540        {
01541               if (psc->pwShCandi[k] == 0x0000)
01542               {
01543                      Jword2Uchar(RecovDyzNWord2244(wCandi, m), szCandi, m);
01544                      printf("%s\n", szCandi);
01545 
01546                      i++;
01547                      m = 0;
01548                      memset (wCandi, '\0', 10 * sizeof(JWORD));
01549                      memset (szCandi, '\0', 20);
01550               }
01551               else
01552                      wCandi[m++] = psc->pwShCandi[k];
01553        }
01554        printf("\n");
01555 
01556        /* GbkCandi */
01557        printf("[GbkCandi]\n");
01558        i = m = 0;
01559        for(k = 0; i < psc->nNumGbkCandi; k++)
01560        {
01561               if (psc->pwGbkCandi[k] == 0x0000)
01562               {
01563                      Jword2Uchar(RecovDyzNWord2244(wCandi, m), szCandi, m);
01564                      printf("%s\n", szCandi);
01565 
01566                      i++;
01567                      m = 0;
01568                      memset (wCandi, '\0', 10 * sizeof(JWORD));
01569                      memset (szCandi, '\0', 20);
01570               }
01571               else
01572                      wCandi[m++] = psc->pwGbkCandi[k];
01573        }
01574        printf("\n\n");
01575 }
01576 
01577 
01578 /*
01579 **                     X x I y Y 
01580 **       X --> nTypeSpYj01   x --> nTypeSpYj1
01581 **       Y --> nTypeSpYj02   y --> nTypeSpYj2
01582 **       I --> Insert Position of nSpRawCaretPos
01583 */
01584 JINT OnEditKeysym_SP(JINT* pNextKeysym, SesGuiElement* pSge, JINT nKeyLayMode)
01585 {
01586        JINT    nLen, nLenRaw, nLenPrs, i, j, k, nTmp;
01587        JINT    nLenSp, nLenSpRaw;
01588        JINT    nTypeSpYj1, nTypeSpYj2, nTypeSpYj01, nTypeSpYj02, nTypeSpYj002, nTypeSpYj0002;
01589 
01590        JINT    nViewPixWid, nTmpWid;
01591        JINT    nPrsCaretPos;
01592        nViewPixWid = WIN_W - 61;   /* Here 59? 61? Is Accurate, with 9 indent in left!!! */
01593        
01594        nLenSp    = JwordValidLen (pSge->pwSpMixPeStr, 256);
01595        nLenSpRaw = JwordValidLen (pSge->pwSpRawPyStr, 40);
01596 
01597        nLen      = JwordValidLen (pSge->pwMixPeStr, 256);
01598        nLenRaw   = JwordValidLen (pSge->pwRawPyStr, 256);
01599 
01600        nTmpWid = 0;
01601 
01602        nTypeSpYj1 = nTypeSpYj2 = nTypeSpYj01 = nTypeSpYj02 = nTypeSpYj002 = nTypeSpYj0002 = -1;
01603        
01604        nTypeSpYj01   = TypeOfSpMixWord(pSge->pwSpMixPeStr, (pSge->nSpRawCaretPos - 2), nKeyLayMode);
01605        nTypeSpYj1    = TypeOfSpMixWord(pSge->pwSpMixPeStr, (pSge->nSpRawCaretPos - 1), nKeyLayMode);
01606        nTypeSpYj2    = TypeOfSpMixWord(pSge->pwSpMixPeStr, pSge->nSpRawCaretPos, nKeyLayMode);
01607        nTypeSpYj02   = TypeOfSpMixWord(pSge->pwSpMixPeStr, (pSge->nSpRawCaretPos + 1), nKeyLayMode);
01608        nTypeSpYj002  = TypeOfSpMixWord(pSge->pwSpMixPeStr, (pSge->nSpRawCaretPos + 2), nKeyLayMode);
01609        nTypeSpYj0002 = TypeOfSpMixWord(pSge->pwSpMixPeStr, (pSge->nSpRawCaretPos + 3), nKeyLayMode);
01610        
01611        if (pNextKeysym[0] == IMXK_Escape)
01612        {
01613               InitSge(pSge);
01614               goto LABEL0002SP;
01615        }
01616 
01617        /* QuoteRight is omitted in ShuangPin Model. MXL */
01618        else if (pNextKeysym[0] == IMXK_quoteright)
01619        {
01620 #ifdef _DRAW_IM_WIN_H
01621               XBell (pDspIme, 100);
01622 #endif
01623               goto LABEL0002SP;
01624        }
01625 
01626        else if ( ((pNextKeysym[0] >= IMXK_a) && (pNextKeysym[0] <= IMXK_z)) ||
01627                  ((pNextKeysym[0] >= IMXK_A) && (pNextKeysym[0] <= IMXK_Z)) )
01628        {
01629               if ((nLen >= 222) || (nLenRaw >= 222) || (nLenSp >= 30) || (nLenSpRaw >= 30))
01630               {
01631 #ifdef _DRAW_IM_WIN_H
01632                      XBell (pDspIme, 100);
01633 #endif
01634                      goto LABEL0002SP;
01635               }
01636               
01637               if (nTypeSpYj1 == SPYJ_YUNMU)
01638               {
01639                      /* append [v] to [hw#rf#mn] to form [hw#rf#mn#v] ===> INVALID */
01640                      /* Insert [v] to [hw#rf#mn] to form [hw#rf#v#mn] ===> NUMSIGN */
01641                      /* Insert [v] to [hw#rf$mn] to form [hw#rf#v$mn] ===> DOLLAR  */
01642                      /* Insert [v] to [hw#rf'mn] to form [hw#rf#v'mn] ===> QUOTE   */
01643                      if ((nTypeSpYj2 == SPYJ_INVALID) || (nTypeSpYj2 == SPYJ_NUMSIGN) ||
01644                             (nTypeSpYj2 == SPYJ_DOLLAR) || (nTypeSpYj2 == SPYJ_QUOTE))
01645                      {
01646                             /* Insert [#v] to Here!! */
01647                             for (i = (nLenSp - 1); i >= pSge->nSpRawCaretPos; i--)
01648                                    pSge->pwSpMixPeStr[i + 2]    = pSge->pwSpMixPeStr[i];
01649 
01650                             pSge->pwSpMixPeStr[pSge->nSpRawCaretPos]     = (JWORD)'#';
01651                             pSge->pwSpMixPeStr[pSge->nSpRawCaretPos + 1] = (JWORD)pNextKeysym[0];
01652                             pSge->pwSpMixPeStr[nLenSp + 2]               = 0x0000;
01653                             (pSge->nSpRawCaretPos) += 2;
01654                      }
01655                      else
01656                      {
01657                             assert((nTypeSpYj2 != SPYJ_SHENGMU) && (nTypeSpYj2 != SPYJ_YUNMU));
01658                      }
01659               }
01660               else if (nTypeSpYj1 == SPYJ_SHENGMU)
01661               {
01662                      /* append [s] to [hw#rf#mn#v] to form [hw#rf#mn#vs] or [hw#rf#mn#v#s] ==> INVALID */
01663                      /* Insert [s] to [hw#rf#v#mn] to form [hw#rf#vs#mn] or [hw#rf#v#s#mn] ==> NUMSIGN */
01664                      /* Insert [s] to [hw#rf#v'mn] to form [hw#rf#vs'mn] or [hw#rf#v#s'#mn]==> QUOTE   */
01665                      if ((nTypeSpYj2 == SPYJ_INVALID) || (nTypeSpYj2 == SPYJ_NUMSIGN) 
01666                             || (nTypeSpYj2 == SPYJ_QUOTE))
01667                      {
01668                             assert(pSge->nSpRawCaretPos >= 1);
01669                             if (IsValidSpSuite((CHAR)pSge->pwSpMixPeStr[pSge->nSpRawCaretPos - 1], 
01670                                    (CHAR)pNextKeysym[0], nKeyLayMode) == TRUE)
01671                             {
01672                                    /* Insert [s] */
01673                                    for (i = (nLenSp - 1); i >= pSge->nSpRawCaretPos; i--)
01674                                           pSge->pwSpMixPeStr[i + 1]    = pSge->pwSpMixPeStr[i];
01675                                    
01676                                    pSge->pwSpMixPeStr[pSge->nSpRawCaretPos]     = (JWORD)pNextKeysym[0];
01677                                    pSge->pwSpMixPeStr[nLenSp + 1]               = 0x0000;
01678                                    (pSge->nSpRawCaretPos) += 1;
01679                             }
01680                             else
01681                             {
01682                                    /* Insert [#v] Here */
01683                                    for (i = (nLenSp - 1); i >= pSge->nSpRawCaretPos; i--)
01684                                           pSge->pwSpMixPeStr[i + 2]    = pSge->pwSpMixPeStr[i];
01685 
01686                                    pSge->pwSpMixPeStr[pSge->nSpRawCaretPos]     = (JWORD)'#';
01687                                    pSge->pwSpMixPeStr[pSge->nSpRawCaretPos + 1] = (JWORD)pNextKeysym[0];
01688                                    pSge->pwSpMixPeStr[nLenSp + 2]               = 0x0000;
01689                                    (pSge->nSpRawCaretPos) += 2;
01690                             }
01691                      }
01692                      /* Insert [s] to [hw#rf#v$mn] to form [hw#rf#vs#mn] or [hw#rf#v$s#mn] */
01693                      else if (nTypeSpYj2 == SPYJ_DOLLAR)
01694                      {
01695                             assert(pSge->nSpRawCaretPos >= 1);
01696                             if (IsValidSpSuite((CHAR)pSge->pwSpMixPeStr[pSge->nSpRawCaretPos - 1], 
01697                                    (CHAR)pNextKeysym[0], nKeyLayMode) == TRUE)
01698                             {
01699                                    /* replace [$] with [s#] and increase CaretPos by 1 */
01700                                    for (i = (nLenSp - 1); i >= pSge->nSpRawCaretPos; i--)
01701                                           pSge->pwSpMixPeStr[i + 1]    = pSge->pwSpMixPeStr[i];
01702                                    
01703                                    pSge->pwSpMixPeStr[pSge->nSpRawCaretPos]     = (JWORD)pNextKeysym[0];
01704                                    pSge->pwSpMixPeStr[pSge->nSpRawCaretPos + 1] = (JWORD)'#';
01705                                    pSge->pwSpMixPeStr[nLenSp + 1]               = 0x0000;
01706                                    (pSge->nSpRawCaretPos) += 1;
01707                             }
01708                             else
01709                             {
01710                                    /* Insert [s#] after [$], NOT AFTER [v] */
01711                                    for (i = (nLenSp - 1); i >= (pSge->nSpRawCaretPos + 1); i--)
01712                                           pSge->pwSpMixPeStr[i + 2]    = pSge->pwSpMixPeStr[i];
01713 
01714                                    pSge->pwSpMixPeStr[pSge->nSpRawCaretPos + 1] = (JWORD)pNextKeysym[0];
01715                                    pSge->pwSpMixPeStr[pSge->nSpRawCaretPos + 2] = (JWORD)'#';
01716                                    pSge->pwSpMixPeStr[nLenSp + 2]               = 0x0000;
01717                                    (pSge->nSpRawCaretPos) += 2;
01718                             }
01719                      }
01720                      /* Insert [s] to [hw#rf#vw#mn] to form [hw#rf#vs#mn] or [hw#rf#v#s#mn] */
01721                      else if (nTypeSpYj2 == SPYJ_YUNMU)
01722                      {
01723                             assert(pSge->nSpRawCaretPos >= 1);
01724                             if (IsValidSpSuite((CHAR)pSge->pwSpMixPeStr[pSge->nSpRawCaretPos - 1], 
01725                                    (CHAR)pNextKeysym[0], nKeyLayMode) == TRUE)
01726                             {
01727                                    /* Replace [w] with [s], move Caret to the next position */
01728                                    pSge->pwSpMixPeStr[pSge->nSpRawCaretPos]     = (JWORD)pNextKeysym[0];
01729                                    (pSge->nSpRawCaretPos) += 1;
01730                             }
01731                             else
01732                             {
01733                                    /* Replace [w] with [#s], add Caret by 2 */
01734                                    for (i = (nLenSp - 1); i >= pSge->nSpRawCaretPos; i--)
01735                                           pSge->pwSpMixPeStr[i + 1]    = pSge->pwSpMixPeStr[i];
01736                                    
01737                                    pSge->pwSpMixPeStr[pSge->nSpRawCaretPos]     = (JWORD)'#';
01738                                    pSge->pwSpMixPeStr[pSge->nSpRawCaretPos + 1] = (JWORD)pNextKeysym[0];
01739                                    pSge->pwSpMixPeStr[nLenSp + 1]               = 0x0000;
01740                                    (pSge->nSpRawCaretPos) += 2;
01741                             }
01742                      }
01743                      else   /* nTypeSpYj2 == SPYJ_SHENGMU */
01744                      {
01745                             assert(nTypeSpYj2 != SPYJ_SHENGMU);
01746                      }
01747               }
01748               /* From the header of SpStr part of this pwSpMixPeStr */
01749               else if (nTypeSpYj1 == SPYJ_INVALID)
01750               {
01751                      if (nTypeSpYj2 == SPYJ_SHENGMU)    /* Insert [v] before [hw#rf#mn] to form [v#hw#rf#mn] */
01752                      {
01753                             /* Insert [v#], add CaretPos by 1 */
01754                             for (i = (nLenSp - 1); i >= pSge->nSpRawCaretPos; i--)
01755                                    pSge->pwSpMixPeStr[i + 2]    = pSge->pwSpMixPeStr[i];
01756                             
01757                             pSge->pwSpMixPeStr[pSge->nSpRawCaretPos]     = (JWORD)pNextKeysym[0];
01758                             pSge->pwSpMixPeStr[pSge->nSpRawCaretPos + 1] = (JWORD)'#';
01759                             pSge->pwSpMixPeStr[nLenSp + 2]               = 0x0000;
01760                             (pSge->nSpRawCaretPos) += 1;
01761                      }
01762                      else if (nTypeSpYj2 == SPYJ_QUOTE) /* Insert [v] before ['hw#rf#mn] to form [v'hw#rf#mn] */
01763                      {
01764                             /* Insert [v], add CaretPos by 1 */
01765                             for (i = (nLenSp - 1); i >= pSge->nSpRawCaretPos; i--)
01766                                    pSge->pwSpMixPeStr[i + 1]    = pSge->pwSpMixPeStr[i];
01767                                    
01768                             pSge->pwSpMixPeStr[pSge->nSpRawCaretPos]     = (JWORD)pNextKeysym[0];
01769                             pSge->pwSpMixPeStr[nLenSp + 1]               = 0x0000;
01770                             (pSge->nSpRawCaretPos) += 1;
01771                      }
01772                      else if (nTypeSpYj2 == SPYJ_INVALID)  /* Insert a single [v] to form [v] */
01773                      {
01774                             /* Only a single [v] in pwSpMixPeStr */
01775                             assert((nLenSp == 0) && (pSge->nSpRawCaretPos == 0));
01776 
01777                             pSge->pwSpMixPeStr[pSge->nSpRawCaretPos]     = (JWORD)pNextKeysym[0];
01778                             pSge->pwSpMixPeStr[nLenSp + 1]               = 0x0000;
01779                             (pSge->nSpRawCaretPos) += 1;
01780                      }
01781                      else
01782                      {
01783                             assert((nTypeSpYj2 != SPYJ_YUNMU) && (nTypeSpYj2 != SPYJ_NUMSIGN) && (nTypeSpYj2 != SPYJ_DOLLAR));
01784                      }
01785               }
01786               else if (nTypeSpYj1 == SPYJ_QUOTE)
01787               {
01788                      if (nTypeSpYj2 == SPYJ_INVALID)   /* Append [v] to [hw#rf'] to form [hw#rf'v] */
01789                      {
01790                             /* Because it means that Caret is at the end of pwSpMixPeStr */
01791                             assert(nLenSp == pSge->nSpRawCaretPos);
01792 
01793                             pSge->pwSpMixPeStr[pSge->nSpRawCaretPos]     = (JWORD)pNextKeysym[0];
01794                             pSge->pwSpMixPeStr[nLenSp + 1]               = 0x0000;
01795                             (pSge->nSpRawCaretPos) += 1;
01796                      }
01797                      else if (nTypeSpYj2 == SPYJ_SHENGMU)   /* Insert [s] to [hw#rf'v#mn] to form [hw#rf's#v#mn] */
01798                      {
01799                             /* Insert [s#], add CaretPos by 1 */
01800                             for (i = (nLenSp - 1); i >= pSge->nSpRawCaretPos; i--)
01801                                    pSge->pwSpMixPeStr[i + 2]    = pSge->pwSpMixPeStr[i];
01802                             
01803                             pSge->pwSpMixPeStr[pSge->nSpRawCaretPos]     = (JWORD)pNextKeysym[0];
01804                             pSge->pwSpMixPeStr[pSge->nSpRawCaretPos + 1] = (JWORD)'#';
01805                             pSge->pwSpMixPeStr[nLenSp + 2]               = 0x0000;
01806                             (pSge->nSpRawCaretPos) += 1;
01807                      }
01808                      else
01809                      {
01810                             /* nTypeSpYj2 should not be SPYJ_NUMSIGN   SPYJ_DOLLAR   SPYJ_YUNMU */
01811                             assert(0);
01812                      }
01813               }
01814               else if ((nTypeSpYj1 == SPYJ_NUMSIGN) || (nTypeSpYj1 == SPYJ_DOLLAR))
01815               {
01816                      /* Error condition for this UI design. For _DEBUG Only */
01817                      printf ("Error: Caret been Moved to the end of SPYJ_NUMSIGN or SPYJ_DOLLAR.\n");
01818               }
01819               
01820               /*********
01821               for (i = (nLenSp - 1); i >= pSge->nSpRawCaretPos; i--)
01822                      pSge->pwSpMixPeStr[i + 1]    = pSge->pwSpMixPeStr[i];
01823               
01824               pSge->pwSpMixPeStr[pSge->nSpRawCaretPos] = (JWORD)pNextKeysym[0];
01825               pSge->pwSpMixPeStr[nLen + 1]             = 0x0000;
01826               (pSge->nSpRawCaretPos)++;
01827               ********/
01828 
01829               /* Convert SpMix to QuanPinMix, include nSpRawCaretPos and nRawCaretPos */
01830               SpMix2QpMix(pSge->pwSpMixPeStr, pSge->pwMixPeStr, pSge->nSpRawCaretPos, &(pSge->nRawCaretPos), nKeyLayMode);
01831               nLenSp    = JwordValidLen (pSge->pwSpMixPeStr, 256);
01832               nLen      = JwordValidLen (pSge->pwMixPeStr, 256);
01833               
01834               goto LABEL0001SP;
01835        }
01836 
01837        else if (pNextKeysym[0] == IMXK_Delete)
01838        {
01839               if ((pSge->nRawCaretPos == nLen) || (pSge->nSpRawCaretPos == nLenSp))
01840               {
01841 #ifdef _DRAW_IM_WIN_H
01842                      XBell (pDspIme, 100);
01843 #endif
01844                      goto LABEL0002SP;
01845               }
01846               else
01847               {
01848                      /*
01849                      **  If to be deleted is a ShengMu, try to Delete a more YunMu also, and delete
01850                      **  SPYJ_NUMSIGN or SPYJ_DOLLAR also.
01851                      */
01852                      /*
01853                      **  SPYJ_SHENGMU & SPYJ_YUNMU & SPYJ_QUOTE & SPYJ_NUMSIGN & SPYJ_DOLLAR & SPYJ_INVALID
01854                      */
01855                      if (nTypeSpYj2 == SPYJ_INVALID)
01856                      {
01857 #ifdef _DRAW_IM_WIN_H
01858                             XBell (pDspIme, 100);
01859 #endif
01860                             goto LABEL0002SP;
01861                      }
01862                      else if (nTypeSpYj2 == SPYJ_YUNMU)
01863                      {
01864                             /* Delete this YUNMU, No matter what content of nTypeSpYj02 */
01865                             for (i = pSge->nSpRawCaretPos; i < (nLenSp - 1); i++)
01866                                    pSge->pwSpMixPeStr[i]      = pSge->pwSpMixPeStr[i + 1];
01867                                    
01868                             pSge->pwSpMixPeStr[nLenSp - 1] = 0x0000;
01869                      }
01870                      else if (nTypeSpYj2 == SPYJ_SHENGMU)
01871                      {
01872                             if ((nTypeSpYj02 == SPYJ_QUOTE) || (nTypeSpYj02 == SPYJ_NUMSIGN)
01873                                    || (nTypeSpYj02 == SPYJ_DOLLAR))
01874                             {
01875                                    /* Delete this SHENGMU and QUOTE/NUMSIGN/DOLLAR */
01876                                    /* [vs#hw#^r#mn#gs]  ==> [vs#hw#^mn#gs]           */
01877                                    for (i = pSge->nSpRawCaretPos; i < (nLenSp - 2); i++)
01878                                           pSge->pwSpMixPeStr[i]      = pSge->pwSpMixPeStr[i + 2];
01879                                    
01880                                    pSge->pwSpMixPeStr[nLenSp - 2] = 0x0000;
01881                                    pSge->pwSpMixPeStr[nLenSp - 1] = 0x0000;
01882                             }
01883                             else if (nTypeSpYj02 == SPYJ_YUNMU)
01884                             {
01885                                    if ((nTypeSpYj002 == SPYJ_QUOTE) || (nTypeSpYj002 == SPYJ_NUMSIGN) 
01886                                           || (nTypeSpYj002 == SPYJ_DOLLAR))
01887                                    {
01888                                           /* Delete this SHENGMU and YUNMU and QUOTE/NUMSIGN/DOLLAR */
01889                                           /* [vs#hw#^rf#mn#gs]  ==> [vs#hw#^mn#gs] */
01890                                           /* [^vs#hw#rf#mn#gs]  ==> [^hw#rf#mn#gs] */
01891                                           for (i = pSge->nSpRawCaretPos; i < (nLenSp - 3); i++)
01892                                                  pSge->pwSpMixPeStr[i]      = pSge->pwSpMixPeStr[i + 3];
01893                                    
01894                                           pSge->pwSpMixPeStr[nLenSp - 3] = 0x0000;
01895                                           pSge->pwSpMixPeStr[nLenSp - 2] = 0x0000;
01896                                           pSge->pwSpMixPeStr[nLenSp - 1] = 0x0000;
01897                                    }
01898                                    else if (nTypeSpYj002 == SPYJ_INVALID)
01899                                    {
01900                                           /* Delete this SHENGMU and YUNMU */
01901                                           /* [vs#hw#rf#mn#^gs]  ==> [vs#hw#rf#mn#^] */
01902                                           for (i = pSge->nSpRawCaretPos; i < (nLenSp - 2); i++)
01903                                                  pSge->pwSpMixPeStr[i]      = pSge->pwSpMixPeStr[i + 2];
01904                                    
01905                                           pSge->pwSpMixPeStr[nLenSp - 2] = 0x0000;
01906                                           pSge->pwSpMixPeStr[nLenSp - 1] = 0x0000;
01907                                    }
01908                                    else
01909                                    {
01910                                           assert((nTypeSpYj002 != SPYJ_SHENGMU) && (nTypeSpYj002 != SPYJ_YUNMU));
01911                                    }
01912                             }
01913                             else if (nTypeSpYj02 == SPYJ_INVALID)
01914                             {
01915                                    /* Delete Only this SHENGMU */
01916                                    /* [vs#hw#^f]        ==> [vs#hw#^]        INVALID  */
01917                                    /* [^f]              ==> [^]              INVALID  */
01918                                    for (i = pSge->nSpRawCaretPos; i < (nLenSp - 1); i++)
01919                                           pSge->pwSpMixPeStr[i]      = pSge->pwSpMixPeStr[i + 1];
01920                                    
01921                                    pSge->pwSpMixPeStr[nLenSp - 1] = 0x0000;
01922                             }
01923                             else
01924                             {
01925                                    assert(nTypeSpYj02 != SPYJ_SHENGMU);
01926                             }
01927                      }
01928                      else if (nTypeSpYj2 == SPYJ_QUOTE)
01929                      {
01930                             /*
01931                             **  if nTypeSpYj02 == INVALID, Just delete it
01932                             **  if nTypeSpYj02 == SHENGMU, replace it by [#]
01933                             **  Else, assert failure.
01934                             */
01935                             if (nTypeSpYj02 == SPYJ_INVALID)
01936                             {
01937                                    for (i = pSge->nSpRawCaretPos; i < (nLenSp - 1); i++)
01938                                           pSge->pwSpMixPeStr[i]      = pSge->pwSpMixPeStr[i + 1];
01939                                    
01940                                    pSge->pwSpMixPeStr[nLenSp - 1] = 0x0000;
01941                             }
01942                             else if (nTypeSpYj02 == SPYJ_SHENGMU)
01943                             {
01944                                    pSge->pwSpMixPeStr[pSge->nSpRawCaretPos] = (JWORD)'#';
01945                             }
01946                             else
01947                             {
01948                                    assert(0);
01949                             }
01950                      }
01951                      else if ((nTypeSpYj2 == SPYJ_NUMSIGN) || (nTypeSpYj2 == SPYJ_DOLLAR))
01952                      {
01953                             assert(nTypeSpYj02 == SPYJ_SHENGMU);
01954                             
01955                             /* Same as nTypeSpYj2 == SPYJ_SHENGMU, but delete this NUMSIGN/DOLLAR also */
01956                             if ((nTypeSpYj002 == SPYJ_QUOTE) || (nTypeSpYj002 == SPYJ_NUMSIGN)
01957                                    || (nTypeSpYj002 == SPYJ_DOLLAR) || (nTypeSpYj002 == SPYJ_INVALID))
01958                             {
01959                                    /* Delete this SHENGMU and QUOTE/NUMSIGN/DOLLAR */
01960                                    /* [vs#hw^#r#mn#gs]  ==> [vs#hw^#mn#gs]           */
01961                                    /* [vs#hw^#f]        ==> [vs#hw^]        INVALID  */
01962                                    for (i = pSge->nSpRawCaretPos; i < (nLenSp - 2); i++)
01963                                           pSge->pwSpMixPeStr[i]      = pSge->pwSpMixPeStr[i + 2];
01964                                    
01965                                    pSge->pwSpMixPeStr[nLenSp - 2] = 0x0000;
01966                                    pSge->pwSpMixPeStr[nLenSp - 1] = 0x0000;
01967                             }
01968                             else if (nTypeSpYj002 == SPYJ_YUNMU)
01969                             {
01970                                    /* [vs#hw^#rf#mn#gs]  ==> [vs#hw^#mn#gs] */
01971                                    /* [vs#hw#rf#mn^#gs]  ==> [vs#hw#rf#mn^] */
01972                                    if ((nTypeSpYj0002 == SPYJ_QUOTE) || (nTypeSpYj0002 == SPYJ_NUMSIGN) 
01973                                           || (nTypeSpYj0002 == SPYJ_DOLLAR) || (nTypeSpYj0002 == SPYJ_INVALID))
01974                                    {
01975                                           /* Delete this SHENGMU and YUNMU and QUOTE/NUMSIGN/DOLLAR */
01976                                           for (i = pSge->nSpRawCaretPos; i < (nLenSp - 3); i++)
01977                                                  pSge->pwSpMixPeStr[i]      = pSge->pwSpMixPeStr[i + 3];
01978                                           
01979                                           pSge->pwSpMixPeStr[nLenSp - 3] = 0x0000;
01980                                           pSge->pwSpMixPeStr[nLenSp - 2] = 0x0000;
01981                                           pSge->pwSpMixPeStr[nLenSp - 1] = 0x0000;
01982                                    }
01983                                    else
01984                                    {
01985                                           assert((nTypeSpYj0002 != SPYJ_SHENGMU) && (nTypeSpYj0002 != SPYJ_YUNMU));
01986                                    }
01987                             }
01988                             else
01989                             {
01990                                    assert(nTypeSpYj002 != SPYJ_SHENGMU);
01991                             }
01992                      }
01993 
01994                      /* pSge->nSpRawCaretPos remain previous value */
01995                      
01996                      /* Convert SpMix to QuanPinMix, include nSpRawCaretPos and nRawCaretPos */
01997                      SpMix2QpMix(pSge->pwSpMixPeStr, pSge->pwMixPeStr, pSge->nSpRawCaretPos, &(pSge->nRawCaretPos), nKeyLayMode);
01998                      nLenSp    = JwordValidLen (pSge->pwSpMixPeStr, UONE);
01999                      nLen      = JwordValidLen (pSge->pwMixPeStr, UONE);
02000 
02001                      goto LABEL0001SP;
02002               }
02003        }
02004 
02005        else if (pNextKeysym[0] == IMXK_BackSpace)
02006        {
02007               if ((pSge->nRawCaretPos == 0) || (nLen == 0) || (nLenSp == 0) || (pSge->nSpRawCaretPos == 0))
02008               {
02009 #ifdef _DRAW_IM_WIN_H
02010                      XBell (pDspIme, 100);
02011 #endif
02012                      goto LABEL0002SP;
02013               }
02014               else if (pSge->pwSpMixPeStr[(pSge->nSpRawCaretPos) - 1] >= 0x8140)   /* Character before Caret is Hanzi */
02015               {
02016                      /* Simple be explained as [LEFT Arrow]  */
02017                      pNextKeysym[0] = IMXK_Left;
02018                      OnEditKeysym_SP(pNextKeysym, pSge, nKeyLayMode);
02019               }
02020               else
02021               {
02022                      /* Simple be explained as [LEFT Arrow] and [Delete] */
02023                      pNextKeysym[0] = IMXK_Left;
02024                      OnEditKeysym_SP(pNextKeysym, pSge, nKeyLayMode);
02025                      pNextKeysym[0] = IMXK_Delete;
02026                      OnEditKeysym_SP(pNextKeysym, pSge, nKeyLayMode);
02027               }
02028        }
02029 
02030        else if (pNextKeysym[0] == IMXK_Left)
02031        {
02032               if ((pSge->nRawCaretPos == 0) || (nLen == 0) || (nLenSp == 0) || (pSge->nSpRawCaretPos == 0))
02033               {
02034 #ifdef _DRAW_IM_WIN_H
02035                      XBell (pDspIme, 100);
02036 #endif
02037                      goto LABEL0002SP;
02038               }
02039               else if (pSge->pwSpMixPeStr[(pSge->nSpRawCaretPos) - 1] >= 0x8140)   /* Chracter before Caret is Hanzi */
02040               {
02041                      /* For ShuangPin Model, This function call SpMix2QpMix() also. */
02042                      RestoreHzToPy_SP(pSge, PYIM_RESTORE_LAST);
02043                      nLenSp = JwordValidLen(pSge->pwSpMixPeStr, UONE);
02044 
02045                      j = 0;
02046                      for (i = 0; i < nLen; i++)
02047                             if (pSge->pwSpMixPeStr[i] >= 0x8140)
02048                                    j ++;
02049                      pSge->nSpRawCaretPos = j;
02050 
02051                      /*
02052                      **  Convert SpMix to QuanPinMix, include nSpRawCaretPos and nRawCaretPos 
02053                      */
02054                      SpMix2QpMix(pSge->pwSpMixPeStr, pSge->pwMixPeStr, pSge->nSpRawCaretPos, &(pSge->nRawCaretPos), nKeyLayMode);
02055                      nLen      = JwordValidLen (pSge->pwMixPeStr, UONE);
02056 
02057                      goto LABEL0001SP;
02058               }
02059               else
02060               {
02061                      if (nTypeSpYj1 != SPYJ_INVALID)
02062                      {
02063                             if ((nTypeSpYj01 == SPYJ_NUMSIGN) || (nTypeSpYj02 == SPYJ_DOLLAR))
02064                                    pSge->nSpRawCaretPos -= 2;
02065                             else
02066                                    pSge->nSpRawCaretPos -= 1;
02067                      }
02068                      else
02069                      {
02070                             assert(0);
02071                      }
02072                      
02073                      SpMix2QpMix(pSge->pwSpMixPeStr, pSge->pwMixPeStr, pSge->nSpRawCaretPos, &(pSge->nRawCaretPos), nKeyLayMode);
02074                      nLen      = JwordValidLen (pSge->pwMixPeStr, UONE);
02075 
02076                      goto LABEL0001SP;
02077               }
02078        }
02079 
02080        else if (pNextKeysym[0] == IMXK_Right)
02081        {
02082               if ((pSge->nRawCaretPos == nLen) || (pSge->nSpRawCaretPos == nLenSp))
02083               {
02084 #ifdef _DRAW_IM_WIN_H
02085                      XBell (pDspIme, 100);
02086 #endif
02087                      goto LABEL0002SP;
02088               }
02089               else
02090               {
02091                      if (nTypeSpYj2 != SPYJ_INVALID)
02092                      {
02093                             if ((nTypeSpYj2 == SPYJ_NUMSIGN) || (nTypeSpYj2 == SPYJ_DOLLAR))
02094                                    pSge->nSpRawCaretPos += 2;
02095                             else
02096                                    pSge->nSpRawCaretPos += 1;
02097                      }
02098                      else
02099                      {
02100                             assert(0);
02101                      }
02102                      
02103                      SpMix2QpMix(pSge->pwSpMixPeStr, pSge->pwMixPeStr, pSge->nSpRawCaretPos, &(pSge->nRawCaretPos), nKeyLayMode);
02104                      nLen      = JwordValidLen (pSge->pwMixPeStr, UONE);
02105 
02106                      goto LABEL0001SP;
02107               }
02108        }
02109 
02110        else if (pNextKeysym[0] == IMXK_Home)
02111        {
02112               RestoreHzToPy_SP(pSge, PYIM_RESTORE_ALL);
02113               nLenSp   = JwordValidLen(pSge->pwSpMixPeStr, UONE);
02114               pSge->nSpRawCaretPos = 0;
02115               
02116               /*
02117               **  Convert SpMix to QuanPinMix, include nSpRawCaretPos and nRawCaretPos 
02118               */
02119               SpMix2QpMix(pSge->pwSpMixPeStr, pSge->pwMixPeStr, pSge->nSpRawCaretPos, &(pSge->nRawCaretPos), nKeyLayMode);
02120               nLen      = JwordValidLen (pSge->pwMixPeStr, UONE);
02121               
02122               pSge->nRawCaretPos  = 0;
02123               pSge->nViewCaretPos = 0;
02124               pSge->nViewPeStart  = 0;
02125               
02126               goto LABEL0001SP;
02127        }
02128 
02129        else if (pNextKeysym[0] == IMXK_End)
02130        {
02131               pSge->nSpRawCaretPos = nLenSp;
02132               pSge->nRawCaretPos   = nLen;
02133               goto LABEL0001SP;
02134        }
02135        
02136        /*
02137        ** This judgement is added to process Selection Action or 
02138        ** Backspace/Home/LeftArrow to existing Hanzi 
02139        */
02140        else if (pNextKeysym[0] == IMXK_REDRAW_INTERNAL)
02141        {
02142               /*
02143               **  Convert SpMix to QuanPinMix, include nSpRawCaretPos and nRawCaretPos 
02144               */
02145               SpMix2QpMix(pSge->pwSpMixPeStr, pSge->pwMixPeStr, pSge->nSpRawCaretPos, &(pSge->nRawCaretPos), nKeyLayMode);
02146               nLenSp    = JwordValidLen (pSge->pwSpMixPeStr, 256);
02147               nLen      = JwordValidLen (pSge->pwMixPeStr, 256);
02148               
02149               nTmp = JwordValidLen(pSge->pwSlctHz, 512);
02150               k = 0;
02151               for (i = 0; i < nTmp; i++)
02152                      if (pSge->pwSlctHz[i] >= 0x8140)
02153                             k++;
02154               
02155               pSge->nViewPeStart = _MAX(0, k - 8);
02156 
02157               goto LABEL0001SP;
02158        }
02159        
02160        else
02161               goto LABEL0002SP;
02162 
02163 LABEL0001SP:
02164        {
02165               /* Prase pwMixPeStr and fill other related pSge field */
02166               PraseMixRawPe(pSge);
02167               
02168               nPrsCaretPos = QpCaretToPrsCaret(pSge->pwPrsMixStr, pSge->nRawCaretPos);
02169               if (nPrsCaretPos <= pSge->nViewPeStart)
02170                      pSge->nViewPeStart = nPrsCaretPos - _MIN(3, nPrsCaretPos);
02171 
02172               nTmpWid = PixWidBetween_SP (pSge->pwPrsMixStr, pSge->nViewPeStart, nPrsCaretPos);
02173               
02174               if (nTmpWid > nViewPixWid)
02175               {
02176                      for (i = pSge->nViewPeStart; nTmpWid > nViewPixWid; i++)
02177                             nTmpWid = PixWidBetween_SP (pSge->pwPrsMixStr, i, nPrsCaretPos);
02178                      
02179                      pSge->nViewPeStart = i - 1;
02180                      pSge->nViewPeEnd   = nPrsCaretPos;
02181               }
02182               
02183               nTmpWid = 0;
02184               nLenPrs = JwordValidLen(pSge->pwPrsMixStr, UTWO);
02185               for (i = pSge->nViewPeStart; (i <= nLenPrs) && (nTmpWid <= nViewPixWid); i++)
02186                      nTmpWid = PixWidBetween_SP (pSge->pwPrsMixStr, pSge->nViewPeStart, i);
02187               
02188               pSge->nViewPeEnd = i - 1;
02189               
02190               GetDspPEandCaretPos_SP (pSge);
02191        }
02192 
02193 LABEL0002SP:  
02194        return TRUE;
02195 }
02196 
02197 
02198 /*
02199 ** NOTICE:    pSge->pwRawPyStr WAS NOT USED Properly!!   MXL 
02200 ** In QianPinYin Model, pwRawPyStr must be filled each time.
02201 ** Replaced by a KeyStroke Count maybe more helpful!!
02202 */
02203 
02204 /*
02205 **  Convert pwSpMix to pwMix. pwSpMix is Hanzi and Sp Chars string. convert these Sp Chars to
02206 **  Qp Chars (without SPACE), and recalulates Caret Pos.
02207 */
02208 VOID SpMix2QpMix(JWORD* pwSpMix, JWORD* pwMix, JINT nSpCaret, JINT *pnCaret, JINT nKeyLayMode)
02209 {
02210        CHAR    szOrgSp[40], szQp[256];
02211        JINT    i, nLen, nLenHz;
02212        JINT    nTmpCaret;
02213        
02214        nLen   = JwordValidLen (pwSpMix, 256);
02215        nLenHz = 0;
02216        
02217        for (i = 0; i < nLen; i++)
02218        {
02219               if (pwSpMix[i] <= 0x0080)
02220                      break;               /* BREAK out FOR_i */
02221        }
02222        nLenHz = i;
02223        
02224        assert((nLen - nLenHz) < 40);
02225        assert(nSpCaret >= nLenHz);
02226        
02227        memset (szOrgSp, '\0', 40);
02228        memset (szQp,    '\0', 256);
02229        
02230        for (i = nLenHz; i < nLen; i++)
02231               szOrgSp[i - nLenHz] = (CHAR)(pwSpMix[i] & 0x00FF);
02232        
02233        Sp2QpStr_Better(szOrgSp, szQp, nKeyLayMode, nSpCaret - nLenHz, &nTmpCaret);
02234        
02235        for (i = 0; i < nLenHz; i++)
02236               pwMix[i] = pwSpMix[i];
02237 
02238        assert((nLenHz + strlen(szQp)) < 240);
02239 
02240        for (i = nLenHz; i < nLenHz + strlen(szQp); i++)
02241               pwMix[i] = (JWORD)szQp[i - nLenHz];
02242               
02243        pwMix[i] = 0x0000;
02244        *pnCaret = nTmpCaret + nLenHz;
02245 }
02246 
02247 
02248 JINT TypeOfSpMixWord(JWORD *pwSpMix, JINT nPos, JINT nKeyLayMode)
02249 {
02250        CHAR    szOrgSp[40];
02251        JINT    i, nLenHz, nLen;
02252        JINT    nRes;
02253 
02254        nLen   = JwordValidLen (pwSpMix, 256);
02255        nLenHz = 0;
02256        
02257        for (i = 0; i < nLen; i++)
02258        {
02259               if (pwSpMix[i] <= 0x0080)
02260                      break;               /* BREAK out FOR_i */
02261        }
02262        nLenHz = i;
02263 
02264        memset (szOrgSp, '\0', 40);
02265        
02266 #ifdef _DEBUG
02267        if ((nLen - nLenHz) > 39)
02268               fprintf (stderr, "Error in TypeOfSpMixWord(): > 39!\n");
02269 #endif
02270 
02271        for (i = nLenHz; i < nLen; i++)
02272               szOrgSp[i - nLenHz] = (CHAR)(pwSpMix[i] & 0x00FF);
02273               
02274        nRes = TypeOfSpChar(szOrgSp, (nPos - nLenHz), nKeyLayMode);
02275        return nRes;
02276 }
02277 
02278 
02279 /*
02280 **  nResFlag: PYIM_RESTORE_ALL  PYIM_RESTORE_LAST
02281 **  Conside only "HHHHHHHeeeeeee", Not include "HHHHHHeeeeHeeeeHHeee"
02282 */
02283 JINT RestoreHzToPy_SP(SesGuiElement* pSge, JINT nResFlag)
02284 {
02285        JINT    nSelectHzLen, nSpSelectRawEngLen, nSpTotRawLen;
02286        JINT    nLenHz, nLenSpEng, nFirstAddr;
02287        JWORD   waHz[256], waSpEng[256];
02288        
02289        JINT   i, j, k, nTmp;
02290 
02291        nSelectHzLen        = JwordValidLen(pSge->pwSlctHz, 512);
02292        nSpSelectRawEngLen  = JwordValidLen(pSge->pwSpSlctRawPy, 512);
02293        nSpTotRawLen        = JwordValidLen(pSge->pwSpMixPeStr, 256);
02294        
02295        for (i = 0; i < 256; i++)
02296        {
02297               waHz[i]     = 0x0000;
02298               waSpEng[i]  = 0x0000;
02299        }
02300 
02301        if (nResFlag == PYIM_RESTORE_ALL)
02302        {
02303               i = j = 0;
02304               for (i = 0; i < nSelectHzLen; i++)
02305                      if (pSge->pwSlctHz[i] >= 0x8140)
02306                             waHz[j++] = pSge->pwSlctHz[i];
02307               nLenHz = j;
02308 
02309               i = j = 0;
02310               for (i = 0; i < nSpSelectRawEngLen; i++)
02311                      if (pSge->pwSpSlctRawPy[i] >= 0x0020)
02312                             waSpEng[j++] = pSge->pwSpSlctRawPy[i];
02313               nLenSpEng = j;
02314               
02315               for (i = 0; i < 512; i++)
02316               {
02317                      pSge->pwSlctHz[i]      = 0x0000;
02318                      pSge->pwSpSlctRawPy[i] = 0x0000;
02319               }
02320               pSge->nSlctSteps = 0;
02321        }
02322 
02323        else if (nResFlag == PYIM_RESTORE_LAST)
02324        {
02325               i = j = k = 0;
02326               for (i = 0; i < nSpSelectRawEngLen; i++)
02327               {
02328                      if (pSge->pwSpSlctRawPy[i] == 0x0009)
02329                             j++;
02330                      
02331                      if ((j == (pSge->nSlctSteps - 1)) && (pSge->pwSpSlctRawPy[i] != 0x0009))
02332                      {
02333                             waSpEng[k++]           = pSge->pwSpSlctRawPy[i];
02334                             pSge->pwSpSlctRawPy[i] = 0x0000;
02335                      }
02336                      if (j == pSge->nSlctSteps)
02337                             pSge->pwSpSlctRawPy[i] = 0x0000;
02338               }
02339               nLenSpEng = k;
02340                             
02341               i = j = k = 0;
02342               for (i = 0; i < nSelectHzLen; i++)
02343               {
02344                      if (pSge->pwSlctHz[i] == 0x0009)
02345                             j++;
02346                      
02347                      if ((j == (pSge->nSlctSteps - 1)) && (pSge->pwSlctHz[i] != 0x0009))
02348                      {
02349                             waHz[k++] = pSge->pwSlctHz[i];
02350                             pSge->pwSlctHz[i] = 0x0000;
02351                      }
02352                      if (j == pSge->nSlctSteps)
02353                             pSge->pwSlctHz[i] = 0x0000;
02354               }
02355               nLenHz = k;
02356               
02357               (pSge->nSlctSteps)--;
02358 
02359        }
02360        else
02361               return FALSE;
02362 
02363        if (nResFlag == PYIM_RESTORE_ALL)
02364               nFirstAddr = 0;
02365        else    /* nResFlag == PYIM_RESTORE_LAST */
02366        {
02367               nTmp = 0;
02368               for (i = 0; i < nSpTotRawLen; i++)
02369                      if (pSge->pwSpMixPeStr[i] >= 0x8140)
02370                             nTmp++;
02371               
02372               nFirstAddr = nTmp - nLenHz;
02373        }
02374        
02375        if (nLenHz >= nLenSpEng)
02376        {
02377               for (i = nFirstAddr; i < (nFirstAddr + nLenSpEng); i++)
02378                      *(pSge->pwSpMixPeStr + i) = waSpEng[i - nFirstAddr];
02379                      
02380               for (i = (nFirstAddr + nLenSpEng); i < (nSpTotRawLen - (nLenHz - nLenSpEng)); i++)
02381                      *(pSge->pwSpMixPeStr + i) = *(pSge->pwSpMixPeStr + i + (nLenHz - nLenSpEng));
02382                      
02383               for (i = (nSpTotRawLen - (nLenHz - nLenSpEng)); i < 256; i++)
02384                      *(pSge->pwSpMixPeStr + i) = 0x0000;
02385        }
02386        else if (nLenHz < nLenSpEng)
02387        {
02388               for (i == (nSpTotRawLen + (nLenSpEng - nLenHz)); i < 256; i++)
02389                      *(pSge->pwSpMixPeStr + i) = 0x0000;
02390                      
02391               /* To be rewriten TO: i++ MXL: 1997-12-27 */
02392               for (i = nSpTotRawLen + (nLenSpEng - nLenHz) - 1; i >= (nFirstAddr + nLenSpEng); i--)
02393                      *(pSge->pwSpMixPeStr + i) = *(pSge->pwSpMixPeStr + i - nLenSpEng + nLenHz);
02394                      
02395               for (i = nFirstAddr; i < (nFirstAddr + nLenSpEng); i++)
02396                      *(pSge->pwSpMixPeStr + i) = waSpEng[i - nFirstAddr];
02397        }
02398        
02399        return TRUE;
02400 }
02401 
02402 
02403 JINT OnSelectKeysym_SP(JINT* pNextKeysym, SesGuiElement* pSge)
02404 {
02405        JINT   i, j, nTmp, nTmpLen, nTmpRes, nRes;
02406        JINT   nCurCandiNum;
02407        JINT   nChoiceMark;    /* nChoiceMark start from 1 to nCurCandiNum */
02408        CHAR   szYjStr[80];    /* ShuangPin Yinjie String (including [']) corressponding to current Selection */
02409        JINT   nLenThisSel;
02410        JWORD  wThisSel[9];
02411        JINT   nXrd;
02412        JINT   nYj, nYjLen;
02413        
02414        JINT   nOffset, nSpYjLen, w;        /* a nOffset was added to calculates the Position of Hanzi in pwSpMixPeStr  */
02415        
02416        nCurCandiNum = pSge->nViewCandiEnd - pSge->nViewCandiStart;
02417        
02418        if ((pNextKeysym[0] == IMXK_space) && (nCurCandiNum >= 1))
02419               pNextKeysym[0] = IMXK_1;
02420        else if ((pNextKeysym[0] == IMXK_space) && (nCurCandiNum == 0))
02421        {
02422 #ifdef _DRAW_IM_WIN_H
02423               XBell (pDspIme, 100);
02424 #endif
02425               return TRUE;
02426        }
02427        
02428        if ((pNextKeysym[0] > IMXK_0) && (pNextKeysym[0] <= (IMXK_0 + nCurCandiNum)))
02429        {
02430               for(i = 0; i < 9; i++)
02431                      wThisSel[i] = 0x0000;
02432               nChoiceMark     = pNextKeysym[0] - IMXK_0;
02433               nXrd            = pSge->nViewCandiStart + nChoiceMark - 1;
02434               nLenThisSel     = GetXrdCandi(&(pSge->scSysCandi), &(pSge->ucUdcCandi), nXrd, wThisSel, pSge->nGBKMode);
02435 
02436               for(i = 0; i < 80; i++)
02437                      szYjStr[i]  = '\0';
02438 
02439               /* 考虑 XIAN 问题, 如果nXrd指示是在SingleHanzi, 则只取第一个音节串 */
02440               if (nXrd >= (pSge->ucUdcCandi.nNumSpecCandi + pSge->ucUdcCandi.nNumUdc28Candi + 
02441                            pSge->scSysCandi.nNumMhCandi   + pSge->scSysCandi.nNumDhCandi))
02442                      nTmp = 1;
02443               else       /* 是双字或多字选择 */
02444                      nTmp = nLenThisSel;
02445 
02446               /*
02447               **  BUG FIXED: nTmp May be 7, more example, "中华人民共和国",
02448               **             But OrgYj String is "zh h r m g". [0, 1, 2, 3, 4]
02449               **             nOrgYj[5] & nOrgYj[6] have been set to 0 in GetF9Yj,
02450               **             So, change the judgement condition
02451               **             FROM (j < nTmp) TO (j < nTmp) && (j < nLenYj) !!
02452               **                  ^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^^^^^^^^^
02453               **             MXL, 97-12-06.
02454               */
02455               /* Empty FOR_j HERE!! Find where is the end of Hanzi */
02456               for (j = 0; pSge->pwSpMixPeStr[j] >= 0x0080; j++)
02457               {
02458                      ;
02459               }
02460               nOffset = j;        /* Offset of First Sp English char */
02461               
02462               w = 0;
02463               for (j = 0; (j < nTmp) && (j < pSge->scSysCandi.nLenYj); j++)
02464               {
02465                      /* Here is a LAZY PATCH!! [Scott Ma 98-04-26]  */
02466                      nSpYjLen = 0;
02467                      if ((pSge->scSysCandi.nOrgYj[j + 1] & 0x000F0000) == 0x000E0000)    /* There is a ['] aheader */
02468                      {
02469                             nSpYjLen++;
02470                      }
02471                      else if ((pSge->scSysCandi.nOrgYj[j + 1] & 0x000F0000) == 0x000D0000)    /* There is a [#] aheader */
02472                      {
02473                             nSpYjLen++;
02474                      }
02475                      else if ((pSge->scSysCandi.nOrgYj[j + 1] & 0x000F0000) == 0x000C0000)    /* There is a [$] aheader */
02476                      {
02477                             nSpYjLen++;
02478                      }
02479 
02480                      nYj = pSge->scSysCandi.nOrgYj[j] & 0x01FF;
02481                      if ((nYj >= 0) && (nYj < NUM_YINJIE) && (nYj != 450) && (nYj != 455) && (nYj != 462) && (nYj != 463) && (nYj != 464))
02482                             nSpYjLen += 2;
02483                      else
02484                             nSpYjLen += 1;
02485                             
02486                      for (i = 0; i < nSpYjLen; i++)
02487                             szYjStr[w++] = (CHAR)(pSge->pwSpMixPeStr[nOffset++]);
02488               }
02489 
02490 #ifdef _DEBUG
02491               printf("TO BE REPLACED: nTmp is [%d],  [%s], nLenYj is %d\n", nTmp, szYjStr, pSge->scSysCandi.nLenYj);
02492 #endif
02493 
02494               nRes = nTmpLen = JwordValidLen(pSge->pwSlctHz, 512);
02495               
02496               for(i = 0; i < nLenThisSel; i++)
02497                      pSge->pwSlctHz[nTmpLen + i]        = wThisSel[i];
02498               pSge->pwSlctHz[nTmpLen + nLenThisSel]  = 0x0009;        /* Horizonal Tab Key */
02499               (pSge->nSlctSteps)++;
02500 
02501               /* Calc new pSge->nRawCaretPos */
02502               nTmp    = 0;
02503               nTmpLen = JwordValidLen(pSge->pwSlctHz, 512);
02504               for (i = 0; i < nTmpLen; i++)
02505                      if (pSge->pwSlctHz[i] != 0x0009)
02506                             nTmp++;
02507               pSge->nSpRawCaretPos = nTmp;
02508 
02509               nTmpRes  = JwordStrStrReplace(pSge->pwSpMixPeStr, StrToJword(szYjStr), (JWORD*)RecovDyz2244((UCHAR*)wThisSel), nLenThisSel);
02510               if (nTmpRes == FALSE)
02511                      fprintf (stderr, "Failed in OnSelectKeysym(): JwordStrStrReplace\n");
02512               
02513               nTmpLen  = JwordValidLen(pSge->pwSpSlctRawPy, 512);
02514               nYjLen   = strlen(szYjStr);
02515               for (i = nTmpLen; i < (nTmpLen + nYjLen); i++)
02516                      pSge->pwSpSlctRawPy[i] = (JWORD)szYjStr[i - nTmpLen];
02517               pSge->pwSpSlctRawPy[nTmpLen + nYjLen] = 0x0009;  /* Horizonal Tab Key */
02518               
02519               /* Recycle call to IMPinyinTrans() !!!! */
02520               pNextKeysym[0] = IMXK_REDRAW_INTERNAL;
02521               IMPinyinTrans(pNextKeysym, pSge);
02522        }
02523        else
02524        {
02525 #ifdef _DRAW_IM_WIN_H
02526               XBell (pDspIme, 100);
02527 #endif
02528               ;
02529        }
02530 
02531        return TRUE;
02532 }
02533 
02534 
02535 /* 
02536  *  Prepare and fill pSge structure for given symbol type
02537  *  nSymbType from 0 to 12
02538  */
02539 JINT PrepareSymbolSge(SesGuiElement* pSge, JINT nSymbType)
02540 {
02541        JINT    i, nLen, nTmp;
02542        
02543        free (pSge->scSysCandi.pwMhCandi);
02544        free (pSge->scSysCandi.pwDhCandi);
02545        free (pSge->scSysCandi.pwShCandi);
02546        free (pSge->scSysCandi.pwGbkCandi);
02547        free (pSge->ucUdcCandi.pwUdc28Candi);
02548        
02549        pSge->scSysCandi.pwMhCandi    = NULL;
02550        pSge->scSysCandi.pwDhCandi    = NULL;
02551        pSge->scSysCandi.pwShCandi    = NULL;
02552        pSge->scSysCandi.pwGbkCandi   = NULL;
02553        pSge->ucUdcCandi.pwUdc28Candi = NULL;
02554        
02555        InitSge(pSge);
02556        
02557        nLen = JwordValidLen(pwNewpySym[nSymbType], 256);
02558        
02559        pSge->scSysCandi.nNumShCandi = nLen;
02560        pSge->scSysCandi.nSizShCandi = nLen * 2;     /* In Jword */
02561        pSge->scSysCandi.pwShCandi   = (JWORD*)malloc((nLen * 2  + MALIGN) * sizeof(JWORD));
02562        if (pSge->scSysCandi.pwShCandi == NULL)
02563        {
02564               fprintf(stderr, "Error!! Failed to Malloc() in Function PrepareSymbolSge().\n");
02565               return FALSE;
02566        }
02567        memset(pSge->scSysCandi.pwShCandi,  0x00, (nLen * 2  + MALIGN) * sizeof(JWORD));
02568        
02569        for (i = 0; i < nLen; i++)
02570               pSge->scSysCandi.pwShCandi[2 * i] = pwNewpySym[nSymbType][i];
02571 
02572        pSge->nViewCandiStart   = 0;
02573        pSge->nViewCandiEnd     = 0;
02574        pSge->nViewPage         = 0;
02575        ScrollViewCandiPage(&(pSge->scSysCandi), &(pSge->ucUdcCandi), pSge);
02576 
02577        if (pSge->nViewCandiStart == 0)
02578               pSge->nIconFlag &= (~F_PREVPAGE);
02579        else
02580               pSge->nIconFlag |= F_PREVPAGE;
02581 
02582        nTmp  = pSge->scSysCandi.nNumMhCandi   + pSge->scSysCandi.nNumDhCandi  +
02583                pSge->scSysCandi.nNumShCandi   + 
02584                pSge->ucUdcCandi.nNumSpecCandi + pSge->ucUdcCandi.nNumUdc28Candi;
02585        if(pSge->nGBKMode == GBK_SUPPORTED) nTmp += pSge->scSysCandi.nNumGbkCandi;
02586        if (pSge->nViewCandiEnd < nTmp)
02587               pSge->nIconFlag |= F_NEXTPAGE;
02588        else
02589               pSge->nIconFlag &= (~F_NEXTPAGE);
02590        
02591        return TRUE;
02592 }
02593 
02594 
02595 VOID ProcSymbIMKey(SesGuiElement* pSge, JINT nSymbType, JINT *pNextKeysym, ImToXSun *pIeh)
02596 {
02597        JWORD  wThisSel[9];
02598        JINT   i, nCurCandiNum, nChoiceMark, nXrd, nLenThisSel;
02599        
02600        GetIehFromSge(pIeh, pSge);
02601        pIeh->nType = IMXSUN_TYPE_NORMAL;
02602        memset(pIeh->pwCommit, 0x00, UONE * sizeof(JWORD));
02603        
02604        if ((nSymbType != pSge->nKeyLayMode) || (pSge->nKeyLayMode != pSge->nPrevKeyLayMode))
02605        {
02606               PrepareSymbolSge(pSge, nSymbType);
02607               GetIehFromSge(pIeh, pSge);
02608               
02609               pIeh->nType = IMXSUN_TYPE_NORMAL;
02610               pSge->nKeyLayMode     = nSymbType;
02611               pSge->nPrevKeyLayMode = pSge->nKeyLayMode;
02612        }
02613        
02614        if (IsPageKeysym(pNextKeysym) == TRUE)
02615        {
02616               OnPageKeysym(pNextKeysym, pSge);
02617               GetIehFromSge(pIeh, pSge);
02618               pIeh->nType = IMXSUN_TYPE_NORMAL;
02619        }
02620        else if (IsSelectKeysym(pNextKeysym) == TRUE)
02621        {
02622               nCurCandiNum = pSge->nViewCandiEnd - pSge->nViewCandiStart;
02623               if (pNextKeysym[0] == IMXK_space)
02624                      pNextKeysym[0] = IMXK_1;
02625                      
02626               if ((pNextKeysym[0] > IMXK_0) && (pNextKeysym[0] <= (IMXK_0 + nCurCandiNum)))
02627               {
02628                      memset(wThisSel, 0x00, 9 * 2);
02629                      nChoiceMark     = pNextKeysym[0] - IMXK_0;
02630                      nXrd            = pSge->nViewCandiStart + nChoiceMark - 1;
02631                      nLenThisSel     = GetXrdCandi(&(pSge->scSysCandi), &(pSge->ucUdcCandi), nXrd, wThisSel, pSge->nGBKMode);
02632                      memset(pIeh->pwCommit, 0x00, 256 * 2);
02633                      assert(nLenThisSel == 1);
02634                      GetIehFromSge(pIeh, pSge);
02635                      for (i = 0; i < nLenThisSel; i++)
02636                             pIeh->pwCommit[i] = wThisSel[i];
02637                      pIeh->nType = IMXSUN_TYPE_COMMITSYMBOL;
02638               }
02639               else
02640               {
02641                      NULL;
02642 #ifdef _DRAW_IM_WIN_H
02643                      XBell (pDspIme, 100);
02644 #endif
02645               }
02646        }
02647        else if ( (IsPageKeysym(pNextKeysym) != TRUE) || (IsSelectKeysym(pNextKeysym) != TRUE) )
02648        {
02649               NULL;
02650 #ifdef _DRAW_IM_WIN_H
02651               XBell (pDspIme, 100);
02652 #endif
02653        }
02654        return;
02655 }
02656 
02657