DBusMessage* FcitxDBusMenuGetLayout(FcitxNotificationItem* notificationitem, DBusMessage* message) { /* signature iias */ DBusMessageIter args; dbus_message_iter_init(message, &args); DBusMessage* reply = NULL; int32_t id, recursionDepth; do { if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_INT32) break; dbus_message_iter_get_basic(&args, &id); dbus_message_iter_next(&args); if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_INT32) break; dbus_message_iter_get_basic(&args, &recursionDepth); dbus_message_iter_next(&args); if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) break; DBusMessageIter sub; dbus_message_iter_recurse(&args, &sub); FcitxStringHashSet* properties = NULL; while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) { char* property; dbus_message_iter_get_basic(&sub, &property); if (!fcitx_utils_string_hash_set_contains(properties, property)) { properties = fcitx_utils_string_hash_set_insert(properties, property); } dbus_message_iter_next(&sub); } reply = dbus_message_new_method_return(message); /* out put is u(ia{sv}av) */ DBusMessageIter iter; dbus_message_iter_init_append(reply, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, ¬ificationitem->revision); FcitxDBusMenuFillLayooutItem(notificationitem, id, recursionDepth, properties, &iter); fcitx_utils_free_string_hash_set(properties); } while(0); if (!reply) { reply = FcitxDBusPropertyUnknownMethod(message); } return reply; }
/** * 加载标点词典 * @param void * @return void * @note 文件中数据的格式为: 对应的英文符号 中文标点 <中文标点> * 加载标点词典。标点词典定义了一组标点转换,如输入‘.’就直接转换成‘。’ */ boolean LoadPuncDict(FcitxPuncState* puncState) { FcitxStringHashSet* puncfiles = FcitxXDGGetFiles("data", PUNC_DICT_FILENAME "." , NULL); FcitxStringHashSet *curpuncfile = puncfiles; FcitxPunc* punc; while (curpuncfile) { punc = LoadPuncFile(curpuncfile->name); if (punc) HASH_ADD_KEYPTR(hh, puncState->puncSet, punc->langCode, strlen(punc->langCode), punc); curpuncfile = curpuncfile->hh.next; } fcitx_utils_free_string_hash_set(puncfiles); return true; }
DBusMessage* FcitxDBusMenuGetGroupProperties(FcitxNotificationItem* notificationitem, DBusMessage* message) { /* signature aias */ DBusMessageIter args; dbus_message_iter_init(message, &args); DBusMessage* reply = NULL; do { if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) break; DBusMessageIter sub; dbus_message_iter_recurse(&args, &sub); UT_array ids; utarray_init(&ids, &ut_int32_icd); while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_INT32) { int32_t id; dbus_message_iter_get_basic(&sub, &id); utarray_push_back(&ids, &id); dbus_message_iter_next(&sub); } dbus_message_iter_next(&args); dbus_message_iter_recurse(&args, &sub); FcitxStringHashSet* properties = NULL; if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) { utarray_done(&ids); break; } while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) { char* property; dbus_message_iter_get_basic(&sub, &property); if (!fcitx_utils_string_hash_set_contains(properties, property)) { properties = fcitx_utils_string_hash_set_insert(properties, property); } dbus_message_iter_next(&sub); } reply = dbus_message_new_method_return(message); /* out put is a(ia{sv}) */ DBusMessageIter iter; dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ia{sv})", &sub); int i = 0; for (; i < utarray_len(&ids); i ++) { int32_t id = *(int32_t*) utarray_eltptr(&ids, i); DBusMessageIter ssub; dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &ssub); dbus_message_iter_append_basic(&ssub, DBUS_TYPE_INT32, &id); FcitxDBusMenuFillProperty(notificationitem, id, properties, &ssub); dbus_message_iter_close_container(&sub, &ssub); } dbus_message_iter_close_container(&iter, &sub); utarray_done(&ids); fcitx_utils_free_string_hash_set(properties); } while(0); if (!reply) { reply = FcitxDBusPropertyUnknownMethod(message); } return reply; }
FcitxAddon* FcitxAddonsLoadInternal(UT_array* addons, boolean reloadIM) { char **addonPath; size_t len; size_t start; if (!reloadIM) utarray_clear(addons); start = utarray_len(addons); FcitxStringHashSet* sset = FcitxXDGGetFiles("addon", NULL, ".conf"); addonPath = FcitxXDGGetPathWithPrefix(&len, "addon"); char *paths[len]; HASH_FOREACH(string, sset, FcitxStringHashSet) { // FIXME: if it will cause realloc, then it's evil for fcitx 4.2 series if (reloadIM && addons->i == addons->n) { break; } int i; for (i = len - 1; i >= 0; i--) { fcitx_utils_alloc_cat_str(paths[i], addonPath[len - i - 1], "/", string->name); FcitxLog(DEBUG, "Load Addon Config File:%s", paths[i]); } FcitxConfigFile* cfile = FcitxConfigParseMultiConfigFile(paths, len, FcitxAddonGetConfigDesc()); if (cfile) { utarray_extend_back(addons); FcitxAddon *a = (FcitxAddon*) utarray_back(addons); utarray_init(&a->functionList, fcitx_ptr_icd); FcitxAddonConfigBind(a, cfile, FcitxAddonGetConfigDesc()); FcitxConfigBindSync((FcitxGenericConfig*)a); FcitxLog(DEBUG, _("Addon Config %s is %s"), string->name, (a->bEnabled) ? "Enabled" : "Disabled"); boolean error = false; if (reloadIM) { if (a->category != AC_INPUTMETHOD) error = true; } /* if loaded, don't touch the old one */ if (FcitxAddonsGetAddonByNameInternal(addons, a->name, true) != a) error = true; if (error) utarray_pop_back(addons); else FcitxLog(INFO, _("Load Addon Config File:%s"), string->name); } for (i = len - 1;i >= 0;i--) { free(paths[i]); } } FcitxXDGFreePath(addonPath); fcitx_utils_free_string_hash_set(sset); size_t to = utarray_len(addons); utarray_sort_range(addons, AddonPriorityCmp, start, to); return (FcitxAddon*)utarray_eltptr(addons, start); }