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_LAZY | RTLD_GLOBAL); if (!handle) { FcitxLog(ERROR, _("Frontend: open %s fail %s") , modulePath , dlerror()); break; } if (!CheckABIVersion(handle)) { FcitxLog(ERROR, "%s ABI Version Error", addon->name); dlclose(handle); break; } frontend = dlsym(handle, "frontend"); if (!frontend || !frontend->Create) { FcitxLog(ERROR, _("Frontend: bad frontend")); dlclose(handle); break; } if ((addon->addonInstance = frontend->Create(instance, frontendindex)) == NULL) { dlclose(handle); break; } 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; }