FCITX_EXPORT_API boolean FcitxInstanceLoadFrontend(FcitxInstance* instance) { UT_array* addons = &instance->addons; UT_array* frontends = &instance->frontends; FcitxAddon *addon; int frontendindex = 0; utarray_clear(frontends); for (addon = (FcitxAddon *) utarray_front(addons); addon != NULL; addon = (FcitxAddon *) utarray_next(addons, addon)) { if (addon->bEnabled && addon->category == AC_FRONTEND) { char *modulePath; switch (addon->type) { case AT_SHAREDLIBRARY: { FILE *fp = FcitxXDGGetLibFile(addon->library, "r", &modulePath); void *handle; FcitxFrontend* frontend; if (!fp) break; fclose(fp); handle = dlopen(modulePath, RTLD_NOW | RTLD_GLOBAL); if (!handle) { FcitxLog(ERROR, _("Frontend: open %s fail %s") , modulePath , dlerror()); break; } if (!FcitxCheckABIVersion(handle, addon->name)) { FcitxLog(ERROR, "%s ABI Version Error", addon->name); dlclose(handle); break; } frontend = FcitxGetSymbol(handle, addon->name, "frontend"); if (!frontend || !frontend->Create) { FcitxLog(ERROR, _("Frontend: bad frontend")); dlclose(handle); break; } if ((addon->addonInstance = frontend->Create(instance, frontendindex)) == NULL) { dlclose(handle); break; } if (instance->loadingFatalError) return false; addon->frontend = frontend; frontendindex ++; utarray_push_back(frontends, &addon); } break; default: break; } free(modulePath); } } if (utarray_len(&instance->frontends) <= 0) { FcitxLog(ERROR, _("No available frontend")); return false; } return true; }
boolean FcitxUILoadInternal(FcitxInstance* instance, FcitxAddon* addon) { boolean success = false; char *modulePath; switch (addon->type) { case AT_SHAREDLIBRARY: { FILE *fp = FcitxXDGGetLibFile(addon->library, "r", &modulePath); void *handle; if (!fp) break; fclose(fp); handle = dlopen(modulePath, RTLD_NOW | (addon->loadLocal ? RTLD_LOCAL : RTLD_GLOBAL)); if (!handle) { FcitxLog(ERROR, _("UI: open %s fail %s") , modulePath , dlerror()); break; } if (!FcitxCheckABIVersion(handle, addon->name)) { FcitxLog(ERROR, "%s ABI Version Error", addon->name); dlclose(handle); break; } addon->ui = FcitxGetSymbol(handle, addon->name, "ui"); if (!addon->ui || !addon->ui->Create) { FcitxLog(ERROR, _("UI: bad ui")); dlclose(handle); break; } if ((addon->addonInstance = addon->ui->Create(instance)) == NULL) { dlclose(handle); break; } /* some may register before ui load, so load it here */ if (addon->ui->RegisterStatus) { UT_array* uistats = &instance->uistats; FcitxUIStatus *status; for (status = (FcitxUIStatus *) utarray_front(uistats); status != NULL; status = (FcitxUIStatus *) utarray_next(uistats, status)) addon->ui->RegisterStatus(addon->addonInstance, status); } /* some may register before ui load, so load it here */ if (addon->ui->RegisterComplexStatus) { UT_array* uicompstats = &instance->uicompstats; FcitxUIComplexStatus *status; for (status = (FcitxUIComplexStatus *) utarray_front(uicompstats); status != NULL; status = (FcitxUIComplexStatus *) utarray_next(uicompstats, status)) addon->ui->RegisterComplexStatus(addon->addonInstance, status); } if (addon->ui->RegisterMenu) { UT_array* uimenus = &instance->uimenus; FcitxUIMenu **menupp; for (menupp = (FcitxUIMenu **) utarray_front(uimenus); menupp != NULL; menupp = (FcitxUIMenu **) utarray_next(uimenus, menupp)) addon->ui->RegisterMenu(addon->addonInstance, *menupp); } success = true; } break; default: break; } free(modulePath); return success; }