Back to index

im-sdk  12.3.91
NewPY.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 #ifdef HAVE_CONFIG_H
00044 #include "config.h"
00045 #endif
00046 
00047 #include "PYIM.h"
00048 #include <assert.h>
00049 #include <sys/utsname.h>
00050 
00051 SesGuiElement* pSge[512];
00052 SesGuiElement* pCurSge;
00053 
00054 JINT GetNextLine(FILE* pfFile, CHAR* szBuf);
00055 JINT GetDefaultSpMode();
00056 
00057 ImToXSun*  NewPY_trans(JINT nSesID, JINT nXKey, JINT nAsciiKey, JINT nSpecKey);
00058 ImToXSunChar*  ConvImToXSun(ImToXSun* pIeh);
00059 ImToXSun*      ImTrans(JINT nSesID, JINT* pKsThis, JINT nSpecKeyState);
00060 VOID    JwordInfo(JWORD* pwJwordArray, JINT nMaxLen);
00061 VOID    Jword2Uchar(JWORD* pwJword, UCHAR* szUch, JINT nMaxLen);
00062 JINT    JwordValidLen(JWORD* pwJwordArray, JINT nMaxLen);
00063 VOID    ProcFreq(SesGuiElement* pSge);
00064 VOID    ProcUdCizu(SesGuiElement* pSge);
00065 VOID    IM_close(JINT nSesID);
00066 
00067 VOID    InitSge(SesGuiElement* pSgeStruct);
00068 VOID    IehReturn(ImToXSun* pieh, JINT nCaseFlag);
00069 JINT    IsQuitKeysym(JINT *pks);
00070 JINT    IsQpSpSwitchKeysym(JINT *pks);
00071 JINT    IsWantedKeysym(JINT *pks);
00072 JINT    IsPyKeysym(JINT *pks);
00073 JINT    IsPageKeysym(JINT *pks);
00074 JINT    IsSelectKeysym(JINT *pks);
00075 JWORD   GetQuanjiaoSymbol(JINT *pks, JINT IsChnPunc, JINT IsChnAscii);
00076 
00077 VOID    ProcAllKeysym(JINT* pKsThis, SesGuiElement* pSge);
00078 VOID    DrawImToXSun(ImToXSun* pIeh, SesGuiElement* pSge);
00079 VOID    GetIehFromSge(ImToXSun* pIeh, SesGuiElement* pSge);
00080 VOID    GetLookupChoiceFromCandi(ImToXSun* pIeh, JWORD* pwCandi);
00081 
00082 /* CikuOper.c */
00083 JINT    GetCikuData(CHAR* szSysCikuName);
00084 JINT    WriteCikuData(CHAR* szSysCikuName, JINT nTimeStamp);
00085 VOID    FreePckAll();
00086 VOID    InitStructSc(SysCandi* psc);
00087 VOID    AdjustFreq(JWORD* pwHz2244, JINT nLenThis);
00088 
00089 /* UdCikuOper.c */
00090 VOID   InitStructUc(UdcCandi* puc);
00091 JINT    ReadUdcData(CHAR* szUdcName);
00092 JINT    WriteUdcData(CHAR* szUdcName, JINT nTimeStamp);
00093 JINT    AddUdc(JWORD* pwHz2244, JINT nLen);
00094 JINT    DelUdc(JWORD* pwHz2244, JINT nLen);
00095 JINT    PureUdc(VOID);
00096 VOID    FreeUdcData();
00097 
00098 /* UDCOpen.c */
00099 VOID    GetUDCData();
00100 
00101 VOID    ProcSymbIMKey(SesGuiElement* pSge, JINT nSymbType, JINT *pNextKeysym, ImToXSun *pIeh);
00102 
00103 extern  BYTE      *pCkAll;      /* Defined in file "CikuOper.c" */
00104 extern  UdcMemAll  udcAll;      /* Defined in file "UdCikuOper.c" */
00105 
00106 #define PUNCTUATION_STATUS    1
00107 #define SOFTKEYBOARD_LAYOUT   2
00108 
00109 #define SKB_QUANPIN           0
00110 #define SKB_SPZRM             1
00111 #define SKB_SPCSTAR           2
00112 #define SKB_SPABC             3
00113 
00114 #define  SKB_SYMBSCIENT     0
00115 #define  SKB_SERIESONE      1
00116 #define  SKB_SERIESTWO      2
00117 #define  SKB_SERIESTHREE    3
00118 #define  SKB_SERIESFOUR     4
00119 #define  SKB_GREECE         5
00120 #define  SKB_RUSSIAN        6
00121 #define  SKB_PYSYM          7
00122 #define  SKB_JAPPIN         8
00123 #define  SKB_JAPPIAN        9
00124 #define  SKB_TABSYMB        10
00125 #define  SKB_GBKEXTSYM1     11
00126 #define  SKB_GBKEXTSYM2     12
00127 #define  SKB_HALFWID        13
00128 #define  SKB_FULLWID        14
00129 
00130 #define  PUNCT_CHINESE      0
00131 #define  PUNCT_ENGLISH      1
00132 
00133 #define  CIKU_DATA_PATH     LE_IME_MODULES_DIR"/data"
00134 
00135 JINT      nGlobalSpMode;      /* ZRM, CStar, ABC */
00136 
00137 ImToXSunChar* Aux_SetPuncSkb(JINT nSesID, JINT nWhichBmp, JINT nBmpValue)
00138 {
00139        JINT    nTmp;
00140        ImToXSunChar*   pImxsun;
00141        ImToXSun *pIeh;
00142        JINT    nPunctMode;
00143        
00144        if (pSge[nSesID] == NULL)
00145        {
00146               printf("Invalid nSesID in Aux_SetPuncSkb().\n");
00147               return NULL;
00148        }
00149        
00150        if ((nWhichBmp == PUNCTUATION_STATUS) && (nBmpValue >= 0) && (nBmpValue <= 1))
00151               nPunctMode = pSge[nSesID]->nPunctMode  = nBmpValue;
00152        else if ((nWhichBmp == SOFTKEYBOARD_LAYOUT) && (nBmpValue >= 0) && (nBmpValue <= 14))
00153        {
00154               nPunctMode = pSge[nSesID]->nPunctMode;
00155               if ((nBmpValue == 13) || (nBmpValue == 14))
00156               {
00157                      nTmp = pSge[nSesID]->nPunctMode;
00158                      InitSge(pSge[nSesID]);
00159                      pSge[nSesID]->nPunctMode = nTmp;
00160               }
00161               pSge[nSesID]->nKeyLayMode = nBmpValue;
00162        }
00163        else
00164               printf("Invalid nWhichBmp[%d] or nBmpValue[%d]\n", nWhichBmp, nBmpValue);
00165        
00166        pIeh = NewPY_trans (nSesID, (JINT)IMXK_Clear, (JINT)IMXK_Clear, 0);
00167        pImxsun = ConvImToXSun(pIeh);
00168        pSge[nSesID]->nPunctMode = nPunctMode;
00169        return (pImxsun);
00170 }
00171 
00172 
00173 VOID NewPY_close (JINT nSesID)
00174 {
00175        NewPY_trans (nSesID, (JINT)IMXK_QUIT_PYIM, (JINT)IMXK_QUIT_PYIM, 0);
00176 }
00177 
00178 ImToXSun* NewPY_open(JINT nSesID)
00179 {
00180        static JINT    nCheckSpMode = FALSE;
00181        
00182 #ifdef NEWPY_GB
00183        nGBKMode = FALSE;
00184        strcpy(szLocale, "GB");
00185 #else
00186        nGBKMode = TRUE;
00187        strcpy(szLocale, "GBK");
00188 #endif
00189 #ifdef CompByNewPinyin
00190        nGlobalSpMode = KEYLAYMODE_NEWPY;
00191 #else
00192        nGlobalSpMode = KEYLAYMODE_ZRM;
00193 #endif
00194 #if 0
00195 #ifdef CompByNewPinyin
00196        GetDefaultSpMode();
00197        nGlobalSpMode = KEYLAYMODE_NEWPY;
00198 #else
00199        nGlobalSpMode = KEYLAYMODE_NEWPY;
00200        if (nCheckSpMode == FALSE)
00201        {
00202               nGlobalSpMode = GetDefaultSpMode();
00203               nCheckSpMode = TRUE;
00204        }
00205 #endif
00206 #endif
00207 
00208 /*
00209        return(NewPY_trans (nSesID, (JINT)IMXK_Clear, (JINT)IMXK_Clear, 0));
00210 */
00211 
00212        /* read udc data from /var/tmp/newpyudc.txt */
00213        GetUDCData();
00214        return(NewPY_trans (nSesID, (JINT)IMXK_Escape, (JINT)IMXK_Escape, 0));
00215 }
00216 
00217 ImToXSun* NewPY_trans(JINT nSesID, JINT nXKey, JINT nAsciiKey, JINT nSpecKeyState)
00218 {
00219        JINT    i;
00220        JINT    ksThis[5];
00221        JINT    nSpecKey;
00222        
00223        for(i = 0; i < 5; i++)
00224               ksThis[i] = 0x00000000;
00225        if ((nAsciiKey >= 0x20) && (nAsciiKey <= 0x7E))
00226               ksThis[0] = nAsciiKey;
00227        else
00228               ksThis[0] = nXKey;
00229        
00230        /* PATCH for ^p and ^n: Scott Ma: 98-04-28 */
00231        nSpecKey = nSpecKeyState;
00232        if ((nAsciiKey == IMXK_N) && (nSpecKeyState == 5))
00233        {
00234               ksThis[0] = (JINT)IMXK_MOUSENEXT;
00235               nSpecKey  = 0;
00236        }
00237        if ((nAsciiKey == IMXK_P) && (nSpecKeyState == 5))
00238        {
00239               ksThis[0] = (JINT)IMXK_MOUSEPREV;
00240               nSpecKey  = 0;
00241        }
00242        
00243        bShiftIsPressed  = (JSHORT)((nSpecKey & SPEC_KEY_SHIFT)    / SPEC_KEY_SHIFT);
00244        bCapsIsPressed   = (JSHORT)((nSpecKey & SPEC_KEY_CAPSLOCK) / SPEC_KEY_CAPSLOCK); /* ??? Not Certain. MXL */
00245        bCapsIsPressed   = (JSHORT)0;
00246        bCtrlIsPressed   = (JSHORT)((nSpecKey & SPEC_KEY_CONTROL)  / SPEC_KEY_CONTROL);
00247        bAltIsPressed    = (JSHORT)((nSpecKey & SPEC_KEY_ALT)      / SPEC_KEY_ALT);
00248        bAltGrIsPressed  = (JSHORT)((nSpecKey & SPEC_KEY_ALTGRAPH) / SPEC_KEY_ALTGRAPH);
00249        bCompIsPressed   = (JSHORT)((nSpecKey & SPEC_KEY_COMPOSE)  / SPEC_KEY_COMPOSE);  /* ??? Not Certain. MXL */
00250        bCompIsPressed   = (JSHORT)0;
00251        bMetaIsPressed   = (JSHORT)((nSpecKey & SPEC_KEY_DIAMOND)  / SPEC_KEY_DIAMOND);
00252 
00253        return ( ImTrans(nSesID, ksThis, nSpecKey) );
00254 }
00255 
00256 
00257 ImToXSun* ImTrans(JINT nSesID, JINT* pKsThis, JINT nSpecKeyState)
00258 {
00259        JINT    i, nLen, nTmpRes, nTmp1, nTmp2;
00260        static  ImToXSun ieh;
00261        static  JINT     nActiveSesNum = 0;
00262        static  JINT     pnSesIDArray[512];
00263        CHAR*   pszHome;
00264        CHAR    szPath[128];
00265 #if 0
00266        struct utsname  unstr, *un;
00267 #else
00268        int    endian;
00269 #endif
00270        
00271        JWORD   wPuncAscii;      /* For Chinese Punctation and Alpha Char */
00272        JINT    FlagChnPunc, FlagChnAscii;
00273 
00274        /* since iiim sets conversion off at first to get the status string,
00275           but this cause some error in newpy. So return a special struct in 
00276           this case. 
00277        */
00278 
00279        if((nActiveSesNum == 0) && IsQuitKeysym(pKsThis)) {
00280               IehReturn(&ieh, QUIT_THIS_IM);
00281               return (&ieh);
00282        }
00283 
00284        /* 
00285        ** 在正式版本中, 应该先读szSysCikuBak & szUdcCikuBak, 
00286        ** 如果失败, 再读szSysCiku & szUdcCiku!!      MXL 97-12-14
00287        */
00288        if (pCkAll == NULL)
00289        {
00290 #if 0
00291               un = &unstr;
00292               (void) uname(un);
00293               if(strcmp(un->machine,"i86pc") ==0)
00294                      nArch=TRUE;
00295               else nArch=FALSE;
00296 #else
00297               endian = 1;
00298               if (*(char *)&endian)
00299                      nArch = TRUE;
00300               else
00301                      nArch = FALSE;
00302 #endif
00303 
00304               sprintf(szPath, "%s/%s", CIKU_DATA_PATH, szSysCiku);
00305               DEBUG_printf("system data path:%s\n", szPath);
00306               nTmpRes = GetCikuData(szPath);
00307               if (nTmpRes == FALSE)
00308               {
00309                      fprintf (stderr, "IME Error: Failed to Open System Ciku < PyCiku.dat >\n");
00310                      return(NULL);
00311               }
00312 
00313               sprintf(szPath, "%s/%s", CIKU_DATA_PATH, szUdcCiku);
00314               DEBUG_printf("User data path:%s\n", szPath);
00315 
00316               /* Read in UdCiku.dat Data */
00317               nTmpRes = ReadUdcData(szPath);
00318               if (nTmpRes == FALSE)
00319               {
00320                      fprintf (stderr, "IME Error: Failed to Open User Defined Ciku < UdCiku.dat >\n");
00321                      return(NULL);
00322               }
00323        }
00324 
00325        if (nActiveSesNum == 0)
00326        {
00327               for (i = 0; i < MAX_SES_NUM; i++)
00328                      pnSesIDArray[i] = 0x0000;
00329        }
00330        
00331        if (pnSesIDArray[nSesID] == 0x0000)       /* New Session */
00332               nActiveSesNum++;
00333        
00334        if (nActiveSesNum > MAX_SES_NUM)   /* Return: Too many sessions */
00335        {
00336               nActiveSesNum--;
00337               IehReturn(&ieh, TOO_MANY_SESSION);
00338               return (&ieh);
00339        }
00340 
00341        if (pnSesIDArray[nSesID] == 0x0000)       /* New Session */
00342        {
00343               pnSesIDArray[nSesID] = (0xF000 + nSesID);
00344               pSge[nSesID] = (SesGuiElement*) malloc(sizeof(SesGuiElement));
00345               if (pSge[nSesID] == NULL)
00346               {
00347                      IehReturn(&ieh, FAILED_ALLOC_MEM);    /* Failed to Alloc Memory */
00348                      pnSesIDArray[nSesID] = 0x0000;
00349                      nActiveSesNum--;
00350                      return (&ieh);
00351               }
00352               pSge[nSesID]->scSysCandi.pwMhCandi  = NULL;
00353               pSge[nSesID]->scSysCandi.pwDhCandi  = NULL;
00354               pSge[nSesID]->scSysCandi.pwShCandi  = NULL;
00355               pSge[nSesID]->scSysCandi.pwGbkCandi = NULL;
00356               pSge[nSesID]->ucUdcCandi.pwUdc28Candi = NULL;
00357               InitSge(pSge[nSesID]);
00358        }
00359        pCurSge = pSge[nSesID];
00360        
00361        if (IsQuitKeysym(pKsThis))
00362        {
00363               /* Free Space Occupied by struct SysCandi */
00364               free (pSge[nSesID]->scSysCandi.pwMhCandi);
00365               free (pSge[nSesID]->scSysCandi.pwDhCandi);
00366               free (pSge[nSesID]->scSysCandi.pwShCandi);
00367               free (pSge[nSesID]->scSysCandi.pwGbkCandi);
00368               free (pSge[nSesID]->ucUdcCandi.pwUdc28Candi);
00369 
00370               pSge[nSesID]->scSysCandi.pwMhCandi  = NULL;
00371               pSge[nSesID]->scSysCandi.pwDhCandi  = NULL;
00372               pSge[nSesID]->scSysCandi.pwShCandi  = NULL;
00373               pSge[nSesID]->scSysCandi.pwGbkCandi = NULL;
00374               pSge[nSesID]->ucUdcCandi.pwUdc28Candi = NULL;
00375               
00376               free (pSge[nSesID]);
00377               pSge[nSesID] = NULL;
00378               pnSesIDArray[nSesID] = 0x0000;
00379               nActiveSesNum--;
00380               IehReturn(&ieh, QUIT_THIS_IM);     /* Application Quit or Switch to other IM */
00381               
00382               /*
00383               **  If nActiveSesNum == 0, means No any Application is still using this IM, SO,
00384               **  Must Write these Adjuested Ciku Data back to File!!!!
00385               */
00386               if(nActiveSesNum == 0)
00387               {
00388 #if 0
00389                      pszHome = getenv("HOME");
00390                      nLen    = strlen(pszHome);
00391                      
00392                      memset (szPath, '\0', 128);
00393                      strcat (szPath, pszHome);
00394                      if (szPath[nLen - 1] == '/')
00395                             szPath[nLen - 1] = '\0';
00396                      strcat (szPath, szSysCikuBak);
00397               
00398                      WriteCikuData(szPath, 0);
00399 #endif
00400                      FreePckAll();
00401                      pCkAll = NULL;
00402 
00403 #if 0
00404                      memset (szPath, '\0', 128);
00405                      strcat (szPath, pszHome);
00406                      if (szPath[nLen - 1] == '/')
00407                             szPath[nLen - 1] = '\0';
00408                      strcat (szPath, szUdcCikuBak);
00409                      
00410                      WriteUdcData (szPath, 0);
00411 #endif
00412                      FreeUdcData();
00413               }
00414               return (&ieh);
00415        }
00416        
00417        else if (IsQpSpSwitchKeysym(pKsThis))
00418        {
00419               nQpSpFlag[nSesID] = 1 - nQpSpFlag[nSesID];
00420               IehReturn(&ieh, SWITCH_BEWTEEN_QPSP);     /* Application Quit or Switch to other IM */
00421               
00422               /* Initialize pSge[nSesID] */
00423               InitSge(pSge[nSesID]);
00424               return (&ieh);
00425        }
00426        
00427        else if (IsWantedKeysym(pKsThis))
00428        {
00429               if ((pCurSge->nKeyLayMode >= 0) && (pCurSge->nKeyLayMode <= 12))
00430               {
00431                      ProcSymbIMKey(pCurSge, pCurSge->nKeyLayMode, pKsThis, &ieh);
00432 #ifdef _DRAW_IM_WIN_H
00433                      DrawImToXSun(&ieh, pCurSge);
00434                      if (ieh.nType == IMXSUN_TYPE_COMMITSYMBOL)
00435                             JwordInfo(ieh.pwCommit, 256);
00436 #endif
00437                      return (&ieh);
00438               }
00439               
00440               /*
00441               **  Determine if this keySym is really valid for current pSge enviroment (GUI Logic).
00442               **  If NO, return!!
00443               **  Some KeySyms that is not useful during PYIM's Input GUI Logic,
00444               **       although that is defined in IsWantedkeysym().
00445               **       IMXSUN_TYPE_BOUNCEKEY 0x0002 was defined in file CmSo.h
00446               */
00447               
00448               /* NULL in preedit line, enter symbol now */
00449               if ( (JwordValidLen(pCurSge->pwMixPeStr, UONE) == 0)  && 
00450                      ((pCurSge->nKeyLayMode == SKB_HALFWID) || (pCurSge->nKeyLayMode == SKB_FULLWID)) &&
00451                      (((pKsThis[0] >= 0x20) && (pKsThis[0] <= 0x7E)) || (pKsThis[0] == IMXK_Clear)) )
00452               {
00453                      if (pKsThis[0] == IMXK_Clear)                    
00454                      {
00455                             nTmp1 = pCurSge->nPunctMode;
00456                             nTmp2 = pCurSge->nKeyLayMode;
00457                             InitSge(pCurSge);
00458                             pCurSge->nPunctMode  = nTmp1;
00459                             pCurSge->nKeyLayMode = nTmp2;
00460                             
00461                             pCurSge->nPrevKeyLayMode = pCurSge->nKeyLayMode;
00462 
00463                             memset(&ieh, 0x00, sizeof(ImToXSun));
00464                             ieh.nType = IMXSUN_TYPE_NORMAL;
00465 #ifdef _DRAW_IM_WIN_H
00466                             DrawImToXSun(&ieh, pCurSge);
00467 #endif
00468                             return (&ieh);
00469                      }
00470                             
00471                      pCurSge->nPrevKeyLayMode = pCurSge->nKeyLayMode;
00472                      if (pCurSge->nPunctMode == PUNCT_CHINESE)
00473                             FlagChnPunc = TRUE;
00474                      else 
00475                             FlagChnPunc = FALSE;
00476                             
00477                      if (pCurSge->nKeyLayMode == SKB_FULLWID)
00478                             FlagChnAscii = TRUE;
00479                      else
00480                             FlagChnAscii = FALSE;
00481 
00482                      wPuncAscii = GetQuanjiaoSymbol(pKsThis, FlagChnPunc, FlagChnAscii);
00483                      if (wPuncAscii != 0x0000)
00484                      {
00485                             ieh.nType = IMXSUN_TYPE_COMMIT;
00486                             memset(ieh.pwCommit, 0x00, sizeof(JWORD) * UONE);
00487                             ieh.pwCommit[0] = wPuncAscii;
00488 #ifdef _DRAW_IM_WIN_H
00489                             JwordInfo(ieh.pwCommit, 256);
00490 #endif
00491                             return (&ieh);
00492                      }
00493               }
00494               
00495 #ifndef _DRAW_IM_WIN_H
00496               if(   bCapsIsPressed  || bCtrlIsPressed || bAltIsPressed  ||
00497                     bAltGrIsPressed || bCompIsPressed || bMetaIsPressed || 
00498                   ( (JwordValidLen(pCurSge->pwMixPeStr, UONE) == 0) && 
00499                     ( (IsPageKeysym(pKsThis)) || (IsSelectKeysym(pKsThis)) || (!IsPyKeysym(pKsThis)) )
00500                   )
00501                 )
00502               {
00503                      ieh.nType = IMXSUN_TYPE_BOUNCEKEY;
00504                      return (&ieh);
00505               }
00506 #endif
00507               
00508               pCurSge->nErrorCode = 0;                /* Clear All Error Message before a KeySym */
00509               ieh.nType   = IMXSUN_TYPE_NORMAL;
00510               for(i = 0; i < UONE; i++)
00511                      pCurSge->pwCommit[i] = ieh.pwCommit[i] = 0x0000;
00512               
00513               ProcAllKeysym(pKsThis, pCurSge);
00514               
00515               /*
00516               **  Determine if there is any other English chars in the end of pwMixPeStr[256].
00517               **  If there is no char lefted, indicates all is committed, pass it to IMToXSun,
00518               **  and InitSge(pCurSge) again. 
00519               **
00520               **  If pwMixPeStr[nLen - 1] is ['], How to deal it???
00521               **
00522               **  To create User defined Cizu HERE!!! Only after a committment.   97.11.08 MXL
00523               */
00524               nLen = JwordValidLen(pCurSge->pwMixPeStr, 256);
00525               if (pCurSge->pwMixPeStr[nLen - 1] >= 0x8140)      /* First Char defined in GBK */
00526               {
00527                      for (i = 0; i < UONE; i++)
00528                             pCurSge->pwCommit[i] = ieh.pwCommit[i] = 0x0000;
00529                      for (i = 0; i < nLen; i++)
00530                      {
00531                             /*
00532                             ** The following line was commented ONLY Because For SUN's HTT!!
00533                             pCurSge->pwCommit[i] = pCurSge->pwMixPeStr[i];
00534                             */
00535                             ieh.pwCommit[i] = pCurSge->pwMixPeStr[i];
00536                      }
00537                      ieh.nType = IMXSUN_TYPE_COMMIT;
00538                      ProcFreq(pCurSge);
00539                      ProcUdCizu(pCurSge);
00540                      
00541                      nTmp1 = pCurSge->nPunctMode;
00542                      InitSge(pCurSge);
00543                      pCurSge->nPunctMode = nTmp1;
00544                      GetIehFromSge(&ieh, pCurSge);
00545                      
00546 #ifdef _DRAW_IM_WIN_H
00547                      DrawImToXSun(&ieh, pCurSge);
00548                      JwordInfo(ieh.pwCommit, 256);
00549                      
00550                      /* Write Ciku File After each Committment */
00551                      pszHome = getenv("HOME");
00552                      nLen    = strlen(pszHome);
00553                      
00554                      memset (szPath, '\0', 128);
00555                      strcat (szPath, pszHome);
00556                      if (szPath[nLen - 1] == '/')
00557                             szPath[nLen - 1] = '\0';
00558                      strcat (szPath, szSysCikuBak);
00559               
00560                      WriteCikuData(szPath, 0);
00561 
00562                      memset (szPath, '\0', 128);
00563                      strcat (szPath, pszHome);
00564                      if (szPath[nLen - 1] == '/')
00565                             szPath[nLen - 1] = '\0';
00566                      strcat (szPath, szUdcCikuBak);
00567                      
00568                      WriteUdcData (szPath, 0);
00569 #endif
00570               }
00571               else
00572               {
00573                      GetIehFromSge(&ieh, pCurSge);
00574                      
00575 #ifdef _DRAW_IM_WIN_H
00576                      DrawImToXSun(&ieh, pCurSge);
00577 #endif
00578               }
00579               return (&ieh);
00580        }
00581        
00582        /*
00583        **  Bounce Other KeySym which is not in the range of above wanted key.
00584        */
00585        else
00586        {
00587               ieh.nType = IMXSUN_TYPE_BOUNCEKEY;  /* In CmSo.h:  IMXSUN_TYPE_BOUNCEKEY 0x0002 */
00588               return (&ieh);
00589        }
00590 }
00591 
00592 
00593 /*
00594 **  Process Specific case.  *** This Function is to be rearranged Later.
00595 */
00596 VOID IehReturn (ImToXSun* pIeh, JINT nCaseFlag)
00597 {
00598        JINT   i, j;
00599        
00600        pIeh->nType      = IMXSUN_TYPE_ERROR;
00601        pIeh->nErrorCode = nCaseFlag;
00602 
00603        if (nCaseFlag == SWITCH_BEWTEEN_QPSP)
00604               pIeh->nCaretPos = 0;
00605        else
00606               pIeh->nCaretPos = -1;
00607 
00608        for (i = 0; i < 128; i++)
00609               pIeh->pwPreedit[i] = 0x0000;
00610        for (i = 0; i < 8; i++)
00611               for (j = 0; j < 24; j++)
00612                      pIeh->pwLookupChoice[i][j] = 0x0000;
00613        pIeh->nChoiceNum  = 0;
00614 }
00615 
00616 
00617 /*
00618 **  Initialize / Reset / Clear SesGuiElement Structure.
00619 */
00620 VOID InitSge(SesGuiElement* pSgeStruct)
00621 {
00622        JINT    i;
00623        
00624        pSgeStruct->nSpRawCaretPos    = 0;
00625 
00626        for (i = 0; i < 40; i++)
00627               pSgeStruct->pwSpRawPyStr[i]  = 0x0000;
00628        for (i = 0; i < UONE; i++)
00629               pSgeStruct->pwSpMixPeStr[i]  = 0x0000;
00630        for (i = 0; i < UTWO; i++)
00631               pSgeStruct->pwSpSlctRawPy[i] = 0x0000;
00632        
00633        for (i = 0; i < UONE; i++)
00634        {
00635               pSgeStruct->pwRawPyStr[i]    = 0x0000;
00636               pSgeStruct->pwMixPeStr[i]    = 0x0000;
00637               pSgeStruct->nPrsPyYjCode[i]  = 0;
00638               pSgeStruct->pwCommit[i]      = 0x0000;
00639        }
00640        
00641        for (i = 0; i < UTWO; i++)
00642        {
00643               pSgeStruct->pwPrsPyStr[i]    = 0x0000;
00644               pSgeStruct->pwPrsMixStr[i]   = 0x0000;
00645               pSgeStruct->pwSlctHz[i]      = 0x0000;
00646               pSgeStruct->pwSlctRawPy[i]   = 0x0000;
00647        }
00648        
00649        for (i = 0; i < UHLF; i++)
00650        {
00651               pSgeStruct->pwViewPe[i]      = 0x0000;
00652               pSgeStruct->pwViewCandi[i]   = 0x0000;
00653        }
00654        
00655        pSgeStruct->nPinyinType       = -1;
00656        pSgeStruct->nPrevKeyLayMode   = 13;
00657        pSgeStruct->nKeyLayMode       = 13;    /* SKB_HALFWID: 13 */
00658        pSgeStruct->nPunctMode        = 0;    /* PUNCT_CHINESE: 0 */
00659        
00660        pSgeStruct->nRawCaretPos      = 0;
00661        pSgeStruct->nViewCaretPos     = 0;
00662        pSgeStruct->nViewPage         = 0;
00663        pSgeStruct->nViewPeStart      = 0;
00664        pSgeStruct->nViewPeEnd        = 0;
00665        pSgeStruct->nViewCandiStart   = 0;
00666        pSgeStruct->nViewCandiEnd     = 0;
00667        pSgeStruct->nSlctSteps        = 0;
00668 
00669        for (i = 0; i < 16; i++)
00670               pSgeStruct->pwStatus[i]   = 0x0000;
00671        pSgeStruct->nErrorCode        = 0;
00672 
00673        pSgeStruct->nIconFlag = F_HALFWIDTH | F_SETUP;
00674        
00675        InitStructSc(&(pSgeStruct->scSysCandi));
00676        InitStructUc(&(pSgeStruct->ucUdcCandi));
00677 
00678        /* The following 3 items were added to Fix Bug 4165549: Scott Ma, 12/8, 1998 */
00679        pSgeStruct->nPrevMatchMode       = -1;
00680        for (i = 0; i < 9; i++)
00681        {
00682               pSgeStruct->pnCurChoiceYjNew[i] = 1;
00683               pSgeStruct->pnCurChoiceYjOld[i] = 0;
00684        }
00685 }
00686 
00687 
00688 /*
00689 **  Get these Common Part of struct Ieh from struct Sge.
00690 **  Notes that these different part is not filled in this function.
00691 **  Include:   i)   nType          ii)    szCommittString
00692 **             iii) szBounceKey    iv)    Error Code
00693 */
00694 VOID GetIehFromSge(ImToXSun* pIeh, SesGuiElement* pSge)
00695 {
00696        JINT   i, j;
00697        
00698        for (i = 0; i < 128; i++)
00699               pIeh->pwPreedit[i] = pSge->pwViewPe[i];
00700               
00701        pIeh->nCaretPos  = pSge->nViewCaretPos;
00702        
00703        pIeh->nChoiceNum = pSge->nViewCandiEnd - pSge->nViewCandiStart;
00704        for (i = 0; i < 8; i++)
00705               for (j = 0; j < 24; j++)
00706                      pIeh->pwLookupChoice[i][j] = 0x0000;
00707        
00708        GetLookupChoiceFromCandi(pIeh, pSge->pwViewCandi);
00709        
00710        for (i = 0; i < 16; i++)
00711               pIeh->pwStatus[i] = pSge->pwStatus[i];
00712        
00713        /* Because nErrorCode was cleared before each new KeySym Process */
00714        if (pSge->nErrorCode != 0)
00715        {
00716               pIeh->nType = IMXSUN_TYPE_ERROR;
00717               pIeh->nErrorCode = pSge->nErrorCode;
00718        }
00719 }
00720 
00721 
00722 VOID GetLookupChoiceFromCandi(ImToXSun* pIeh, JWORD* pwCandi)
00723 {
00724        JINT    i, j, k, nLen;
00725        JINT    nbStartCandi;
00726        
00727        nLen = JwordValidLen(pwCandi, 128);
00728        
00729        i = j = k = nbStartCandi = 0;
00730        for (i = 0; i < nLen; i++)
00731        {
00732               if (pwCandi[i] >= 0x8140)   /* First Hanzi in GBK */
00733               {
00734                      nbStartCandi = 1;
00735                      pIeh->pwLookupChoice[j][k++] = pwCandi[i];
00736                      while(pwCandi[++i] >= 0x8140)
00737                             pIeh->pwLookupChoice[j][k++] = pwCandi[i];
00738                      j++;
00739                      k = 0;
00740                      nbStartCandi = 0;
00741               }
00742        }
00743        pIeh->nChoiceNum = j;
00744 }
00745 
00746 
00747 /*
00748 **  Convert from Struct ImToXSun to Struct ImToXSunChar
00749 */
00750 ImToXSunChar* ConvImToXSun(ImToXSun* pIeh)
00751 {
00752        JINT   i, j, nHz;
00753        JINT   nNumDollar;   /* Number of Numsign and Dollar before Caret */
00754        static ImToXSunChar  iehc;
00755        
00756        for (i = 0; i < 256; i++)
00757               iehc.szPreedit[i]   = '\0';
00758               
00759        for (i = 0; i < 10; i++)
00760               for (j = 0; j < 48; j++)
00761                      iehc.szLookupChoice[i][j] = '\0';
00762                      
00763        for (i = 0; i < 512; i++)
00764               iehc.szCommit[i]    = '\0';
00765               
00766        for (i = 0; i < 32; i++)
00767               iehc.szStatus[i]    = '\0';
00768               
00769        /* One Hanzi is  2 Bytes */
00770        nHz = 0;
00771        for (i = 0; (pIeh->pwPreedit[i] >= 0x8140); i++)
00772               nHz++;
00773               
00774        iehc.nType        = pIeh->nType;
00775        iehc.nErrorCode   = pIeh->nErrorCode;
00776        iehc.nChoiceNum   = pIeh->nChoiceNum;
00777        iehc.nLabelType   = LABELTYPE_1234567;
00778        
00779        nNumDollar = 0;
00780        j = 0;
00781        for (i = 0; pIeh->pwPreedit[i] != 0x0000; i++)
00782        {
00783               if ((pIeh->pwPreedit[i] != (JWORD)'#') && (pIeh->pwPreedit[i] != (JWORD)'$'))
00784               {
00785                      pIeh->pwPreedit[j++] = pIeh->pwPreedit[i];
00786               }
00787               else  /* '#' and '$' before pIeh->nCaretPos should be counted!! */
00788               {
00789                      if (i < pIeh->nCaretPos)
00790                             nNumDollar ++;
00791               }
00792        }
00793        for (; j < 128; j++)
00794               pIeh->pwPreedit[j++] = 0x0000;
00795        
00796        iehc.nCaretPos    = pIeh->nCaretPos + nHz - nNumDollar;
00797        
00798        Jword2Uchar(pIeh->pwPreedit, iehc.szPreedit, 128);
00799        Jword2Uchar(pIeh->pwCommit,  iehc.szCommit,  256);
00800        Jword2Uchar(pIeh->pwStatus,  iehc.szStatus,   16);
00801        
00802        for(i = 0; i < 8; i++)
00803               Jword2Uchar(pIeh->pwLookupChoice[i], iehc.szLookupChoice[i],  24);
00804        
00805        return (&iehc);
00806 }
00807 
00808 
00809 /* 
00810  *   Read From $HOME/.Xlocale/NewpyMode.txt 
00811  */
00812 JINT GetDefaultSpMode()
00813 {
00814        CHAR*   pszHome;
00815        CHAR   pszHomeTmp[128];
00816        CHAR    szPath[128];
00817        FILE   *fp;
00818        JINT    nTmp, nOff, nLen;
00819        CHAR    szLine[1024];
00820 
00821        char   szFileContent[] = 
00822        "#\n#  Notes: Lines start with '#' are comments.\n#\n#  Set ShuangPinYin Keyboard Layout Mode of <新双拼> input methods.\n#\n#  SpKeyboardLayout    ZiRanMaMode \n#  SpKeyboardLayout    CStarMode\n#  SpKeyboardLayout    IntelligentABCMode\n#\n\nSpKeyboardLayout    ZiRanMaMode\n\n";
00823 
00824 /*
00825        pszLocale = setlocale(LC_CTYPE, "");
00826        strcpy (szLocale, pszLocale);     
00827 */
00828               
00829        pszHome = getenv("HOME");
00830        if(!pszHome) return KEYLAYMODE_ZRM;
00831 
00832        strcpy(pszHomeTmp, pszHome);
00833 
00834        nLen    = strlen(pszHomeTmp);
00835        if(nLen == 0) return KEYLAYMODE_ZRM;
00836 
00837        if (pszHomeTmp[nLen - 1] == '/') pszHomeTmp[nLen - 1] = '\0';
00838               
00839        memset (szPath, '\0', 128);
00840        strcpy (szPath, pszHomeTmp);
00841        strcat(szPath, "/.Xlocale/ShuangPinType.txt");
00842        
00843        fp = fopen(szPath, "rb");
00844        if (fp == NULL)
00845        {
00846               strcpy (szPath, pszHomeTmp);
00847               strcat (szPath, "/.Xlocale");
00848               mkdir (szPath, 0755);
00849               
00850               strcpy (szPath, pszHomeTmp);
00851               strcat (szPath, "/.Xlocale/ShuangPinType.txt");
00852               
00853               fp = fopen(szPath, "wb");
00854               if (fp != NULL) {
00855                      fwrite(szFileContent, 1, strlen(szFileContent), fp);
00856                      fclose(fp);
00857               }
00858               
00859               return KEYLAYMODE_ZRM;
00860        }
00861        else
00862        {
00863               for (nTmp = 1; nTmp == 1; ) 
00864               {
00865                      memset(szLine, 0x00, 1024);
00866                      nTmp = GetNextLine(fp, szLine);
00867                      if (strncmp(szLine, "SpKeyboardLayout\0", strlen("SpKeyboardLayout\0")) == 0)
00868                      {
00869                             nOff = strlen("SpKeyboardLayout\0");
00870                             for(; (szLine[nOff] == 0x20) || (szLine[nOff] == 0x09); )
00871                                    nOff++;
00872                                    
00873                             if (strncmp(szLine + nOff, "ZiRanMaMode\0", strlen("ZiRanMaMode\0")) == 0)
00874                                    return KEYLAYMODE_ZRM;
00875                             
00876                             if (strncmp(szLine + nOff, "CStarMode\0", strlen("CStarMode\0")) == 0)
00877                                    return KEYLAYMODE_CSTAR;
00878 
00879                             if (strncmp(szLine + nOff, "IntelligentABCMode\0", strlen("IntelligentABCMode\0")) == 0)
00880                                    return KEYLAYMODE_ABC;
00881                      }
00882               }
00883        }
00884        
00885        return KEYLAYMODE_ZRM;
00886 }
00887 
00888 
00889 JINT GetNextLine(FILE* pfFile, CHAR* szBuf)
00890 {
00891        JINT    i = 0;
00892        
00893        do
00894        {
00895               fread (&szBuf[i], 1, 1, pfFile);
00896               i ++;
00897        } while (!feof(pfFile) && (szBuf[i-1] != 0x0A));
00898        
00899        szBuf[i-1] = '\0';
00900        if ((i >= 2) && (szBuf[i-2] == 0x0D))
00901               szBuf[i-2] = '\0';
00902        
00903        if (!feof(pfFile))
00904               return 1;
00905        else
00906               return 0;
00907 }