Back to index

im-sdk  12.3.91
zhuyin_interface.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 
00003 #ifdef HAVE_CONFIG_H
00004 #include "config.h"
00005 #endif
00006 
00007 #include "ctim.h"
00008 #include "zhuyin_data.h"
00009 #include "zhuyin_messages.h"
00010 
00011 #define NAME_UTF8    "Codetable"
00012 #define AUTHOR              "Ervin Yan <Ervin.Yan@sun.com>"
00013 #define COPYRIGHT    "Copyright (c) 2005 Sun Microsystems"
00014 #define HINTING             "Codetable Input Method"
00015 
00016 ImeResult zhuyin_Initialize(ImeInfo ime_info);
00017 ImeResult zhuyin_Destroy(ImeInfo ime_info);
00018 ImeResult zhuyin_Process_Key_Event(ImeInputContext ic, ImeKey key_event);
00019 ImeResult zhuyin_Create_Session(ImeInputContext ic);
00020 ImeResult zhuyin_Destroy_Session(ImeInputContext ic);
00021 ImeResult zhuyin_FocusOut(ImeInputContext ic);
00022 ImeResult zhuyin_FocusIn(ImeInputContext ic);
00023 
00024 ImmServices imm_services;
00025 
00026 typedef struct _codetable_im_data_t {
00027        char *file_name;
00028        TZhuyinData *zhuyin_data;
00029 } codetable_im_data_t;
00030 
00031 ImeMethodsRec zhuyin_methods = {
00032        1,                                /* version */
00033        zhuyin_Initialize,                  /* ImeInitialize */
00034        zhuyin_Destroy,                     /* ImeDestroy  */
00035        zhuyin_Process_Key_Event,           /* ImeProcessKeyEvent */
00036        NULL,                             /* ImeProcessAuxEvent  */
00037        zhuyin_Create_Session,              /* ImeAttachSession */
00038        zhuyin_Destroy_Session,             /* ImeDetachSession */
00039        zhuyin_FocusIn,                     /* ImeFocusIn  */
00040        zhuyin_FocusOut,                    /* ImeFocusOut */
00041        NULL,                             /* ImeAttachUser */
00042        NULL,                             /* ImeDetachUser */
00043        NULL,                             /* ImeAttachDesktop */
00044        NULL,                             /* ImeDetachDesktop */
00045        NULL,                             /* ImeGetErrorMessage */
00046 #if 0
00047        NULL,                             /* ImeDoConfig */
00048 #endif
00049 };
00050 
00051 #ifdef WIN32
00052 #define EXPORT extern __declspec(dllexport)
00053 EXPORT
00054 #endif
00055 ImeResult RegisterIME(ImmServices srvs, ImeInfo* ppinfo, ImeMethods* pmthds, int argc, char **argv)
00056 {
00057        ImeInfoRec *zhuyin_info = NULL;
00058        char *zhuyin_config_file = NULL;
00059        char *base_dir = NULL;
00060        char file_path[256];
00061        TZhuyinData  *zhuyin_data = NULL;
00062        CodeTableStruct *ctHeader;
00063 
00064        int version_num, i, ret;
00065 
00066        DEBUG_printf("Register Codetable IM: argc: %d\n", argc);
00067        for (i=0; i<argc; i++) {
00068               if (!strcasecmp(argv[i], "-basedir")) {
00069                      if (argv[i+1]) {
00070                             base_dir = argv[i+1];
00071                             DEBUG_printf("       setting base dir to: %s\n", argv[i+1]);
00072                      }
00073                      i++;
00074               } else if (!strcasecmp(argv[i], "-config")) {
00075                      if (argv[i+1]) {
00076                             zhuyin_config_file = argv[i+1];
00077                             DEBUG_printf("       setting codetable file to: %s\n", argv[i+1]);
00078                      }
00079                      i++;
00080               }
00081        }
00082 
00083        if (!zhuyin_config_file || !*zhuyin_config_file)
00084               return (IME_FAIL);
00085 
00086        if (base_dir == NULL)
00087               base_dir = LE_BASE_DIR;
00088 
00089        if (base_dir && *base_dir && *zhuyin_config_file != '/') {
00090               snprintf(file_path, 256, "%s/%s", base_dir, zhuyin_config_file);
00091        }
00092 
00093        zhuyin_data = (TZhuyinData *)calloc(1, sizeof(TZhuyinData));
00094        if (zhuyin_data == NULL)
00095               return(IME_FAIL);
00096 
00097        ret = ZhuyinData_Init(file_path, zhuyin_data);
00098        if (ret == ZHUYIN_ERROR) {
00099               ZhuyinData_Free(zhuyin_data);
00100               free ((char *)zhuyin_data);
00101               return (IME_FAIL);
00102        }
00103 
00104        zhuyin_info = (ImeInfoRec *)calloc(1, sizeof(ImeInfoRec));
00105        if (zhuyin_info == NULL)  {
00106               ZhuyinData_Free(zhuyin_data);
00107               free ((char *)zhuyin_data);
00108               return (IME_FAIL);
00109        }
00110 
00111        ctHeader =(CodeTableStruct *)(zhuyin_data->pCodetableHeader);
00112        version_num = 1;
00113        if (*(ctHeader->Version))
00114               version_num = atoi(ctHeader->Version);
00115        version_num += CODETABLE_VERSION * 100;
00116 
00117        zhuyin_info->version           = version_num;
00118        zhuyin_info->encoding          = ctHeader->Encode;
00119        zhuyin_info->name              = (char *)strdup(ctHeader->Cname);
00120        zhuyin_info->uuid              = (char *)strdup(ctHeader->UUID);
00121 
00122        if (*ctHeader->Author)
00123               zhuyin_info->author    = (char *)strdup(ctHeader->Author);
00124        else
00125               zhuyin_info->author    = (char *)strdup(AUTHOR);
00126        if (*ctHeader->Copyright)
00127               zhuyin_info->copyright = (char *)strdup(ctHeader->Copyright);
00128        else
00129               zhuyin_info->copyright = (char *)strdup(COPYRIGHT);
00130        if (*ctHeader->Hinting)
00131               zhuyin_info->hinting   = (char *)strdup(ctHeader->Hinting);
00132        else
00133               zhuyin_info->hinting   = (char *)strdup(HINTING);
00134 
00135        zhuyin_info->icon_file         = (char *)strdup(ctHeader->IconPath);
00136 
00137        zhuyin_info->support_locales   = ZHUYIN_SUPPORT_LOCALES;
00138 
00139        zhuyin_info->specific_data     = (void *)zhuyin_data;
00140 
00141        zhuyin_Init_Ime_Properties (zhuyin_info, zhuyin_data);
00142 
00143        *ppinfo = zhuyin_info;
00144        *pmthds = &zhuyin_methods;
00145 
00146        imm_services = srvs;
00147 
00148        DEBUG_printf("begin leave Register IME\n");
00149        return (IME_OK);
00150 }
00151 
00152 ImeResult zhuyin_Initialize(ImeInfo zhuyin_info)
00153 {
00154        TZhuyinData *zhuyin_data;
00155        int ret;
00156 
00157        DEBUG_printf("zhuyin_Initialize\n");
00158 
00159        if (zhuyin_info == NULL)
00160               return (IME_FAIL);
00161 
00162        zhuyin_data = (TZhuyinData *)zhuyin_info->specific_data;
00163        ret = ZhuyinData_Open(zhuyin_data);
00164        if (ret == ZHUYIN_ERROR) {
00165               ZhuyinData_Free(zhuyin_data);
00166               free ((char *)zhuyin_data);
00167               return (IME_FAIL);
00168        }
00169 
00170        return (IME_OK);
00171 }
00172 
00173 ImeResult zhuyin_Destroy(ImeInfo zhuyin_info)
00174 {
00175        TZhuyinData *zhuyin_data;
00176 
00177        DEBUG_printf("zhuyin_Destroy\n");
00178 
00179        if (zhuyin_info != NULL) {
00180               if (zhuyin_info->uuid != NULL)
00181                      free ((char *)zhuyin_info->uuid);
00182               if (zhuyin_info->icon_file != NULL)
00183                      free ((char *)zhuyin_info->icon_file);
00184               if (zhuyin_info->name != NULL)
00185                      free ((char *)zhuyin_info->name);
00186               if (zhuyin_info->author != NULL)
00187                      free ((char *)zhuyin_info->author);
00188               if (zhuyin_info->copyright != NULL)
00189                      free ((char *)zhuyin_info->copyright);
00190               if (zhuyin_info->hinting != NULL)
00191                      free ((char *)zhuyin_info->hinting);
00192 
00193               zhuyin_Destroy_Ime_Properties(zhuyin_info);
00194 
00195               zhuyin_data = (TZhuyinData *)zhuyin_info->specific_data;
00196               if (zhuyin_data) {
00197                      ZhuyinData_Free(zhuyin_data);
00198                      free ((char *)zhuyin_data);
00199               }
00200 
00201               free ((char *)zhuyin_info);
00202        }
00203 
00204        return (IME_OK);
00205 }
00206 
00207 ImeResult zhuyin_Create_Session(ImeInputContext ic)
00208 {
00209        int i;
00210        ImmResult imm_result;
00211        ImeBufferRec *ime_buffer = NULL;
00212 
00213        ime_buffer = (ImeBufferRec *)imm_services->ImmGetData(ic, IME_SCOPE_SESSION);
00214        DEBUG_printf("zhuyin_Create_Session ======= begin get ime_session_data: 0x%x\n", ime_buffer);
00215        if (ime_buffer == NULL) {
00216               ime_buffer = (ImeBufferRec *)calloc(1, sizeof(ImeBufferRec));
00217               if (ime_buffer == NULL)
00218                      return (IME_FAIL);
00219 
00220               for (i = 0; i < MAX_CANDIDATES_NUM; i++) {
00221                      ime_buffer->candidates[i] = ime_buffer->candidates_buf[i];
00222                      ime_buffer->comments[i] = ime_buffer->comments_buf[i];
00223                      ime_buffer->lookups[i] = ime_buffer->lookups_buf[i];
00224               }
00225 
00226               imm_result = imm_services->ImmSetData(ic, IME_SCOPE_SESSION, ime_buffer);
00227               if (imm_result == IMM_FAIL) {
00228                      free ((char *)ime_buffer);
00229                      return (IME_FAIL);
00230               }
00231        }
00232        
00233        return (IME_OK);
00234 }
00235 
00236 ImeResult zhuyin_Destroy_Session(ImeInputContext ic)
00237 {
00238        ImeBufferRec *ime_buffer = NULL;
00239 
00240        ime_buffer = (ImeBufferRec *)imm_services->ImmGetData(ic, IME_SCOPE_SESSION);
00241        DEBUG_printf("zhuyin_Destroy_Session ======= begin get ime_session_data: 0x%x\n", ime_buffer);
00242 
00243        if (ime_buffer != NULL) {
00244               free ((char *)ime_buffer);
00245        }
00246 
00247        imm_services->ImmSetData(ic, IME_SCOPE_SESSION, NULL);
00248 
00249        return (IME_OK);
00250 }
00251 
00252 ImeResult zhuyin_FocusIn(ImeInputContext ic)
00253 {
00254         DEBUG_printf("codetable: call zhuyin_FocusIn()\n");
00255         return(IME_OK);
00256 }
00257 
00258 ImeResult zhuyin_FocusOut(ImeInputContext ic)
00259 {
00260         DEBUG_printf("codetable: call zhuyin_FocusOut()\n");
00261         return(IME_OK);
00262 }
00263 
00264 ImmResult zhuyin_beep(ImeInputContext ic)
00265 {
00266        return (imm_services->ImmBeep(ic, ImeBeepWarning));
00267 }
00268 
00269 ImmResult zhuyin_commit(ImeInputContext ic, int encoding, char *commit_buf, int commit_len)
00270 {
00271        if (commit_len <= 0)
00272               return (IMM_FAIL);
00273 
00274        if (commit_buf == NULL)
00275               return (IMM_FAIL);
00276 
00277        return (imm_services->ImmCommit(ic, commit_buf));
00278 }
00279 
00280 ImmResult zhuyin_update_preedit(ImeInputContext ic, int encoding,
00281                             char *preedit_buf, int preedit_len, int caret_pos)
00282 {
00283        ImePreeditRec ime_preedit;
00284 
00285        memset(&ime_preedit, 0, sizeof(ImePreeditRec));
00286 
00287        if (preedit_len == 0) {
00288               return (imm_services->ImmHidePreedit(ic));
00289        }
00290 
00291         imm_services->ImmShowPreedit(ic);
00292 
00293        ime_preedit.caret = caret_pos;
00294        ime_preedit.preedit.text = preedit_buf;
00295 
00296        return (imm_services->ImmUpdatePreedit(ic, &ime_preedit));
00297 }
00298 
00299 ImmResult zhuyin_update_candidates(ImeInputContext ic, int encoding, char **candidates, int num_candidates, int page_state)
00300 {
00301        int i;
00302        ImmResult imm_result;
00303        ImeCandidatesRec ime_candidates;
00304 
00305        memset(&ime_candidates, 0, sizeof(ImeCandidatesRec));
00306 
00307        if (num_candidates == 0 || candidates == NULL) {
00308               return (imm_services->ImmHideCandidates(ic));
00309        }
00310 
00311        imm_services->ImmShowCandidates(ic);
00312 
00313        ime_candidates.title = NULL;
00314        ime_candidates.focus = 0;
00315        ime_candidates.page_state = page_state;
00316        ime_candidates.numbers = NULL;
00317        ime_candidates.count = num_candidates;
00318        ime_candidates.candidates = (ImeTextRec *)calloc(num_candidates, sizeof(ImeTextRec));
00319        if (ime_candidates.candidates == NULL)
00320               return (IMM_FAIL);
00321 
00322        for (i=0; i<num_candidates; i++) {
00323               ime_candidates.candidates[i].text = candidates[i];
00324        }
00325 
00326        imm_result = imm_services->ImmUpdateCandidates(ic, &ime_candidates);
00327 
00328        free ((char *)ime_candidates.candidates);
00329        return(imm_result);
00330 }
00331 
00332 /* process key input event */
00333 /* return value:  IME_UNUSED_KEY:  if IME not use this key, return this key to systerm directly */
00334 /*                IME_OK:      if IME has used this key */
00335 ImeResult zhuyin_Process_Key_Event(ImeInputContext ic, ImeKey key_event)
00336 {
00337        ImeInfoRec *zhuyin_info = NULL;
00338        ImeBufferRec *ime_buffer = NULL;
00339 
00340        TZhuyinData *zhuyin_data;
00341        unsigned char key;
00342        int ret;
00343 
00344        DEBUG_printf("zhuyin_Process_Key_Event: ic: 0x%x\n", ic);
00345        ime_buffer = (ImeBufferRec *)imm_services->ImmGetData(ic, IME_SCOPE_SESSION);
00346        if (ime_buffer == NULL)
00347               return (IME_UNUSED_KEY);
00348 
00349        zhuyin_info = (ImeInfo)imm_services->ImmGetImeInfo(ic);
00350        if (zhuyin_info == NULL || zhuyin_info->specific_data == NULL)
00351               return (IME_UNUSED_KEY);
00352 
00353        zhuyin_data = (TZhuyinData *)zhuyin_info->specific_data;
00354        if (zhuyin_data == NULL ||
00355            zhuyin_data->pCodetableHeader == NULL)
00356               return (IME_UNUSED_KEY);
00357 
00358        if (imm_services->ImmPrefilterKey == NULL) {
00359               DEBUG_printf("zhuyin_Process_Key_Event: imm_services->ImmPrefilterKey is NULL\n");
00360               return (IME_UNUSED_KEY);
00361        }
00362               
00363        key = imm_services->ImmPrefilterKey(key_event);
00364        DEBUG_printf("zhuyin_Process_Key_Event: imm_services->ImmPrefilterKey return: 0x%x\n", key);
00365        if (key == IME_FILTERED_KEY_UNUSED)
00366               return (IME_UNUSED_KEY);
00367 
00368        zhuyin_Set_Ime_Properties(ic, zhuyin_data);
00369 
00370        ret = zhuyin_filter(zhuyin_data, key, ime_buffer);
00371 
00372        if (ime_buffer->return_status & IME_PREEDIT_AREA) {
00373               zhuyin_update_preedit(ic, ime_buffer->encoding, ime_buffer->preedit_buf,
00374                                   ime_buffer->preedit_len, ime_buffer->preedit_caretpos);
00375        }
00376 
00377        if (ime_buffer->return_status & IME_LOOKUP_AREA) {
00378               zhuyin_update_candidates(ic, ime_buffer->encoding, ime_buffer->lookups, ime_buffer->num_candidates, ime_buffer->page_state);
00379        }
00380        
00381        if (ime_buffer->return_status & IME_COMMIT) {
00382               zhuyin_commit(ic, ime_buffer->encoding, ime_buffer->commit_buf, ime_buffer->commit_len);
00383        }
00384 
00385         if (ime_buffer->return_status & IME_BEEP) {
00386               zhuyin_beep(ic);
00387         }
00388 
00389        if (ret == IME_UNUSED_KEY)
00390               return (IME_UNUSED_KEY);
00391 
00392        return (IME_OK);
00393 }
00394