Back to index

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