Back to index

im-sdk  12.3.91
ctfilter.c
Go to the documentation of this file.
00001 /*
00002   Copyright 2002-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 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 
00046 #include "codetable.h"
00047 #include "unit_input.h"
00048 #include "keymap.h"
00049 #include "logf.h"
00050 
00051 #define LOOKUP_CHOICE_NUM   6
00052 
00053 #define IME_Status  ime_buffer->return_status
00054 #define Input_Buf  ime_buffer->inputkey_buf
00055 #define Input_Len  ime_buffer->inputkey_len
00056 #define Preedit_Buf  ime_buffer->preedit_buf
00057 #define Preedit_Len  ime_buffer->preedit_len
00058 #define Preedit_CaretPos ime_buffer->preedit_caretpos
00059 #define Commit_Buf  ime_buffer->commit_buf
00060 #define Commit_Len  ime_buffer->commit_len
00061 #define Status_Buf  ime_buffer->status_buf
00062 #define Status_Len  ime_buffer->status_len
00063 #define Lookup_Buf  ime_buffer->lookup_buf
00064 #define Lookup_Num  ime_buffer->lookup_num
00065 #define Lookup_Pos  ime_buffer->cur_lookup_pos
00066 #define Candidates_Buf  ime_buffer->candidates_buf
00067 #define Additions_Buf  ime_buffer->additions_buf
00068 
00069 int Is_UsedCodes_Key(hztbl, key)
00070      CodeTableStruct *hztbl;
00071      int key;
00072 {
00073   if ( index(hztbl->UsedCodes, key) )
00074     return(1);
00075   else
00076     return(0);
00077 }
00078 
00079 int get_select_num(hztbl, key)
00080      CodeTableStruct *hztbl;
00081      int key;
00082 {
00083   int ret = -1;
00084   switch(hztbl->nSelectKeyMode)
00085     {
00086     case NUMBER_MODE:
00087       if (key >= '0' && key <= '9')
00088        ret = (key - '0' + 9) % 10;
00089       break;
00090 
00091     case LOWER_MODE:
00092       if (key >= 'a' && key <= 'a' + 10)
00093        ret = key - 'a';
00094       break;
00095 
00096     case UPPER_MODE:
00097       if (key >= 'A' && key <= 'A' + 10)
00098        ret = key - 'A';
00099       break;
00100     }
00101   return(ret);
00102 }
00103 
00104 int Is_Select_Key(hztbl, key)
00105      CodeTableStruct *hztbl;
00106      int key;
00107 {
00108   int ret = get_select_num(hztbl, key);
00109   if (ret == -1)
00110     return(0);
00111   else
00112     return(1);
00113 }
00114 
00115 int Is_Commit_Key(hztbl, key)
00116      CodeTableStruct *hztbl;
00117      int key;
00118 {
00119   if (key == SPACE_KEY || key == RETURN_KEY)
00120     return(1);
00121   else
00122     return(0);
00123 }
00124 
00125 int Is_BackSpace_Key(hztbl, key)
00126      CodeTableStruct *hztbl;
00127      int key;
00128 {
00129   unsigned char *keylist = hztbl->functionkey[BACKSPACE_KEY_ID].keylist;
00130 
00131   if (key == BACKSPACE_KEY || key == DELETE_KEY)
00132     return(1);
00133 
00134   if ( keylist[0] )
00135     {
00136       if ( index(keylist, key) )
00137        return(1);
00138     }
00139 
00140   return(0);
00141 }
00142 
00143 int Is_ClearAll_Key(hztbl, key)
00144      CodeTableStruct *hztbl;
00145      int key;
00146 {
00147   unsigned char *keylist = hztbl->functionkey[CLEARALL_KEY_ID].keylist;
00148 
00149   if (key == ESC_KEY)
00150     return(1);
00151 
00152   if ( keylist[0] )
00153     {
00154       if ( index(keylist, key) )
00155        return(1);
00156     }
00157   return(0);
00158 }
00159 
00160 int Is_NextPage_Key(hztbl, key)
00161      CodeTableStruct *hztbl;
00162      int key;
00163 {
00164   unsigned char *keylist = hztbl->functionkey[PAGEDOWN_KEY_ID].keylist;
00165 
00166   if (key == PAGEDOWN_KEY)
00167     return(1);
00168 
00169   if ( keylist[0] )
00170     {
00171       if ( index(keylist, key) )
00172        return(1);
00173     }
00174   return(0);
00175 }
00176 
00177 int Is_PrevPage_Key(hztbl, key)
00178      CodeTableStruct *hztbl;
00179      int key;
00180 {
00181   unsigned char *keylist = hztbl->functionkey[PAGEUP_KEY_ID].keylist;
00182 
00183   if (key == PAGEUP_KEY)
00184     return(1);
00185  
00186   if ( keylist[0] )
00187     {
00188       if ( index(keylist, key) )
00189        return(1);
00190     }
00191   return(0);
00192 }
00193 
00194 int get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, pos, max_lookup_num)
00195      CodeTableStruct *hztbl;
00196      IMEBufferRec *ime_buffer;
00197      int nHelpInfoMode;
00198      int pos;
00199      int max_lookup_num;
00200 {
00201   int i, lookup_num;
00202 
00203   lookup_num = codetable_search(hztbl, Input_Buf, Input_Len, Candidates_Buf, Additions_Buf, pos, max_lookup_num); 
00204   if (lookup_num > 0)
00205     {
00206       for (i=0; i<lookup_num; i++)
00207        {
00208          log_f("%d: %s %s\n", i, Candidates_Buf[i], Additions_Buf[i]);
00209          if (nHelpInfoMode)
00210            sprintf((char *)Lookup_Buf[i], "%s %s", Candidates_Buf[i], Additions_Buf[i]);
00211          else
00212            strcpy(Lookup_Buf[i], Candidates_Buf[i]);
00213        }
00214     }
00215   return(lookup_num);
00216 }
00217 
00218 int commit_candidate(ime_buffer, id)
00219      IMEBufferRec *ime_buffer;
00220      int id;
00221 {
00222   if (id >= Lookup_Num)
00223     return(-1);
00224 
00225   strcpy((char *)Commit_Buf, (char *)Candidates_Buf[id]);
00226   Commit_Len = strlen((char *)Commit_Buf);
00227   log_f("Inside commit_candidate, Commit_Buf <%s>\n",Commit_Buf);
00228   IME_Status = IME_COMMIT;
00229   Input_Len = 0;
00230   Input_Buf[Input_Len] = '\0';
00231   Preedit_Len = 0;
00232   Lookup_Num = 0;
00233   Preedit_CaretPos = 0;
00234   IME_Status |= IME_PREEDIT_AREA | IME_LOOKUP_AREA;
00235   return(0);
00236 }
00237 
00238 void warning_bell()
00239 {
00240 }
00241 
00242 /* return value:  IME_NOT_USED_KEY:  if IME not use this key, return this key to systerm directly */
00243 /*                IME_USED_KEY:      if IME has used this key */
00244 int codetable_filter(hztbl, key_event, ime_buffer)
00245      CodeTableStruct *hztbl;
00246      IMEKey key_event;
00247      IMEBufferRec *ime_buffer;
00248 {
00249   int     hznum;
00250   char    ch;
00251   int     key, pos;
00252   int nLookup_Pos_Save = 0;
00253   int  bNeedCheckMore = 0;
00254  
00255   int  Max_Lookup_Num = LOOKUP_CHOICE_NUM;
00256   int  nKeyByKeyMode = hztbl->nKeyByKeyMode;
00257   int  nHelpInfoMode = hztbl->nHelpInfoMode;
00258   int  nAutoSelectMode = hztbl->nAutoSelectMode;
00259   int  nKeyPromptMode = hztbl->nKeyPromptMode;
00260   int prev_Input_Len;
00261   static int static_prev_Input_Buf[MAX_INPUT_KEY_NUM];
00262   int *prev_Input_Buf = static_prev_Input_Buf;
00263  
00264   ime_buffer->encode = hztbl->Encode;
00265 
00266   IME_Status = 0;
00267 
00268   key = map_keyevent_to_imekey(hztbl, key_event);
00269   log_f("ctfilter: map_keyevent_to_imekey: return key:0x%x\n", key);
00270  
00271   if (key == IME_NOT_USED_KEY)
00272     return(IME_NOT_USED_KEY);
00273  
00274   switch(hztbl->nSelectKeyMode) {
00275   case NUMBER_MODE:
00276     ime_buffer->lookup_label_type = NUMERIC_LABEL;
00277     break;
00278   case LOWER_MODE:
00279     ime_buffer->lookup_label_type = LOWER_LABEL;
00280     break;
00281   case UPPER_MODE:
00282     ime_buffer->lookup_label_type = UPPER_LABEL;
00283     break;
00284   default:
00285     ime_buffer->lookup_label_type = NUMERIC_LABEL;
00286   }
00287 
00288   if((Is_UsedCodes_Key(hztbl, key)) || (Is_Wildchar_Key(hztbl, key))) { 
00289     prev_Input_Buf = Input_Buf;
00290     prev_Input_Len = Input_Len;
00291 
00292     /* if inputted keys length has over the limit */
00293           
00294     if (Input_Len >= hztbl->MaxCodes) {
00295       warning_bell();
00296       return (IME_USED_KEY);
00297     }
00298 
00299     /* if not key by key, and is selectkey, and Lookup Mode */
00300     /* directly select */
00301 
00302     if(!nKeyByKeyMode && (Is_Select_Key(hztbl, key)) && (Lookup_Num>0)) { 
00303 
00304       /* select from candidata */
00305       /* here should see whether there is enough candidates */
00306 
00307       int select_num;
00308       select_num = get_select_num(hztbl, key);
00309       if ((select_num >= 0) && (select_num < Lookup_Num)) {
00310         commit_candidate(ime_buffer, select_num);
00311       }else warning_bell();
00312 
00313       return(IME_USED_KEY);
00314     }
00315 
00316     Input_Buf[Input_Len] = key;
00317     Input_Len ++;
00318     Input_Buf[Input_Len] = '\0';
00319 
00320     Lookup_Num = 0;
00321     bNeedCheckMore = 0;
00322     /* if need display key by key */
00323     if (nKeyByKeyMode) {
00324       nLookup_Pos_Save = Lookup_Pos;
00325       Lookup_Pos = 0;
00326       Lookup_Num = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, Lookup_Pos, Max_Lookup_Num); 
00327       if (Lookup_Num == 1 && nAutoSelectMode) {
00328         commit_candidate(ime_buffer, 0);
00329         return(IME_USED_KEY);
00330       }
00331 
00332       if (Lookup_Num == 0) {
00333         log_f("Lookup_Num is zero \n"); 
00334         /* if key is also a seleck key */
00335         if (Is_Select_Key(hztbl, key))
00336           bNeedCheckMore = 1;
00337         else {
00338           Input_Buf = prev_Input_Buf;
00339           Input_Len = prev_Input_Len;
00340           if (Input_Len == 0) {
00341             Commit_Len = 0;
00342             Commit_Buf[Commit_Len] = key;
00343             Commit_Len++;
00344             Commit_Buf[Commit_Len] = '\0';
00345             Commit_Len = strlen((char *)Commit_Buf);
00346             log_f("codetable_filter: commit_candidate, Commit_Buf <%s>\n",Commit_Buf);
00347             IME_Status = IME_COMMIT;
00348             Input_Len = 0;
00349             Input_Buf[Input_Len] = 0;
00350             Preedit_Len = 0;
00351             Preedit_Buf[Preedit_Len] = '\0';
00352             IME_Status |= IME_PREEDIT_AREA | IME_LOOKUP_AREA;
00353             return(IME_NOT_USED_KEY);
00354           }
00355           nLookup_Pos_Save = Lookup_Pos;
00356           Lookup_Pos = 0;
00357           Lookup_Num = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, Lookup_Pos, Max_Lookup_Num); 
00358           commit_candidate(ime_buffer, 0);
00359           Input_Buf[Input_Len] = key;
00360           Input_Len ++;
00361           Input_Buf[Input_Len] = '\0';
00362           Lookup_Num = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, Lookup_Pos, Max_Lookup_Num);
00363           if (bNeedCheckMore == 0) {
00364             Preedit_Buf[Preedit_Len] = key;
00365             Preedit_Len += 1;
00366             Preedit_Buf[Preedit_Len] = '\0';
00367             Preedit_CaretPos = Preedit_Len;
00368             return(IME_USED_KEY);
00369           }
00370         }
00371       }
00372       log_f("prev_Input_Len [%d], Input_Len [%d]\n",prev_Input_Len, Input_Len);
00373       if (prev_Input_Len != Input_Len) {
00374        Preedit_Buf[Preedit_Len] = key;
00375        Preedit_Len += 1;
00376        Preedit_Buf[Preedit_Len] = '\0';
00377       }
00378     }else{
00379       Preedit_Buf[Preedit_Len] = key;
00380       Preedit_Len += 1;
00381       Preedit_Buf[Preedit_Len] = '\0';
00382     }
00383     Preedit_CaretPos = Preedit_Len;
00384     IME_Status = IME_PREEDIT_AREA;
00385 
00386     if (bNeedCheckMore == 0) {
00387       IME_Status |= IME_LOOKUP_AREA;
00388       return(IME_USED_KEY);
00389     }
00390   }
00391   
00392   if (bNeedCheckMore == 1) {
00393     /* restore the original status that before into this function */
00394     IME_Status = 0;
00395     Input_Len --;
00396     Input_Buf[Input_Len] = '\0';
00397     Lookup_Pos = nLookup_Pos_Save;
00398     Lookup_Num = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, Lookup_Pos, Max_Lookup_Num); 
00399   }
00400 
00401   if (Is_Select_Key(hztbl, key)) { /* select from candidata */
00402     /* here should see whether there is enough candidates */
00403     int select_num;
00404 
00405     /*  if no inputted key, directly return this key */
00406     if (Input_Len==0) return(IME_NOT_USED_KEY);
00407     log_f("Select Key, key:%c, Lookup_Num:%d\n", key, Lookup_Num);
00408     select_num = get_select_num(hztbl, key);
00409     if (Lookup_Num>0 && (select_num >= 0) && (select_num < Lookup_Num)) {
00410       commit_candidate(ime_buffer, select_num);
00411     } else warning_bell();
00412 
00413     return(IME_USED_KEY);
00414   }
00415 
00416   if (Is_ClearAll_Key(hztbl, key)) { 
00417     /* Esc , clear preedit, lookup choice pointer, and so on */
00418     log_f("ESC_KEY\n");
00419     /*  if no inputted key, directly return this key */
00420     if (Input_Len==0) return(IME_NOT_USED_KEY);
00421   
00422     Input_Len = 0;
00423     Preedit_Len = 0;
00424     Lookup_Num = 0;
00425     Preedit_CaretPos = 0;
00426     IME_Status = IME_PREEDIT_AREA | IME_LOOKUP_AREA;
00427     return (IME_USED_KEY);
00428   }
00429 
00430   if (Is_BackSpace_Key(hztbl, key)) { /* Back Space & Delete */
00431     log_f("BACKSPACE_KEY\n");
00432     /*  if no inputted key, directly return this key */
00433     if (Input_Len==0) return(IME_NOT_USED_KEY);
00434   
00435     /* Delete characters in pre-edit region */
00436     Input_Len --;
00437     if (nKeyPromptMode) {
00438       ch = Input_Buf[Input_Len];
00439       log_f("ch:%c, keyprompt:%s\n", ch, hztbl->keyprompt[atoi(&ch)].prompt);
00440       Preedit_Len -= strlen(hztbl->keyprompt[atoi(&ch)].prompt);
00441       Preedit_Buf[Preedit_Len] = '\0';
00442     }else{
00443       Preedit_Len -= 1;
00444       Preedit_Buf[Preedit_Len] = '\0';
00445     }
00446 
00447     Input_Buf[Input_Len] = '\0';
00448     Preedit_CaretPos = Preedit_Len;
00449     IME_Status = IME_PREEDIT_AREA;
00450 
00451     Lookup_Num = 0;
00452   
00453     /* if still left some keys, and need display key by key, then search. */
00454     /* else undisplay the candidate window */
00455     if ((Input_Len > 0) && nKeyByKeyMode) {
00456       Lookup_Pos = 0;
00457       Lookup_Num = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, Lookup_Pos, Max_Lookup_Num); 
00458     }
00459 
00460     IME_Status |= IME_LOOKUP_AREA;
00461     return(IME_USED_KEY);
00462 
00463   }
00464 
00465   if (Is_NextPage_Key(hztbl, key)) { /* select from candidata */
00466     /*  if no inputted key, directly return this key */
00467     if (Input_Len==0) return(IME_NOT_USED_KEY);
00468 
00469     /* if any preedit key and not in Lookup status */
00470     log_f("NextPage:  Lookup_Num:%d\n", Lookup_Num);
00471     if (Lookup_Num==0) return(IME_USED_KEY);
00472 
00473     pos = Lookup_Pos + Max_Lookup_Num;
00474     log_f("NextPage: pos:%d\n", pos);
00475     hznum = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, pos, Max_Lookup_Num); 
00476     if (hznum > 0) {
00477       Lookup_Num = hznum;
00478       Lookup_Pos = pos;
00479       IME_Status = IME_LOOKUP_AREA;
00480     }else warning_bell();
00481     
00482     return(IME_USED_KEY);
00483 
00484   }
00485 
00486   if (Is_PrevPage_Key(hztbl, key)) { /* select from candidata */
00487 
00488     /*  if no inputted key, directly return this key */
00489     if (Input_Len==0) return(IME_NOT_USED_KEY);
00490     log_f("PrevPage:  Lookup_Num:%d\n", Lookup_Num);
00491     /* if any preedit key and not in Lookup status */
00492     if (Lookup_Num==0) return(IME_USED_KEY);
00493   
00494     /* if in beginning pos */
00495     if (Lookup_Pos<=0) {
00496       warning_bell();
00497       return(IME_USED_KEY);
00498     }
00499 
00500     pos = Lookup_Pos - Max_Lookup_Num;
00501     hznum = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, pos, Max_Lookup_Num); 
00502     log_f("hznum :%d\n", hznum);
00503     if (hznum > 0) {
00504       Lookup_Num = hznum;
00505       Lookup_Pos = pos;
00506       IME_Status = IME_LOOKUP_AREA;
00507     }else warning_bell();
00508 
00509     return(IME_USED_KEY);
00510   }
00511 
00512   if (Is_Commit_Key(hztbl, key)) { /* space or return key */
00513     log_f("Space or Return key, Commit Key ===\n");
00514     /* if no input keys and no candidates */
00515     if (Input_Len==0 && Lookup_Num==0) 
00516       return(IME_NOT_USED_KEY);
00517 
00518     /* if any candidates, then commit the first candidate */
00519     if (Lookup_Num > 0) {
00520       log_f("Commit Key , Commit the first candidate===\n");
00521       commit_candidate(ime_buffer, 0);
00522       return(IME_USED_KEY);
00523     }
00524 
00525     /* if any keys and key is Space key and mode is not keybykey */
00526     /* then search and display the candidates */
00527     if (key == SPACE_KEY && !nKeyByKeyMode) {
00528       Lookup_Pos = 0;
00529       Lookup_Num = get_lookup_result(hztbl, ime_buffer, nHelpInfoMode, Lookup_Pos, Max_Lookup_Num); 
00530       log_f("Lookup_Num:%d\n", Lookup_Num);
00531       if (Lookup_Num == 1 && nAutoSelectMode) {
00532         commit_candidate(ime_buffer, 0);
00533         return(IME_USED_KEY);
00534       }
00535 
00536       if (Lookup_Num == 0)
00537         warning_bell();
00538 
00539       IME_Status = IME_LOOKUP_AREA;
00540       return(IME_USED_KEY);
00541     }
00542 
00543     return(IME_USED_KEY);
00544   }
00545 
00546   /* for unnormal keys */
00547   log_f(" unnormal key:%d\n", key);
00548   if (Input_Len==0) return(IME_NOT_USED_KEY);
00549   else return(IME_USED_KEY);
00550 }
00551