Back to index

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