Back to index

im-sdk  12.3.91
le_info.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 
00003 #include "le_info.h"
00004 
00005 LeResult le_info_destroy(LeInfoRec * le_info);
00006 LeResult le_info_init_m17n_input_methods(LeInfoRec * le_info);
00007 LeResult le_info_done_m17n_input_methods(LeInfoRec * le_info);
00008 
00009 extern void le_session_ui_callbacks(MInputContext *ic, MSymbol command);
00010 
00011 LeInfoRec *le_info_new()
00012 {
00013     LeResult result;
00014     LeInfoRec *le_info = NULL;
00015 
00016     le_info = (LeInfoRec *) calloc(1, sizeof(LeInfoRec));
00017     if (le_info == NULL)
00018        return NULL;
00019 
00020     result = le_info_init_m17n_input_methods(le_info);
00021     if (result == LE_FAIL) {
00022         le_info_destroy(le_info);
00023         return NULL;
00024     }
00025 
00026     return le_info;
00027 }
00028 
00029 LeResult le_info_destroy(LeInfoRec * le_info)
00030 {
00031     if (le_info == NULL)
00032        return LE_FAIL;
00033 
00034     le_info_done_m17n_input_methods(le_info);
00035 
00036     free((char *) le_info);
00037 
00038     return LE_OK;
00039 }
00040 
00041 LeResult le_info_print(LeInfoRec * le_info)
00042 {
00043 #ifdef DEBUG
00044     if (le_info == NULL)
00045        return LE_FAIL;
00046 
00047     return LE_OK;
00048 #endif
00049 }
00050 
00051 #define M17N_IM_LIST_NUM_ALLOC  10
00052 int le_info_pushback_m17n_input_method(LeInfoRec *le_info,
00053                                        M17nImInfoRec *m17n_im)
00054 {
00055     int i, num_input_methods;
00056 
00057     if (le_info == NULL || m17n_im == NULL)
00058         return LE_FAIL;
00059 
00060     if (le_info->input_methods == NULL) {
00061         le_info->input_methods = (M17nImInfoRec **) calloc (M17N_IM_LIST_NUM_ALLOC,
00062                                                             sizeof(M17nImInfoRec *));
00063         if (le_info->input_methods == NULL)
00064             return LE_FAIL;
00065     }
00066 
00067     num_input_methods = le_info->num_input_methods;
00068     if ((num_input_methods + 1) % M17N_IM_LIST_NUM_ALLOC == 0) {
00069         int num = num_input_methods + 1 + M17N_IM_LIST_NUM_ALLOC;
00070 
00071         le_info->input_methods = (M17nImInfoRec **)realloc(le_info->input_methods,
00072                                                   num * sizeof(M17nImInfoRec *));
00073         if (le_info->input_methods == NULL)
00074             return LE_FAIL;
00075 
00076         for (i = num_input_methods; i < num; i++)
00077             le_info->input_methods[i] = NULL;
00078     }
00079 
00080     le_info->input_methods[num_input_methods] = m17n_im;
00081     le_info->num_input_methods ++;
00082 
00083     return LE_OK;
00084 }
00085 
00086 int le_info_compare_m17n_input_method (const void *elt1, const void *elt2)
00087 {
00088     const M17nImInfoRec *im1 = elt1;
00089     const M17nImInfoRec *im2 = elt2;
00090     MSymbol lang1, lang2;
00091 
00092     if (im1->language == Mnil)
00093         return 1;
00094     if (im1->language == im2->language)
00095         return strcmp (msymbol_name (im1->name), msymbol_name (im2->name));
00096     if (im1->language == Mt)
00097         return 1;
00098     if (im2->language == Mt)
00099         return -1;
00100 
00101     return strcmp (msymbol_name (im1->language), msymbol_name (im2->language));
00102 }
00103 
00104 LeResult le_info_init_m17n_input_methods(LeInfoRec * le_info)
00105 {
00106     MPlist *imlist, *pl;
00107     MInputMethod *im = NULL;
00108 
00109     int num_input_methods;
00110     M17nImInfoRec *input_methods;
00111 
00112     M17N_INIT ();
00113     if (merror_code != MERROR_NONE) {
00114         fprintf (stderr, "Fail to initialize the m17n library!\n");
00115        return LE_FAIL;
00116     }
00117 
00118     le_info->Miiim_ic = msymbol ("iiim_ic");
00119     le_info->Mkey_english_native = msymbol ("iiim_key_english_native");
00120     le_info->Mkey_switch_next_im = msymbol ("iiim_key_switch_next_im");
00121 
00122     le_info->converter = mconv_buffer_converter(Mcoding_utf_16, NULL, 0);
00123     if (!le_info->converter)
00124         return LE_FAIL;
00125 
00126     imlist = (MPlist *)mdatabase_list (msymbol ("input-method"), Mnil, Mnil, Mnil);
00127     if (imlist == (MPlist *)Mnil) {
00128         mconv_free_converter (le_info->converter);
00129        return LE_FAIL;
00130     }
00131 
00132     num_input_methods = mplist_length (imlist);
00133     if (num_input_methods <= 0) {
00134         mconv_free_converter (le_info->converter);
00135         m17n_object_unref (imlist);
00136        return LE_FAIL;
00137     }
00138 
00139     for (pl = imlist; mplist_key (pl) != Mnil; pl = mplist_next (pl)) {
00140         MDatabase *mdb = mplist_value (pl);
00141         MSymbol *tag = mdatabase_tag (mdb);
00142 
00143         if (tag[1] != Mnil) {
00144             M17nImInfoRec *input_method;
00145 
00146             input_method = (M17nImInfoRec *)calloc(1, sizeof(M17nImInfoRec));
00147             if (input_method == NULL)
00148                 continue;
00149 
00150             input_method->language = tag[1];
00151             input_method->name = tag[2];
00152             input_method->im = NULL;
00153 
00154             DEBUG_printf("lang: %s, name: %s\n",
00155                          msymbol_name(tag[1]), msymbol_name(tag[2]));
00156             le_info_pushback_m17n_input_method(le_info, input_method);
00157         }
00158     }
00159 
00160     m17n_object_unref (imlist);
00161 
00162     qsort(le_info->input_methods, le_info->num_input_methods,
00163           sizeof(le_info->input_methods[0]), le_info_compare_m17n_input_method);
00164 
00165     DEBUG_printf("num_input_methods: %d\n", le_info->num_input_methods);
00166 
00167     return LE_OK;
00168 }
00169 
00170 LeResult le_info_done_m17n_input_methods(LeInfoRec *le_info)
00171 {
00172     int i;
00173     int num_input_methods;
00174     M17nImInfoRec **input_methods;
00175 
00176     if (le_info == NULL)
00177         return LE_OK;
00178 
00179     input_methods = le_info->input_methods;
00180     num_input_methods = le_info->num_input_methods;
00181     if (input_methods) {
00182         for (i = 0; i < num_input_methods; i++) {
00183              if (input_methods[i]->im)
00184                  minput_close_im (input_methods[i]->im);
00185         }
00186         free ((char *) input_methods);
00187     }
00188 
00189     mconv_free_converter (le_info->converter);
00190 
00191     M17N_FINI ();
00192 
00193     return LE_OK;
00194 }
00195 
00196 LeResult le_info_register_ui_callbacks(MInputMethod *im)
00197 {
00198     MPlist *callback_list;
00199 
00200     if (im == (MInputMethod *)Mnil)
00201         return LE_FAIL;
00202 
00203     if (!im->driver.callback_list)
00204         im->driver.callback_list = (MPlist *)mplist();
00205 
00206     callback_list = im->driver.callback_list;
00207 
00208     mplist_add(callback_list, Minput_preedit_start, (void *)le_session_ui_callbacks);
00209     mplist_add(callback_list, Minput_preedit_draw, (void *)le_session_ui_callbacks);
00210     mplist_add(callback_list, Minput_preedit_done, (void *)le_session_ui_callbacks);
00211     mplist_add(callback_list, Minput_status_start, (void *)le_session_ui_callbacks);
00212     mplist_add(callback_list, Minput_status_draw, (void *)le_session_ui_callbacks);
00213     mplist_add(callback_list, Minput_status_done, (void *)le_session_ui_callbacks);
00214     mplist_add(callback_list, Minput_candidates_start, (void *)le_session_ui_callbacks);
00215     mplist_add(callback_list, Minput_candidates_draw, (void *)le_session_ui_callbacks);
00216     mplist_add(callback_list, Minput_candidates_done, (void *)le_session_ui_callbacks);
00217 
00218     return LE_OK;
00219 }
00220 
00221 MInputMethod *le_info_get_input_method_for_locale(LeInfoRec *le_info, char *locale)
00222 {
00223     int i;
00224 
00225     if (le_info == NULL || locale == NULL)
00226         return ((MInputMethod *)Mnil);
00227 
00228     /* find input method which match the given locale */
00229     for (i = 0; i < le_info->num_input_methods; i ++) {
00230         M17nImInfoRec *input_method = le_info->input_methods[i];
00231         MSymbol m_lang, m_name;
00232         char *lang;
00233 
00234         if (input_method == NULL)
00235             continue;
00236 
00237         m_lang = input_method->language;
00238         m_name = input_method->name;
00239         if (m_lang == Mt)
00240             continue;
00241 
00242         lang = msymbol_name(m_lang);
00243         if (!lang || !*lang)
00244             continue;
00245 
00246         if (!strncasecmp(locale, lang, strlen(lang))) {
00247             if (input_method->im == (MInputMethod *)Mnil) {
00248                 input_method->im = minput_open_im(m_lang, m_name, NULL);
00249                 le_info_register_ui_callbacks(input_method->im);
00250             }
00251                 
00252             if (input_method->im != (MInputMethod *)Mnil)
00253                 return (input_method->im);
00254         }
00255     }
00256 
00257     return ((MInputMethod *)Mnil);
00258 }
00259 
00260 MInputMethod *le_info_get_next_input_method_for_locale(LeInfoRec *le_info,
00261                                                        char *locale,
00262                                                        MInputMethod *im)
00263 {
00264     int i;
00265 
00266     MSymbol m_lang, m_name;
00267     M17nImInfoRec *im_info_first = NULL;
00268     M17nImInfoRec *im_info_current = NULL;
00269     M17nImInfoRec *im_info_matched = NULL;
00270 
00271     if (le_info == NULL || locale == NULL)
00272         return ((MInputMethod *)Mnil);
00273 
00274     DEBUG_printf("le_info_get_next_input_method_for_locale: locale: %s, im: %p\n", locale, im);
00275     /* find input method which match the given locale */
00276     for (i = 0; i < le_info->num_input_methods; i ++) {
00277         M17nImInfoRec *input_method = le_info->input_methods[i];
00278         char *lang;
00279 
00280         if (input_method == NULL)
00281             continue;
00282 
00283         m_lang = input_method->language;
00284         m_name = input_method->name;
00285 
00286         lang = msymbol_name(m_lang);
00287         if (!lang || !*lang)
00288             continue;
00289 
00290         DEBUG_printf("input_method[%d]: lang: %s, name: %s, im: %p\n",
00291                 i, lang, msymbol_name(m_name), input_method->im);
00292 
00293         if (strncasecmp(locale, lang, strlen(lang)) && m_lang != Mt)
00294             continue;
00295 
00296         if (im == (MInputMethod *) Mnil) {
00297             im_info_matched = input_method;
00298             break;
00299         }
00300 
00301         if (im_info_first == NULL)
00302             im_info_first = input_method;
00303 
00304         if (input_method->im == im) {
00305             im_info_current = input_method;
00306         } else if (im_info_current != NULL) {
00307             im_info_matched = input_method;
00308             break;
00309         }
00310     }
00311 
00312     DEBUG_printf("im_info_matched: %p, im_info_first: %p\n", im_info_matched, im_info_first);
00313     if (im_info_matched == NULL && im_info_first != NULL)
00314         im_info_matched = im_info_first;
00315 
00316     if (im_info_matched != NULL) {
00317         if (im_info_matched->im == (MInputMethod *)Mnil) {
00318             m_lang = im_info_matched->language;
00319             m_name = im_info_matched->name;
00320 
00321             im_info_matched->im = minput_open_im(m_lang, m_name, NULL);
00322             le_info_register_ui_callbacks(im_info_matched->im);
00323         }
00324         return (im_info_matched->im);
00325     }
00326                 
00327     return ((MInputMethod *)Mnil);
00328 }
00329 
00330 
00331 char *disabled_langs[] = {
00332     "zh",
00333 #if 0
00334     "ko",
00335     "ja"
00336 #endif
00337 };
00338 
00339 int le_info_check_language_disabled(LeInfoRec *le_info, char *lang)
00340 {
00341     int i, num;
00342 
00343     if (!le_info || !lang || !*lang)
00344         return 0;
00345 
00346     num = sizeof(disabled_langs)/sizeof(char *);
00347     for (i = 0; i < num; i ++) {
00348          if (!strcasecmp(lang, disabled_langs[i]))
00349              return 1;
00350     }
00351 
00352     return 0;
00353 }
00354 
00355 typedef struct {
00356     char *m17n_lang_name;
00357     char *standard_lang_name;
00358 } language_name_pair_t;
00359 
00360 language_name_pair_t lang_name_pairs[] = {
00361     { "am", "am_ET" },
00362     { "as", "" },
00363     { "bn", "" },
00364     { "bo", "" },
00365     { "dv", "" },
00366     { "el", "el_GR" },
00367     { "en", "en" },
00368     { "ar", "ar" },
00369     { "fa", "" },
00370     { "gu", "gu_IN" },
00371     { "he", "he" },
00372     { "hi", "hi_IN" },
00373     { "hr", "" },
00374     { "hy", "" },
00375     { "ja", "ja" },
00376     { "ka", "" },
00377     { "kk", "" },
00378     { "km", "" },
00379     { "kn", "kn_IN" },
00380     { "ko", "ko" },
00381     { "lo", "" },
00382     { "ml", "ml_IN" },
00383     { "my", "" },
00384     { "or", "" },
00385     { "pa", "pa_IN" },
00386     { "ru", "ru_RU" },
00387     { "si", "" },
00388     { "sk", "" },
00389     { "sr", "" },
00390     { "ta", "ta_IN" },
00391     { "te", "te_IN" },
00392     { "th", "th_TH" },
00393     { "vi", "vi_VN" },
00394     { "zh", "zh_CN" },
00395 };
00396 
00397 char *le_info_get_standard_language_name(char *lang)
00398 {
00399     int i, num;
00400 
00401     if (!lang || !*lang)
00402         return lang;
00403 
00404     num = sizeof(lang_name_pairs)/sizeof(language_name_pair_t);
00405     for (i = 0; i < num; i ++) {
00406          char *standard_lang_name;
00407          char *m17n_lang_name;
00408 
00409          m17n_lang_name = lang_name_pairs[i].m17n_lang_name;
00410          standard_lang_name =  lang_name_pairs[i].standard_lang_name;
00411 
00412          if (!m17n_lang_name || !*m17n_lang_name)
00413              continue;
00414 
00415          if (!standard_lang_name || !*standard_lang_name)
00416              continue;
00417 
00418          if (!strcasecmp(lang, m17n_lang_name)) {
00419              if (!standard_lang_name || !*standard_lang_name)
00420                  return lang;
00421              else
00422                  return standard_lang_name;
00423          }
00424     }
00425 
00426     return lang;
00427 }