Back to index

im-sdk  12.3.91
LEMgr.cpp
Go to the documentation of this file.
00001 #include <config.h>
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <libgen.h>
00005 #include "LEMgr.hh"
00006 #include "IMInputContext.hh"
00007 #include "IMLog.hh"
00008 #include "IMUtil.hh"
00009 
00010 void
00011 LEMgr::listup_LEs()
00012 {
00013     LEDirectoryInfo di;
00014     DirectoryInfoVec *pdv;
00015 
00016     if (di.refresh(lepath.c_str())) {
00017         pdv = di.get_directory_info();
00018         DirectoryInfoVec::const_iterator i = pdv->begin();
00019         for (; i != pdv->end();++i) {
00020            if (loading_preferred_les) {
00021               /* check if this LE is preferred */
00022               if (iiim_le_xmlconf_is_empty_module(pxmllecfg)) {
00023                   LOG_DEBUG("No LEs are registered. disabling the loading preferred LE feature at this moment.");
00024                   loading_preferred_les = false;
00025               } else {
00026                   string lename = i->dirname + i->filename;
00027                   IIIMLELanguageList *langlist, *langtmp;
00028                   IIIMLEInfoList *lelist, *letmp;
00029 
00030                   langlist = iiim_le_xmlconf_get_lang_list(pxmllecfg);
00031                   for (langtmp = langlist; langtmp != NULL; langtmp = langtmp->next) {
00032                      lelist = iiim_le_xmlconf_get_le_info_list(pxmllecfg, langtmp->language);
00033 
00034                      for (letmp = lelist; letmp != NULL; letmp = letmp->next) {
00035                          if (!strcmp(letmp->data->lename, lename.c_str())) {
00036                             LOG_DEBUG("Matched %s", lename.c_str());
00037                             goto matched;
00038                          }
00039                      }
00040                   }
00041                   LOG_DEBUG("Not matched %s. skipping...", lename.c_str());
00042                   continue;
00043                 matched:;
00044               }
00045            }
00046            LEBase *pleb = new LEBase(i->dirname, i->filename);
00047            // memory error.
00048            if (!pleb) return;
00049            if (pleb->errorp()) {
00050                delete pleb;
00051                continue;
00052            }
00053            lemap.insert(make_pair(i->filename, pleb));
00054         }
00055     }
00056     psunim_default_lebase = new LEBase(LEBase::SUNIM_DEFAULT);
00057     if (!psunim_default_lebase || psunim_default_lebase->errorp()) {
00058        LOG_CRITICAL("Could not create default sunim LE.  Exit.");
00059        // TODO! we should use exception.
00060        exit(255);
00061     }
00062     LEBaseMap::iterator itl;
00063     LEBase* ple;
00064     IMHotkeyManagerStruct *hkm;
00065     IMHotkeyProfileStruct *hkps;
00066     int j, nhkp = 0;
00067 
00068     le_hotkey_profile_map.clear();
00069     for (itl = lemap.begin();itl != lemap.end();++itl) {
00070         ple = itl->second;
00071         hkm = ple->get_hotkey_manager();
00072         if (hkm) {
00073             nhkp = hkm->num_hotkey_profiles;
00074             if (hkm->hkps && nhkp) {
00075                 for (j=0; j<nhkp; j++) {
00076                     hkps = &(hkm->hkps[j]);
00077                    le_hotkey_profile_map.insert(make_pair(hkps, itl->first));
00078                 }
00079             }
00080         }
00081     }
00082 
00083 }
00084 
00085 void
00086 LEMgr::check_new_LEs()
00087 {
00088     LEDirectoryInfo di;
00089     DirectoryInfoVec::iterator i;
00090     DirectoryInfoVec *pdv;
00091 
00092     if (!di.refresh(lepath.c_str())) return;
00093     pdv = di.get_directory_info();
00094     for (i = pdv->begin(); i != pdv->end(); ++i) {
00095        if (lemap.find(i->filename) != lemap.end()) continue;
00096        LEBase *pleb = new LEBase(i->dirname, i->filename);
00097        if (!pleb) return;
00098        if (pleb->errorp()) {
00099            delete pleb;
00100            continue;
00101        }
00102        lemap.insert(make_pair(i->filename, pleb));
00103     }
00104     return;
00105 }
00106 
00107 void
00108 LEMgr::check_reloaded_LEs()
00109 {
00110     LENameVec::iterator itl;
00111     LEBaseMap::iterator pos;
00112     LEBase *ple;
00113     bool reload_f = false;
00114 
00115     if (reload_les.empty()) return;
00116 
00117     for (itl = reload_les.begin(); itl != reload_les.end();) {
00118         pos = lemap.find(*itl);
00119        if (pos == lemap.end()) {
00120            itl = reload_les.erase(itl);
00121            continue;
00122        }
00123        ple = pos->second;
00124 
00125        // remove if reloading LE is failed.
00126        if (ple->errorp()) {
00127            lemap.erase(pos);
00128            reload_f = true;
00129            itl = reload_les.erase(itl);
00130            delete ple;
00131            continue;
00132        }
00133        // succeed to reload
00134        if (!ple->reloadp()) {
00135            itl = reload_les.erase(itl);
00136            reload_f = true;
00137            continue;
00138        }
00139        ++itl;
00140     }
00141 
00142     if (reload_f) {
00143         initialize_ledata();
00144     }
00145 }
00146 
00147 void
00148 LEMgr::reload()
00149 {
00150     LEBaseMap::iterator itl;
00151     LEBase* ple;
00152 
00153     check_new_LEs();
00154     for (itl = lemap.begin(); itl != lemap.end(); ) {
00155         ple = itl->second;
00156         if (!ple->reload()) {
00157            /* TODO */
00158             if (ple->errorp()) {
00159                lemap.erase(itl++);
00160                delete ple;
00161                continue;
00162            }
00163 
00164            LENameVec::iterator pos;
00165            pos = find(reload_les.begin(), reload_les.end(), itl->first);
00166            if (pos == reload_les.end())
00167               reload_les.push_back(itl->first);
00168        }
00169        ++itl;
00170     }
00171     /* reload XML config file */
00172     iiim_le_xmlconf_load_file(pxmllecfg);
00173     /* re-initialized */
00174     initialize_ledata();
00175 }
00176 
00177 bool
00178 LEMgr::initialize_ledata()
00179 {
00180     LEBaseMap::iterator itl;
00181     LEBase* ple;
00182     iml_desktop_t *imdesktop = (iml_desktop_t *)NULL;
00183     const IMLangList *piml;
00184     const IMImeInfoList *pimi;
00185     const IMDescriptorList *pimd;
00186     const IMObjectWithDescList *pimodl;
00187 
00188     langlist.clear();
00189     imeinfolist.clear();
00190     imdesclist.clear();
00191     imobjectdesclist.clear();
00192 
00193     for (itl = lemap.begin();itl != lemap.end();++itl) {
00194        ple = itl->second;
00195         if (!imdesktop) {
00196            imdesktop = ple->get_imldesktop();
00197         }
00198        piml = ple->get_langlist();
00199        if (piml) {
00200            langlist.insert(langlist.end(), piml->begin(), piml->end());
00201        }
00202         pimi = ple->get_imeinfolist();
00203         if (pimi) {
00204             imeinfolist.insert(imeinfolist.end(), pimi->begin(), pimi->end());
00205         }
00206        pimd = ple->get_imdesclist();
00207        if (pimd) {
00208            imdesclist.insert(imdesclist.end(), pimd->begin(), pimd->end());
00209        }
00210        pimodl = ple->get_objectdesclist();
00211        if (pimodl) {
00212            imobjectdesclist.insert(imobjectdesclist.end(),
00213                                 pimodl->begin(), pimodl->end());
00214        }
00215     }
00216 
00217     langlist.sort();
00218     langlist.unique();
00219 
00220     lemgr_dlmap.insert(make_pair(imdesktop, langlist));
00221     lemgr_ddmap.insert(make_pair(imdesktop, imdesclist));
00222 
00223     ledata_inited = true;
00224     return true;
00225 }
00226 
00227 const IMLangList*
00228 LEMgr::get_all_langlist(
00229     iml_desktop_t *curr_desktop
00230 )
00231 {
00232     if (!ledata_inited) {
00233         initialize_ledata();
00234     } else {
00235         check_reloaded_LEs();
00236     }
00237 
00238     LEMgrDesktopLangMap::iterator itdl;
00239 
00240     for (itdl = lemgr_dlmap.begin();itdl != lemgr_dlmap.end();++itdl) {
00241        if (itdl->first == curr_desktop) {
00242            return &itdl->second;
00243        }
00244     }
00245     
00246     return &langlist;
00247 }
00248 
00249 const IMDescriptorList*
00250 LEMgr::get_all_imdesclist(
00251     iml_desktop_t *curr_desktop
00252 )
00253 {
00254     if (!ledata_inited) {
00255         initialize_ledata();
00256     } else {
00257         check_reloaded_LEs();
00258     }
00259     LEMgrDesktopDescMap::iterator itdd;
00260 
00261     for (itdd = lemgr_ddmap.begin(); itdd != lemgr_ddmap.end();++itdd) {
00262        if (itdd->first == curr_desktop) {
00263            return &itdd->second;
00264        }
00265     }
00266     return &imdesclist;
00267 }
00268 
00269 const bool
00270 LEMgr::update_imdesclist(
00271     IMLEName *LEname,
00272     IMLocale *Locales,
00273     int nLocales
00274 )
00275 {
00276     LEBaseMap::iterator itl;
00277     LEBase* ple;
00278     string curr_lename = string(LEname->id);
00279     bool result = false; 
00280     iml_desktop_t *curr_desktop;
00281     IMLangList uimll;
00282     IMImeInfoList uimil;
00283     IMDescriptorList uimdl;
00284     const IMLangList *piml;
00285     const IMImeInfoList *pimi;
00286     const IMDescriptorList *pimd;
00287 
00288     langlist.clear();
00289     imeinfolist.clear();
00290     imdesclist.clear();
00291     for (itl = lemap.begin();itl != lemap.end();++itl) {
00292        ple = itl->second;
00293        if (!itl->first.find(curr_lename)) {
00294            LOG_DEBUG("LEMgr::update_imdesclist: filename [%s], curr_lename [%s]\n",itl->first.c_str(), curr_lename.c_str());
00295            if (result = ple->update_imdesclist(LEname, Locales, nLocales, &curr_desktop, uimll, uimil, uimdl)) {
00296                 langlist.insert(langlist.end(), uimll.begin(), uimll.end());
00297                 imeinfolist.insert(imeinfolist.end(), uimil.begin(), uimil.end());
00298               lemgr_dlmap.insert(make_pair(curr_desktop, langlist));
00299                 imdesclist.insert(imdesclist.end(), uimdl.begin(), uimdl.end());
00300               lemgr_ddmap.insert(make_pair(curr_desktop, imdesclist));
00301            } 
00302        } else {
00303            piml = ple->get_langlist();
00304            if (piml) {
00305               langlist.insert(langlist.end(), piml->begin(), piml->end());
00306            }
00307             pimi = ple->get_imeinfolist();
00308             if (pimi) {
00309                 imeinfolist.insert(imeinfolist.end(), pimi->begin(), pimi->end());
00310             }
00311            pimd = ple->get_imdesclist();
00312            if (pimd) {
00313               imdesclist.insert(imdesclist.end(), pimd->begin(), pimd->end());
00314            }
00315        }
00316     }
00317     return result; 
00318 }
00319 
00320 const IMObjectWithDescList*
00321 LEMgr::get_all_imobjectdesclist()
00322 {
00323     if (!ledata_inited) {
00324         initialize_ledata();
00325     } else {
00326         check_reloaded_LEs();
00327     }
00328     return &imobjectdesclist;
00329 }
00330 
00331 IMHotkeyProfileStruct*
00332 LEMgr::get_hotkey_profiles(int *count_profiles)
00333 {
00334     IMHotkeyProfileStruct *hkps;
00335     size_t count = le_hotkey_profile_map.size();
00336     size_t n;
00337     LEHotkeyProfileMap::iterator itl;
00338 
00339     if (count == 0)
00340        return NULL;
00341 
00342     LOG_DEBUG("LEMgr: get_hotkey_profiles: Number of Profiles [%d]\n", count);
00343     hkps = new IMHotkeyProfileStruct[count];
00344     *count_profiles = count;
00345     for (n = 0, itl = le_hotkey_profile_map.begin(); n < count && itl != le_hotkey_profile_map.end(); ++itl, n++)
00346        hkps[n] = *(itl->first);
00347 
00348     return hkps;
00349 }
00350 
00351 LEContext*
00352 LEMgr::choose_LE(
00353     IMInputContext *pic
00354 )
00355 {
00356     const ICAttribute &attr = pic->get_icattr();
00357     LEBaseMap::iterator itl;
00358     LEBase* ple = NULL;
00359     const IMLangList *pimll;
00360     const IMLang *piml = NULL;
00361     const string *preq_lang = NULL;
00362     const u16string *preq_imdesc = NULL;
00363 
00364     if (!attr.get_inputlanguage().empty()) {
00365        preq_lang = attr.get_inputlanguage().get_string();
00366        if (!preq_lang) goto notfound;
00367     }
00368     if (!attr.get_inputmethod().empty()) {
00369        preq_imdesc = &attr.get_inputmethod();
00370     }
00371 
00372     if (preq_lang)
00373        LOG_DEBUG("requested lang = %s", preq_lang->c_str());
00374     if (preq_imdesc)
00375        LOG_DEBUG("requested desc = %s", preq_imdesc->get_string()->c_str());
00376     if (pxmllecfg != NULL && preq_lang != NULL && preq_imdesc == NULL) {
00377        /* choose LE from the order described in XML config */
00378        IIIMLEInfoList *list, *ltmp;
00379 
00380        LOG_DEBUG("searching LEs with lang %s", preq_lang->c_str());
00381        list = iiim_le_xmlconf_get_le_info_list(pxmllecfg, preq_lang->c_str());
00382 
00383        for (ltmp = list; ltmp != NULL; ltmp = ltmp->next) {
00384            IIIMLEInfo *info = ltmp->data;
00385            char *fname = new char[strlen(info->lename) + 1];
00386            string filename;
00387            string pathname;
00388 
00389            strcpy(fname, info->lename);
00390            filename = basename(fname);
00391            strcpy(fname, info->lename);
00392            pathname = dirname(fname);
00393            /* assume that pathname should be /usr/lib/iiim/le/<LE name>/ or so
00394               and lepath should be /usr/lib/iiim/le or so */
00395            strcpy(fname, pathname.c_str());
00396            pathname = dirname(fname);
00397            delete [] fname;
00398 
00399            LOG_DEBUG("searching module... %s", filename.c_str());
00400            if (lepath[lepath.size()-1] == '/') {
00401               pathname += '/';
00402            }
00403            if (lepath != pathname)
00404               continue;
00405            if ((itl = lemap.find(filename)) == lemap.end()) {
00406               continue;
00407            } else {
00408               ple = itl->second;
00409               break;
00410            }
00411        }
00412        if (ple == NULL) {
00413            LOG_DEBUG("Not found the requested module. trying to find out with the traditional way...");
00414            goto retry_traditional;
00415        }
00416 
00417        return ple->create_lecontext(pic, preq_lang->c_str());
00418     } else if (pxmllecfg != NULL && preq_lang == NULL && preq_imdesc == NULL) {
00419        /* probably the client library couldn't find any LEs they want to use */
00420        goto notfound;
00421     } else {
00422 retry_traditional:
00423        for (itl = lemap.begin();itl != lemap.end();++itl) {
00424            ple = itl->second;
00425 
00426            // choose LE by language.
00427            if (preq_lang) {
00428               IMLangList::const_iterator itlang;
00429               pimll = ple->get_langlist();
00430               if (!pimll) continue;
00431               itlang = find(pimll->begin(), pimll->end(), *preq_lang);
00432               if (itlang != pimll->end()) {
00433                   piml = &*itlang;
00434               } else {
00435                   continue;
00436               }
00437            }
00438 
00439            // choose LE by imname.
00440            if (preq_imdesc) {
00441               IMDescriptorList::const_iterator itimd;
00442               const IMDescriptorList *pimd = ple->get_imdesclist();
00443               if (!pimd) continue;
00444               itimd = find_if(pimd->begin(), pimd->end(),
00445                             IMDescriptorMatchPredicate(preq_imdesc));
00446               if (itimd != pimd->end()) {
00447                   break;
00448               } else {
00449                   continue;
00450               }
00451            }
00452            break;
00453        }
00454        if (itl == lemap.end()) goto notfound;
00455 
00456        if (piml) {
00457            return ple->create_lecontext(pic, piml->get_id());
00458        }
00459     }
00460 
00461     return ple->create_lecontext(pic, NULL);
00462 
00463 notfound:
00464     LOG_DEBUG("Using sumim_default");
00465     return psunim_default_lebase->create_lecontext(pic, NULL);
00466 }
00467 
00468 void
00469 LEMgr::set_nsmap_config(
00470     IMNsMapStruct *nsm,
00471     int count
00472 )
00473 {
00474     LEBaseMap::iterator itl;
00475     LEBase* ple;
00476 
00477     for (itl = lemap.begin();itl != lemap.end();++itl) {
00478        ple = itl->second;
00479        ple->set_nsmap_config(nsm, count);
00480     }
00481 }
00482 
00483 LEMgr::LEMgr(
00484     const char* x_lepath
00485 )
00486 {
00487     lepath = x_lepath;
00488     pxmllecfg = NULL;
00489     ledata_inited = false;
00490     listup_LEs();
00491 }
00492 
00493 LEMgr::LEMgr(
00494     const char *x_lepath,
00495     IIIMLEXMLConf &xml
00496 )
00497 {
00498     lepath = x_lepath;
00499     pxmllecfg = &xml;
00500     ledata_inited = false;
00501     loading_preferred_les = false;
00502     listup_LEs();
00503 }
00504 
00505 LEMgr::LEMgr(
00506     const char *x_lepath,
00507     IIIMLEXMLConf &xml,
00508     bool preferred_loading
00509 )
00510 {
00511     lepath = x_lepath;
00512     pxmllecfg = &xml;
00513     ledata_inited = false;
00514     loading_preferred_les = preferred_loading;
00515     listup_LEs();
00516 }
00517 
00518 LEMgr::~LEMgr()
00519 {
00520     delete_all(lemap);
00521     delete psunim_default_lebase;
00522     lemgr_dlmap.clear();
00523     lemgr_ddmap.clear();
00524 }
00525 
00526 /* Local Variables: */
00527 /* c-file-style: "iiim-project" */
00528 /* End: */