Back to index

im-sdk  12.3.91
zhuyin_filter.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include "ctim.h"
00003 #include "zhuyin_data.h"
00004 
00005 #define LOOKUP_CHOICE_NUM   6
00006 
00007 #define IME_Status          ime_buffer->return_status
00008 #define Input_Buf           ime_buffer->input_buf
00009 #define Input_Len           ime_buffer->input_len
00010 #define Preedit_Buf         ime_buffer->preedit_buf
00011 #define Preedit_Len         ime_buffer->preedit_len
00012 #define Preedit_CaretPos    ime_buffer->preedit_caretpos
00013 #define Commit_Buf          ime_buffer->commit_buf
00014 #define Commit_Len          ime_buffer->commit_len
00015 #define Status_Buf          ime_buffer->status_buf
00016 #define Status_Len          ime_buffer->status_len
00017 #define Lookups_Num         ime_buffer->num_candidates
00018 #define Lookup_Pos          ime_buffer->cur_lookup_pos
00019 #define Candidates          ime_buffer->candidates
00020 #define Comments            ime_buffer->comments
00021 #define Lookups                    ime_buffer->lookups
00022 #define Page_State          ime_buffer->page_state
00023 
00024 int Is_UsedCodes_Key(TZhuyinData *pZhuyinData, int key)
00025 {
00026        int nKeymap_ID = pZhuyinData->nCurrentKeymapID;
00027        return(ZhuyinKeymapList_Item_CheckIfValidKey(pZhuyinData->pZhuyinKeymapList, nKeymap_ID, key));
00028 }
00029 
00030 int Is_Zhuyin_Tone_Key(TZhuyinData *pZhuyinData, int key)
00031 {
00032        int nKeymap_ID = pZhuyinData->nCurrentKeymapID;
00033        int nKeyType = ZhuyinKeymapList_Item_KeyToType(pZhuyinData->pZhuyinKeymapList, nKeymap_ID, key);
00034        return(nKeyType == ZHUYIN_TYPE_TONE ? 1 : 0);
00035 }
00036 
00037 int get_select_num(TZhuyinData *pZhuyinData, int key)
00038 {
00039        CodeTableStruct *hztbl = pZhuyinData->pCodetableHeader;
00040        int ret = -1;
00041        switch(hztbl->nSelectKeyMode) {
00042               case NUMBER0_MODE:
00043                      if (key >= '0' && key <= '9')
00044                             ret = (key - '0') % 10;
00045                      break;
00046 
00047               case NUMBER_MODE:
00048                      if (key >= '1' && key <= '9')
00049                             ret = (key - '0' + 9) % 10;
00050                      break;
00051 
00052               case LOWER_MODE:
00053                      if (key >= 'a' && key <= 'a' + 10)
00054                             ret = key - 'a';
00055                      break;
00056 
00057               case UPPER_MODE:
00058                      if (key >= 'A' && key <= 'A' + 10)
00059                             ret = key - 'A';
00060                      break;
00061        }
00062        return(ret);
00063 }
00064 
00065 int Is_Select_Key(TZhuyinData *pZhuyinData, int key)
00066 {
00067        CodeTableStruct *hztbl = pZhuyinData->pCodetableHeader;
00068        int ret = get_select_num(pZhuyinData, key);
00069        if (ret == -1)
00070               return(0);
00071        else
00072               return(1);
00073 }
00074 
00075 int Is_Space_Key(TZhuyinData *pZhuyinData, int key)
00076 {
00077        if (key == IME_FILTERED_KEY_SPACEBAR)
00078               return(1);
00079        else
00080               return(0);
00081 }
00082 
00083 int Is_Return_Key(TZhuyinData *pZhuyinData, int key)
00084 {
00085        if (key == IME_FILTERED_KEY_ENTER)
00086               return(1);
00087        else
00088               return(0);
00089 }
00090 
00091 int Is_BackSpace_Key(TZhuyinData *pZhuyinData, int key)
00092 {
00093        CodeTableStruct *hztbl = pZhuyinData->pCodetableHeader;
00094        unsigned char *keylist = hztbl->functionkey[BACKSPACE_KEY_ID].keylist;
00095        int i;
00096 
00097        if (key == IME_FILTERED_KEY_BACKSPACE || key == IME_FILTERED_KEY_DELETE)
00098               return(1);
00099 
00100        if (keylist[0]) {
00101               for (i=0; i<MAX_FUNCTIONKEY_LEN; i++)
00102                      if (keylist[i] == key)
00103                             return(1);
00104        }
00105 
00106        return(0);
00107 }
00108 
00109 int Is_ClearAll_Key(TZhuyinData *pZhuyinData, int key)
00110 {
00111        CodeTableStruct *hztbl = pZhuyinData->pCodetableHeader;
00112        unsigned char *keylist = hztbl->functionkey[CLEARALL_KEY_ID].keylist;
00113        int i;
00114 
00115        if (key == IME_FILTERED_KEY_ESCAPE)
00116               return(1);
00117 
00118        if (keylist[0]) {
00119               for (i=0; i<MAX_FUNCTIONKEY_LEN; i++)
00120                      if (keylist[i] == key)
00121                             return(1);
00122        }
00123        return(0);
00124 }
00125 
00126 int Is_NextPage_Key(TZhuyinData *pZhuyinData, int key)
00127 {
00128        CodeTableStruct *hztbl = pZhuyinData->pCodetableHeader;
00129        unsigned char *keylist = hztbl->functionkey[PAGEDOWN_KEY_ID].keylist;
00130        int i;
00131 
00132        if (key == IME_FILTERED_KEY_PAGEDOWN)
00133               return(1);
00134 
00135        if (keylist[0]) {
00136               for (i=0; i<MAX_FUNCTIONKEY_LEN; i++)
00137                      if (keylist[i] == key)
00138                             return(1);
00139        }
00140        return(0);
00141 }
00142 
00143 int Is_PrevPage_Key(TZhuyinData *pZhuyinData, int key)
00144 {
00145        CodeTableStruct *hztbl = pZhuyinData->pCodetableHeader;
00146        unsigned char *keylist = hztbl->functionkey[PAGEUP_KEY_ID].keylist;
00147        int i;
00148 
00149        if (key == IME_FILTERED_KEY_PAGEUP)
00150               return(1);
00151        
00152        if (keylist[0]) {
00153               for (i=0; i<MAX_FUNCTIONKEY_LEN; i++)
00154                      if (keylist[i] == key)
00155                             return(1);
00156        }
00157        return(0);
00158 }
00159 
00160 int If_Has_WildChar(char *input_str)
00161 {
00162        char *p = input_str;
00163 
00164        while(*p) {
00165               if (*p == '?' || *p == '*')
00166                      return(1);
00167               p++;
00168        }
00169        return(0);
00170 }
00171 
00172 int get_lookup_result(CodeTableStruct *hztbl, ImeBufferRec *ime_buffer, 
00173 int nHelpInfoMode, int pos, int max_lookup_num)
00174 {
00175        int i, lookup_num;
00176 
00177        lookup_num = codetable_search(hztbl, Input_Buf, Candidates, Comments, pos, max_lookup_num + 1); 
00178        if (lookup_num > 0) {
00179               Page_State = 0;
00180               if (pos == 0)
00181                      Page_State |= ImeCandidatesFirstPage;
00182               if (lookup_num < max_lookup_num + 1)
00183                      Page_State |= ImeCandidatesLastPage;
00184               if (lookup_num == max_lookup_num + 1)
00185                      lookup_num = max_lookup_num;
00186 
00187               for (i=0; i<lookup_num; i++) {
00188                      if (nHelpInfoMode)
00189                             snprintf((char *)Lookups[i], MAX_CANDIDATE_CHAR_NUM, "%s %s",
00190                                     Candidates[i], Comments[i]);
00191                      else
00192                             strcpy(Lookups[i], Candidates[i]);
00193               }
00194        }
00195 
00196        return(lookup_num);
00197 }
00198 
00199 int Commit_And_Clean_All_Area(ImeBufferRec *ime_buffer)
00200 {
00201        Input_Len = 0;
00202        Preedit_Len = 0;
00203        Lookups_Num = 0;
00204        Preedit_CaretPos = 0;
00205        IME_Status = IME_COMMIT | IME_PREEDIT_AREA | IME_LOOKUP_AREA;
00206 }
00207 
00208 int Clean_All_Area(ImeBufferRec *ime_buffer)
00209 {
00210        Input_Len = 0;
00211        Preedit_Len = 0;
00212        Lookups_Num = 0;
00213        Preedit_CaretPos = 0;
00214        IME_Status = IME_PREEDIT_AREA | IME_LOOKUP_AREA;
00215 }
00216 
00217 int commit_candidate(ImeBufferRec *ime_buffer, int id)
00218 {
00219        if (id >= Lookups_Num)
00220               return(-1);
00221 
00222        strcpy((char *)Commit_Buf, (char *)Candidates[id]);
00223        Commit_Len = strlen((char *)Commit_Buf);
00224        Commit_And_Clean_All_Area(ime_buffer);
00225 
00226        return(0);
00227 }
00228 
00229 void warning_bell(ImeBufferRec *ime_buffer)
00230 {
00231        IME_Status |= IME_BEEP;
00232 }
00233 
00234 int zhuyin_inputbuf_to_preeditbuf(TZhuyinData *pZhuyinData, ImeBufferRec *ime_buffer)
00235 {
00236        int i, nKeyType;
00237        char tmp_buf[4];
00238        char *space_str = "  ";
00239        unsigned char *pSymbol, buffer[128];
00240        CodeTableStruct *hztbl = pZhuyinData->pCodetableHeader;
00241 
00242        memset(tmp_buf, 0, 4);
00243        for (i=0; i<Input_Len; i++) {
00244               if (i>=4) break;
00245               nKeyType = ZhuyinKeyToZhuyinType(Input_Buf[i]);
00246               if (nKeyType == ZHUYIN_TYPE_ERROR) continue;
00247 
00248               tmp_buf[nKeyType - 1] = Input_Buf[i];
00249        }
00250 
00251        Preedit_Len = 0;
00252        for (i=0; i<4; i++) {
00253               pSymbol = NULL;
00254               if (tmp_buf[i]) {
00255                      pSymbol = (unsigned char *)ZhuyinKeyToZhuyinSymbol(tmp_buf[i]);
00256                      if (pSymbol && hztbl->Encode != ENCODE_UTF8) {
00257                             char *ip, *op;
00258                             int ileft, oleft;
00259                             ip = (char *)pSymbol;
00260                             ileft = strlen(pSymbol);
00261                             op = (char *)buffer;
00262                             oleft = 128;
00263                             memset(buffer, 0, 128);
00264                             Convert_UTF8_To_Native(hztbl->Encode, ip, ileft, &op, &oleft);
00265                             pSymbol = buffer;
00266                      }
00267               }
00268               if(!pSymbol || !*pSymbol) pSymbol = (unsigned char *)space_str;
00269 
00270               strcpy(Preedit_Buf+Preedit_Len, pSymbol);
00271               Preedit_Len += strlen(pSymbol);
00272        }
00273        Preedit_Buf[Preedit_Len] = '\0';
00274        Preedit_CaretPos = Preedit_Len;
00275        return(0);
00276 }
00277 
00278 int zhuyin_add_key(TZhuyinData *pZhuyinData, ImeBufferRec *ime_buffer, int key)
00279 {
00280        char StandardKey;
00281        int nKeyType, nSKeyType, i, j;
00282        int nKeymap_ID = pZhuyinData->nCurrentKeymapID;
00283 
00284        StandardKey = ZhuyinKeymapList_Item_KeyToStandardKey(pZhuyinData->pZhuyinKeymapList, nKeymap_ID, key);
00285        if (StandardKey == 0) 
00286               return(-1);
00287 
00288        nSKeyType = ZhuyinKeyToZhuyinType(StandardKey);
00289        if (nSKeyType == ZHUYIN_TYPE_ERROR)
00290               return(-1);
00291 
00292        /* if is Tone 0 */
00293        if (StandardKey == ' ') StandardKey = '\0';
00294 
00295        for (i=0; i<Input_Len; i++) {
00296               if (i >= 4) break;
00297               nKeyType = ZhuyinKeyToZhuyinType(Input_Buf[i]);
00298               if (nKeyType == ZHUYIN_TYPE_ERROR)
00299                      return(-1);
00300 
00301               if (nSKeyType == nKeyType) {
00302                      /* replace the key */
00303                      Input_Buf[i] = StandardKey;
00304                      return(0);
00305               } else if (nSKeyType < nKeyType) {
00306                      /* insert the new key */
00307                      for (j=Input_Len; j>i; j--) {
00308                             Input_Buf[j] = Input_Buf[j-1];
00309                      }
00310                      Input_Buf[i] = StandardKey;
00311                      Input_Len++;
00312                      Input_Buf[Input_Len] = 0;
00313                      return(0);
00314               }
00315        }
00316 
00317        Input_Buf[Input_Len++] = StandardKey;
00318        Input_Buf[Input_Len] = 0;
00319        return(0);
00320 }
00321 
00322 /* return value:  IME_UNUSED_KEY:  if IME not use this key, return this key to systerm directly */
00323 /*                IME_OK:      if IME has used this key */
00324 int zhuyin_filter(TZhuyinData *pZhuyinData, unsigned char key, ImeBufferRec *ime_buffer)
00325 {
00326        char    ch;
00327        int     ret, i, k, hznum;
00328        int     pos, select_num;
00329        int    bHasWildChar, symbol_area_id;
00330        int    Max_Lookups_Num = LOOKUP_CHOICE_NUM;
00331        int     Max_Symbols_Lookups_Num = 10;
00332 
00333        CodeTableStruct *hztbl = pZhuyinData->pCodetableHeader;
00334 
00335        int    nHelpInfoMode = hztbl->nHelpInfoMode;
00336        int    nAutoSelectMode = hztbl->nAutoSelectMode;
00337 
00338        ime_buffer->encoding = hztbl->Encode;
00339 
00340        IME_Status = 0;
00341 
00342 /*
00343        ime_buffer->lookup_label_type = NUMERIC_LABEL;
00344 */
00345 
00346        bHasWildChar = If_Has_WildChar(Input_Buf);
00347 
00348        if(Is_Select_Key(pZhuyinData, key) && (Lookups_Num > 0)) {
00349               select_num = get_select_num(pZhuyinData, key);
00350               if (select_num >= 0 && select_num < Lookups_Num) {
00351                      commit_candidate(ime_buffer, select_num);
00352                      return(IME_OK);
00353               }
00354        }
00355 
00356        if(Is_Space_Key(pZhuyinData, key)) {
00357               /* if no input keys */
00358               if (Input_Len==0) 
00359                      return(IME_UNUSED_KEY);
00360 
00361               if (Lookups_Num==0) {
00362                      /* Search from beginning */
00363                      Lookup_Pos = 0;
00364                      Lookups_Num = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, Lookup_Pos, Max_Lookups_Num);
00365                      if (Lookups_Num == 1 && nAutoSelectMode) {
00366                             commit_candidate(ime_buffer, 0);
00367                      } else if (Lookups_Num == 0) {
00368                             warning_bell(ime_buffer);
00369                      }
00370                      IME_Status |= IME_LOOKUP_AREA;
00371                      return(IME_OK);
00372               }
00373 
00374               /* Space key as scroll key */
00375               /* if Have several candidates, need search the next page */
00376               pos = Lookup_Pos + Max_Lookups_Num;
00377               hznum = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, pos, Max_Lookups_Num); 
00378               if (hznum == 0) {
00379                      /* if no candidates for the next page */
00380                      if (Lookup_Pos = 0) {
00381                             /* if is the first page, need not do anything */
00382                             return(IME_OK);
00383                      } else {
00384                             /* if not the first page, need scroll to the first page */
00385                             pos = 0;
00386                             hznum = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, pos, Max_Lookups_Num); 
00387                      }
00388               }
00389 
00390               Lookup_Pos = pos;
00391               Lookups_Num = hznum;
00392               IME_Status = IME_LOOKUP_AREA;
00393 
00394               return(IME_OK);
00395        }
00396 
00397        if(Is_UsedCodes_Key(pZhuyinData, key)) { 
00398               /* if inputted keys length has over the limit */
00399               if (Lookups_Num > 0) {
00400                      strcpy((char *)Commit_Buf, (char *)Candidates[0]);
00401                      Commit_Len = strlen((char *)Commit_Buf);
00402                      Commit_And_Clean_All_Area(ime_buffer);
00403               }
00404 
00405               if (Input_Len == 0 && Is_Zhuyin_Tone_Key(pZhuyinData, key))
00406                      return(IME_OK);
00407 
00408               ret = zhuyin_add_key(pZhuyinData, ime_buffer, key);
00409               if (ret == -1) return(IME_OK);
00410 
00411               zhuyin_inputbuf_to_preeditbuf(pZhuyinData, ime_buffer);
00412               IME_Status |= IME_PREEDIT_AREA;
00413 
00414               if (Is_Zhuyin_Tone_Key(pZhuyinData, key)) {
00415                      /* Search from beginning */
00416                      Lookup_Pos = 0;
00417                      Lookups_Num = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, Lookup_Pos, Max_Lookups_Num);
00418                      if (Lookups_Num == 1 && nAutoSelectMode) {
00419                             commit_candidate(ime_buffer, 0);
00420                      } else if (Lookups_Num == 0) {
00421                             warning_bell(ime_buffer);
00422                      }
00423                      IME_Status |= IME_LOOKUP_AREA;
00424               }
00425 
00426               return(IME_OK);
00427        }
00428 
00429        if(Is_ClearAll_Key(pZhuyinData, key)) { 
00430               /* Esc , clear preedit area, lookup choice area */
00431 
00432               /*  if no inputted key, directly return this key */
00433               if (Lookups_Num == 0 && Input_Len==0) return(IME_UNUSED_KEY);
00434 
00435               Clean_All_Area(ime_buffer);
00436               return (IME_OK);
00437        }
00438 
00439        if (Is_BackSpace_Key(pZhuyinData, key)) { /* Back Space & Delete */
00440               /*  if no inputted key, directly return this key */
00441               if (Input_Len==0) return(IME_UNUSED_KEY);
00442 
00443               /* Delete characters in pre-edit region */
00444               Input_Len --;
00445               Input_Buf[Input_Len] = 0;
00446               if (Input_Len > 0) {
00447                      zhuyin_inputbuf_to_preeditbuf(pZhuyinData, ime_buffer);
00448               } else {
00449                      Preedit_Len = 0;
00450               }
00451               IME_Status = IME_PREEDIT_AREA;
00452 
00453               Lookups_Num = 0;
00454               IME_Status |= IME_LOOKUP_AREA;
00455               return(IME_OK);
00456 
00457        }
00458 
00459        if(Is_NextPage_Key(pZhuyinData, key)) {
00460               /*  if no inputted key, directly return this key */
00461               if (Input_Len==0) return(IME_UNUSED_KEY);
00462 
00463               /* if any preedit key and not in Lookup status */
00464               if (Lookups_Num==0) return(IME_OK);
00465 
00466               pos = Lookup_Pos + Max_Lookups_Num;
00467               hznum = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, pos, Max_Lookups_Num); 
00468               if (hznum > 0) {
00469                      Lookups_Num = hznum;
00470                      Lookup_Pos = pos;
00471                      IME_Status = IME_LOOKUP_AREA;
00472               } else {
00473                             warning_bell(ime_buffer);
00474               }
00475 
00476               return(IME_OK);
00477        }
00478 
00479        if(Is_PrevPage_Key(pZhuyinData, key)) {
00480               /*  if no inputted key, directly return this key */
00481               if (Input_Len==0) return(IME_UNUSED_KEY);
00482 
00483               /* if any preedit key and not in Lookup status */
00484               if (Lookups_Num==0) return(IME_OK);
00485 
00486               /* if in beginning pos */
00487               if (Lookup_Pos<=0) {
00488                             warning_bell(ime_buffer);
00489                      return(IME_OK);
00490               }
00491 
00492               pos = Lookup_Pos - Max_Lookups_Num;
00493               hznum = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, pos, Max_Lookups_Num); 
00494               if (hznum > 0) {
00495                      Lookups_Num = hznum;
00496                      Lookup_Pos = pos;
00497                      IME_Status = IME_LOOKUP_AREA;
00498               } else {
00499                             warning_bell(ime_buffer);
00500               }
00501 
00502               return(IME_OK);
00503        }
00504 
00505        if(Is_Return_Key(pZhuyinData, key)) { 
00506               /* Esc , clear preedit area, lookup choice area */
00507 
00508               /*  if no inputted key, directly return this key */
00509               if (Lookups_Num == 0 && Input_Len==0) return(IME_UNUSED_KEY);
00510 
00511               Clean_All_Area(ime_buffer);
00512               return (IME_OK);
00513        }
00514 
00515 
00516        /* for unnormal keys */
00517        if (Lookups_Num > 0) {
00518               /* need commit the first candidate */
00519               strcpy((char *)Commit_Buf, (char *)Candidates[0]);
00520               Commit_Len = strlen((char *)Commit_Buf);
00521               Commit_And_Clean_All_Area(ime_buffer);
00522        }
00523 
00524         return(IME_UNUSED_KEY);
00525 }