void FcitxXkbOptionGroupInfoFree(void* arg) { FcitxXkbOptionGroupInfo* optionGroupInfo = (FcitxXkbOptionGroupInfo*) arg; fcitx_utils_free(optionGroupInfo->name); fcitx_utils_free(optionGroupInfo->description); utarray_free(optionGroupInfo->optionInfos); }
void FcitxXkbVariantInfoFree(void* arg) { FcitxXkbVariantInfo* variantInfo = (FcitxXkbVariantInfo*) arg; fcitx_utils_free(variantInfo->name); fcitx_utils_free(variantInfo->description); utarray_free(variantInfo->languages); }
void SpellCustomFreeDict(FcitxSpell *spell, SpellCustomDict *dict) { fcitx_utils_free(dict->map); fcitx_utils_free(dict->words); free(dict); }
void FreeAutoEng(void* arg) { FcitxAutoEngState *autoEngState = (FcitxAutoEngState*)arg; AutoEngFreeList(autoEngState); fcitx_utils_free(autoEngState->buf); fcitx_utils_free(autoEngState->back_buff); }
void FcitxXkbModelInfoFree(void* arg) { FcitxXkbModelInfo* modelInfo = (FcitxXkbModelInfo*) arg; fcitx_utils_free(modelInfo->name); fcitx_utils_free(modelInfo->description); fcitx_utils_free(modelInfo->vendor); }
void FcitxIsoCodes639EntryFree(FcitxIsoCodes639Entry* entry) { fcitx_utils_free(entry->iso_639_1_code); fcitx_utils_free(entry->iso_639_2B_code); fcitx_utils_free(entry->iso_639_2T_code); fcitx_utils_free(entry->name); free(entry); }
char* py_enhance_stroke_get_str(const uint8_t *stroke, unsigned int s_l, char *str, unsigned int *len) { const PyEnhanceStrLen *static_buff[256]; void *tofree; const PyEnhanceStrLen **buff; if (fcitx_likely(s_l <= 256)) { tofree = NULL; buff = static_buff; } else { tofree = malloc(sizeof(const PyEnhanceStrLen*) * s_l); buff = tofree; } unsigned int i; *len = 0; for (i = 0;i < s_l;i++) { buff[i] = py_enhance_stroke_get_char(stroke[i]); *len += buff[i]->len; } if (!str) str = malloc(*len + 1); unsigned int accum_len = 0; for (i = 0;i < s_l;i++) { memcpy(str + accum_len, buff[i]->str, buff[i]->len); accum_len += buff[i]->len; } fcitx_utils_free(tofree); str[*len] = '\0'; return str; }
void FcitxNotificationItemGetToolTip(void* arg, DBusMessageIter* iter) { FcitxNotificationItem* notificationitem = (FcitxNotificationItem*) arg; DBusMessageIter sub, ssub; char* iconNameToFree = NULL, *iconName, *title, *content; dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, 0, &sub); FcitxInputContext* ic = FcitxInstanceGetCurrentIC(notificationitem->owner); if (ic == NULL) { iconName = "input-keyboard"; title = _("No input window"); content = ""; } else { iconName = FcitxNotificationItemGetIconNameString(notificationitem); iconNameToFree = iconName; FcitxIM* im = FcitxInstanceGetCurrentIM(notificationitem->owner); title = im ? im->strName : _("Disabled"); content = im ? "" : _("Input Method Disabled"); } dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &iconName); dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "(iiay)", &ssub); dbus_message_iter_close_container(&sub, &ssub); dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &title); dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &content); dbus_message_iter_close_container(iter, &sub); fcitx_utils_free(iconNameToFree); }
void PinyinEnhanceMapLoad(PyEnhanceMap **map, FcitxMemoryPool *pool, FILE *fp) { char *buff = NULL; char *key; char *word; int key_l; int word_l; size_t len; while (getline(&buff, &len, fp) != -1) { /* remove leading spaces */ key = buff + strspn(buff, PYENHANCE_MAP_BLANK); /* empty line or comment */ if (*key == '\0' || *key == '#') continue; /* find delimiter */ key_l = strcspn(key, PYENHANCE_MAP_BLANK); if (!key_l) continue; word = key + key_l; *word = '\0'; word++; /* find start of word */ word = word + strspn(word, PYENHANCE_MAP_BLANK); word_l = strcspn(word, PYENHANCE_MAP_BLANK); if (!word_l) continue; word[word_l] = '\0'; PinyinEnhanceMapAdd(map, pool, key, key_l, word, word_l); } fcitx_utils_free(buff); }
static void ClipboardDestroy(void *arg) { FcitxClipboard *clipboard = (FcitxClipboard*)arg; ClipboardWriteHistory(clipboard); fcitx_utils_free(clipboard->primary.str); free(arg); }
void FcitxXkbRulesFree(FcitxXkbRules* rules) { if (!rules) return; utarray_free(rules->layoutInfos); utarray_free(rules->modelInfos); utarray_free(rules->optionGroupInfos); fcitx_utils_free(rules->version); free(rules); }
void py_enhance_stroke_load_tree(PyEnhanceStrokeTree *tree, FILE *fp) { char *buff = NULL; char *key; char *word; unsigned int key_l; int word_l; size_t len; memset(tree, 0, sizeof(PyEnhanceStrokeTree)); /** * init each entry to the key_id (single and double) * or other odd numbers (multiple). **/ unsigned int i; for (i = 0;i < sizeof(tree->table) / sizeof(uint32_t);i++) tree->table[i] = i * 2 + 1; /** * reserve some space before loading to avoid repeating realloc **/ py_enhance_buff_reserve(&tree->keys, 1024 * 1024 / 2 * 3); py_enhance_buff_reserve(&tree->words, 1024 * 1024); while (getline(&buff, &len, fp) != -1) { /* remove leading spaces */ key = buff + strspn(buff, PYENHANCE_MAP_BLANK); /* empty line or comment */ if (*key == '\0' || *key == '#') continue; /* find delimiter */ key_l = strspn(key, "12345"); if (fcitx_unlikely(key_l == 0 || key_l > 0xff)) continue; word = key + key_l; word_l = strspn(word, PYENHANCE_MAP_BLANK); if (!word_l) continue; *word = '\0'; word += word_l; word_l = strcspn(word, PYENHANCE_MAP_BLANK); if (fcitx_unlikely(word_l == 0 || word_l > UTF8_MAX_LENGTH)) continue; word[word_l] = '\0'; word_l++; for (i = 0;i < key_l;i++) key[i] -= '1'; py_enhance_stroke_add_word(tree, (uint8_t*)key, key_l, word, word_l); } py_enhance_stroke_load_finish(tree); py_enhance_buff_shrink(&tree->keys); py_enhance_buff_shrink(&tree->words); fcitx_utils_free(buff); }
void ChttransEnabledForIMFilter(FcitxGenericConfig* config, FcitxConfigGroup* group, FcitxConfigOption* option, void* value, FcitxConfigSync sync, void* arg) { FcitxChttrans* chttrans = (FcitxChttrans*) config; char** enableForIM = (char**) value; if (sync == Value2Raw) { fcitx_utils_free(*enableForIM); *enableForIM = fcitx_string_map_to_string(chttrans->enableIM, ','); } else if (sync == Raw2Value) { if (*enableForIM) { fcitx_string_map_from_string(chttrans->enableIM, *enableForIM, ','); } } }
void FcitxRimeDestroy(void* arg) { FcitxRime* rime = (FcitxRime*) arg; if (rime->session_id) { rime->api->destroy_session(rime->session_id); rime->session_id = 0; } FcitxUIUnRegisterMenu(rime->owner, &rime->schemamenu); FcitxMenuFinalize(&rime->schemamenu); fcitx_utils_free(rime->iconname); rime->api->finalize(); free(rime); }
FCITX_EXPORT_API int fcitx_utils_calculate_record_number(FILE* fpDict) { char *strBuf = NULL; size_t bufLen = 0; int nNumber = 0; while (getline(&strBuf, &bufLen, fpDict) != -1) { nNumber++; } rewind(fpDict); fcitx_utils_free(strBuf); return nNumber; }
SkinImage* GetIMIcon(FcitxClassicUI* classicui, FcitxSkin *sc, const char* fallbackIcon, int flag, boolean fallbackToDefault) { FcitxIM* im = FcitxInstanceGetCurrentIM(classicui->owner); if (!im) return NULL; const char *path; char *tmpstr = NULL; if (im->strIconName[0] == '/') { path = im->strIconName; } else { fcitx_utils_alloc_cat_str(tmpstr, im->strIconName, ".png"); path = tmpstr; } SkinImage *imicon = NULL; if (strncmp(im->uniqueName, "fcitx-keyboard-", strlen("fcitx-keyboard-")) == 0) { SkinImage* activeIcon = LoadImage(sc, fallbackIcon, fallbackToDefault); char temp[LANGCODE_LENGTH + 1] = { '\0', }; char* iconText = 0; if (*im->langCode) { strncpy(temp, im->langCode, LANGCODE_LENGTH); iconText = temp; iconText[0] = toupper(iconText[0]); } else { iconText = im->uniqueName + strlen("fcitx-keyboard-"); } imicon = LoadImageWithText( classicui, sc, path, iconText, cairo_image_surface_get_width(activeIcon->image), cairo_image_surface_get_height(activeIcon->image), true); } if (imicon == NULL) imicon = LoadImage(sc, path, flag); fcitx_utils_free(tmpstr); if (imicon == NULL) { imicon = LoadImage(sc, fallbackIcon, fallbackToDefault); } else { SkinImage* activeIcon = LoadImage(sc, fallbackIcon, fallbackToDefault); if (activeIcon) { ResizeSurface(&imicon->image, cairo_image_surface_get_width(activeIcon->image), cairo_image_surface_get_height(activeIcon->image)); } } return imicon; }
static void CloudSetClientPreedit(FcitxCloudPinyin *cloudpinyin, const char *str) { FcitxInputState *input = FcitxInstanceGetInputState(cloudpinyin->owner); FcitxMessages *message = FcitxInputStateGetClientPreedit(input); char *py; char *string = GetCurrentString(cloudpinyin, &py); FcitxMessagesSetMessageCount(message, 0); if (py) { *py = '\0'; FcitxMessagesAddMessageAtLast(message, MSG_INPUT, "%s%s", string, str); } else { FcitxMessagesAddMessageAtLast(message, MSG_INPUT, "%s", str); } fcitx_utils_free(string); FcitxInstanceUpdateClientSideUI( cloudpinyin->owner, FcitxInstanceGetCurrentIC(cloudpinyin->owner)); }
static int check_im_type(PinyinEnhance *pyenhance) { FcitxIM *im = FcitxInstanceGetCurrentIM(pyenhance->owner); if (!im) return PY_IM_INVALID; if (strcmp(im->uniqueName, "pinyin") == 0 || strcmp(im->uniqueName, "pinyin-libpinyin") == 0 || strcmp(im->uniqueName, "googlepinyin") == 0 || strcmp(im->uniqueName, "shuangpin-libpinyin") == 0) return PY_IM_PINYIN; if (strcmp(im->uniqueName, "shuangpin") == 0) return PY_IM_SHUANGPIN; if (strcmp(im->uniqueName, "sunpinyin") == 0) { boolean sp = false; char *str; FCITX_DEF_MODULE_ARGS(args, "", &sp); str = FcitxSunPinyinInvokeGetFullPinyin(im->owner->owner, args); fcitx_utils_free(str); return sp ? PY_IM_SHUANGPIN : PY_IM_PINYIN; } return PY_IM_INVALID; }
static void ApplyClipboardConfig(FcitxClipboard *clipboard) { FcitxClipboardConfig *config = &clipboard->config; if (config->history_len < 1) { config->history_len = 1; } else if (config->history_len > CLIPBOARD_MAX_LEN) { config->history_len = CLIPBOARD_MAX_LEN; } while (clipboard->clp_hist_len > (uint32_t)config->history_len) { char *str = clipboard->clp_hist_lst[--clipboard->clp_hist_len].str; fcitx_utils_free(str); } if (fcitx_unlikely(config->choose_modifier >= _CBCM_COUNT)) config->choose_modifier = _CBCM_COUNT - 1; ClipboardWriteHistory(clipboard); if (config->cand_max_len < CAND_MAX_LEN_MIN) { config->cand_max_len = CAND_MAX_LEN_MIN; } else if (config->cand_max_len > CAND_MAX_LEN_MAX) { config->cand_max_len = CAND_MAX_LEN_MAX; } clipboard->cand_half_len = (config->cand_max_len - strlen(CLIPBOARD_CAND_SEP)) / 2; }
void py_enhance_stroke_load_tree(PyEnhanceStrokeTree *tree, FILE *fp, FcitxMemoryPool *pool) { char *buff = NULL; char *key; char *word; int key_l; int word_l; size_t len; memset(tree, 0, sizeof(PyEnhanceStrokeTree)); while (getline(&buff, &len, fp) != -1) { /* remove leading spaces */ key = buff + strspn(buff, PYENHANCE_MAP_BLANK); /* empty line or comment */ if (*key == '\0' || *key == '#') continue; /* find delimiter */ key_l = strspn(key, "12345"); if (!key_l) continue; word = key + key_l; word_l = strspn(word, PYENHANCE_MAP_BLANK); if (!word_l) continue; *word = '\0'; word += word_l; word_l = strcspn(word, PYENHANCE_MAP_BLANK); if (!word_l) continue; word[word_l] = '\0'; word_l++; py_enhance_stroke_add_word(tree, pool, key, key_l, word, word_l); } fcitx_utils_free(buff); }
/** * 该函数装载data/gbks2t.tab的简体转繁体的码表, * 然后按码表将GBK字符转换成GBK繁体字符。 * * WARNING: 该函数返回新分配内存字符串,请调用者 * 注意释放。 */ char *ConvertGBKTradition2Simple(FcitxChttrans* transState, const char *strHZ) { if (strHZ == NULL) return NULL; switch (transState->engine) { case ENGINE_OPENCC: #ifdef ENABLE_OPENCC do { if (transState->odt2s == NULL) { OpenCCInit(transState); if (transState->odt2s == NULL) { break; } } char * res = OpenCCConvert(transState->odt2s, strHZ, (size_t) - 1); if (!res || res == (char *) - 1) { return NULL; } return res; } while(0); #endif case ENGINE_NATIVE: { FILE *fp; char *ret; int i, len, ret_len; const char *ps; if (!transState->t2s_table) { char *strBuf = NULL; size_t bufLen = 0; fp = FcitxXDGGetFileWithPrefix("data", TABLE_GBKS2T, "r", NULL); if (!fp) { ret = (char *) malloc(sizeof(char) * (strlen(strHZ) + 1)); strcpy(ret, strHZ); return ret; } while (getline(&strBuf, &bufLen, fp) != -1) { simple2trad_t *t2s = NULL; char *ps; uint32_t wc; ps = fcitx_utf8_get_char(strBuf, &wc); HASH_FIND_INT(transState->s2t_table, &wc, t2s); if (t2s) { continue; } t2s = (simple2trad_t*) malloc(sizeof(simple2trad_t)); fcitx_utf8_get_char(ps, &wc); t2s->wc = wc; t2s->len = fcitx_utf8_char_len(strBuf); strncpy(t2s->str, strBuf, t2s->len); t2s->str[t2s->len] = '\0'; HASH_ADD_INT(transState->t2s_table, wc, t2s); } fcitx_utils_free(strBuf); } i = 0; len = fcitx_utf8_strlen(strHZ); ret_len = 0; ret = fcitx_utils_malloc0(UTF8_MAX_LENGTH * len + 1); ps = strHZ; ret[0] = '\0'; for (; i < len; ++i) { uint32_t wc; simple2trad_t *t2s = NULL; int chr_len = fcitx_utf8_char_len(ps); char *nps; nps = fcitx_utf8_get_char(ps , &wc); HASH_FIND_INT(transState->t2s_table, &wc, t2s); if (t2s) { strcat(ret, t2s->str); ret_len += t2s->len; } else { strncat(ret, ps, chr_len); ret_len += chr_len; } ps = nps; } ret[ret_len] = '\0'; return ret; } } return NULL; }
void CloudPinyinHandleRequest(FcitxCloudPinyin* cloudpinyin, CurlQueue* queue) { if (queue->type == RequestKey) { cloudpinyin->isrequestkey = false; if (queue->source != cloudpinyin->config.source) return; if (queue->http_code == 200) { if (engine[cloudpinyin->config.source].ParseKey) engine[cloudpinyin->config.source].ParseKey(cloudpinyin, queue); } } else if (queue->type == RequestPinyin) { if (queue->http_code == 200 && cloudpinyin->config.source == queue->source) { char *realstring = engine[cloudpinyin->config.source].ParsePinyin(cloudpinyin, queue); if (realstring) { CloudPinyinCache* cacheEntry = CloudPinyinCacheLookup(cloudpinyin, queue->pinyin); if (cacheEntry == NULL) cacheEntry = CloudPinyinAddToCache(cloudpinyin, queue->pinyin, realstring); FcitxIM* im = FcitxInstanceGetCurrentIM(cloudpinyin->owner); char* strToFree = NULL, *inputString; strToFree = GetCurrentString(cloudpinyin, &inputString); if (inputString) { FcitxLog(DEBUG, "fill: %s %s", inputString, queue->pinyin); if (strcmp(inputString, queue->pinyin) == 0) { if (CHECK_VALID_IM) { CloudPinyinFillCandidateWord(cloudpinyin, inputString); } } } if (strToFree) free(strToFree); free(realstring); } } if (queue->http_code != 200) { cloudpinyin->errorcount ++; if (cloudpinyin->errorcount > MAX_ERROR) { cloudpinyin->initialized = false; cloudpinyin->key[0] = '\0'; cloudpinyin->errorcount = 0; } } } CloudPinyinReleaseCurlHandle(cloudpinyin, queue->curl); fcitx_utils_free(queue->str); fcitx_utils_free(queue->pinyin); free(queue); }
static int fxaddon_scan_addon(FILE *ifp, FILE *ofp) { FcitxDesktopFile dfile; char *buff = NULL; unsigned int i; char **p; if (!fcitx_desktop_file_init(&dfile, NULL, NULL)) return 1; if (!fcitx_desktop_file_load_fp(&dfile, ifp)) return 1; fclose(ifp); FcitxDesktopGroup *addon_grp; FcitxDesktopEntry *tmp_ety; addon_grp = fcitx_desktop_file_find_group(&dfile, "FcitxAddon"); if (!addon_grp) return 1; tmp_ety = fcitx_desktop_group_find_entry(addon_grp, "Name"); if (!tmp_ety) return 1; const char *name = tmp_ety->value; tmp_ety = fcitx_desktop_group_find_entry(addon_grp, "Prefix"); if (!tmp_ety) return 1; const char *prefix = tmp_ety->value; UT_array macros; fxaddon_load_numbered_entries(¯os, addon_grp, "Macro", false); UT_array includes; fxaddon_load_numbered_entries(&includes, addon_grp, "Include", false); UT_array functions; fxaddon_load_numbered_entries(&functions, addon_grp, "Function", true); fxaddon_write_copyright(ofp); size_t name_len = strlen(name); buff = fcitx_utils_set_str_with_len(buff, name, name_len); fxaddon_name_to_macro(buff); _write_str(ofp, "\n#ifndef __FCITX_MODULE_"); _write_len(ofp, buff, name_len); _write_str(ofp, "_H\n"); _write_str(ofp, "#define __FCITX_MODULE_"); _write_len(ofp, buff, name_len); _write_str(ofp, "_H\n" "\n" "#ifdef __cplusplus\n" "extern \"C\" {\n" "#endif\n" "\n"); for (i = 0;i < utarray_len(¯os);i++) { p = (char**)_utarray_eltptr(¯os, i); fxaddon_write_macro(ofp, &dfile, *p); } fxaddon_write_includes(ofp, &includes); utarray_done(&includes); _write_str(ofp, "DEFINE_GET_ADDON(\""); _write_len(ofp, name, name_len); _write_str(ofp, "\", "); _write_str(ofp, prefix); _write_str(ofp, ")\n\n"); for (i = 0;i < utarray_len(&functions);i++) { p = (char**)_utarray_eltptr(&functions, i); fxaddon_write_function(ofp, &dfile, prefix, *p, i); } _write_str(ofp, "\n" "#ifdef __cplusplus\n" "}\n" "#endif\n" "\n" "#endif\n"); fclose(ofp); fcitx_utils_free(buff); fcitx_desktop_file_done(&dfile); utarray_done(&functions); return 0; }
void FcitxXkbOptionInfoFree(void* arg) { FcitxXkbOptionInfo* optionInfo = (FcitxXkbOptionInfo*) arg; fcitx_utils_free(optionInfo->name); fcitx_utils_free(optionInfo->description); }
void* DBusCreate(FcitxInstance* instance) { FcitxDBus *dbusmodule = (FcitxDBus*) fcitx_utils_malloc0(sizeof(FcitxDBus)); FcitxAddon* dbusaddon = FcitxAddonsGetAddonByName(FcitxInstanceGetAddons(instance), FCITX_DBUS_NAME); dbusmodule->owner = instance; DBusError err; if (FcitxInstanceIsTryReplace(instance)) { fcitx_utils_launch_tool("fcitx-remote", "-e"); sleep(1); } dbus_threads_init_default(); // first init dbus dbus_error_init(&err); int retry = 0; DBusConnection* conn = NULL; char* servicename = NULL; asprintf(&servicename, "%s-%d", FCITX_DBUS_SERVICE, fcitx_utils_get_display_number()); /* do session dbus initialize */ do { if (!getenv("DISPLAY") && !getenv("DBUS_SESSION_BUS_ADDRESS")) { FcitxLog(WARNING, "Without DISPLAY or DBUS_SESSION_BUS_ADDRESS session bus will not work"); break; } /* try to get session dbus */ while (1) { conn = dbus_bus_get(DBUS_BUS_SESSION, &err); if (dbus_error_is_set(&err)) { FcitxLog(WARNING, "Connection Error (%s)", err.message); dbus_error_free(&err); dbus_error_init(&err); } if (NULL == conn && retry < MAX_RETRY_TIMES) { retry ++; sleep(RETRY_INTERVAL * retry); } else { break; } } if (NULL == conn) { break; } if (!dbus_connection_add_filter(conn, DBusModuleFilter, dbusmodule, NULL)) break; if (!dbus_connection_set_watch_functions(conn, DBusAddWatch, DBusRemoveWatch, NULL, &dbusmodule->watches, NULL)) { FcitxLog(WARNING, "Add Watch Function Error"); dbus_error_free(&err); dbus_error_init(&err); dbus_connection_unref(conn); conn = NULL; break; } /* from here we know dbus connection is successful, now we need to register the service */ dbus_connection_set_exit_on_disconnect(conn, FALSE); dbusmodule->conn = conn; boolean request_retry = false; int replaceCountdown = FcitxInstanceIsTryReplace(instance) ? 3 : 0; FcitxInstanceResetTryReplace(instance); do { request_retry = false; // request a name on the bus int ret = dbus_bus_request_name(conn, servicename, DBUS_NAME_FLAG_DO_NOT_QUEUE, &err); if (dbus_error_is_set(&err)) { FcitxLog(WARNING, "Name Error (%s)", err.message); goto dbus_init_failed; } if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { FcitxLog(WARNING, "DBus Service Already Exists"); if (replaceCountdown > 0) { replaceCountdown --; fcitx_utils_launch_tool("fcitx-remote", "-e"); /* sleep for a while and retry */ sleep(1); request_retry = true; continue; } /* if we know fcitx exists, we should exit. */ dbus_error_free(&err); free(servicename); free(dbusmodule); FcitxInstanceEnd(instance); return NULL; } } while (request_retry); dbus_connection_flush(dbusmodule->conn); } while(0); DBusConnection* privconn = NULL; do { int noPrivateDBus = fcitx_utils_get_boolean_env("FCITX_NO_PRIVATE_DBUS", false); if (noPrivateDBus) break; char* file; FILE* dbusfp = FcitxXDGGetFileWithPrefix("dbus", "daemon.conf", "r", &file); if (dbusfp) { fclose(dbusfp); } else { free(file); file = NULL; } dbusmodule->daemon = DBusLaunch(file); fcitx_utils_free(file); if (dbusmodule->daemon.pid == 0) break; privconn = dbus_connection_open(dbusmodule->daemon.address, &err); if (dbus_error_is_set(&err)) { FcitxLog(ERROR, "Private dbus daemon connection error (%s)", err.message); break; } dbus_bus_register(privconn, &err); if (dbus_error_is_set(&err)) { FcitxLog(ERROR, "Private dbus bus register error (%s)", err.message); break; } int ret = dbus_bus_request_name(privconn, servicename, DBUS_NAME_FLAG_DO_NOT_QUEUE, &err); if (dbus_error_is_set(&err)) { FcitxLog(WARNING, "Private Name Error (%s)", err.message); break; } if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { FcitxLog(ERROR, "Private DBus Service Already Exists, fcitx being hacked?"); break; } if (!dbus_connection_add_filter(privconn, DBusModuleFilter, dbusmodule, NULL)) break; if (!dbus_connection_set_watch_functions(privconn, DBusAddWatch, DBusRemoveWatch, NULL, &dbusmodule->watches, NULL)) { FcitxLog(WARNING, "Add Watch Function Error"); break; } char* addressFile = NULL; char* localMachineId = dbus_get_local_machine_id(); asprintf(&addressFile, "%s-%d", localMachineId, fcitx_utils_get_display_number()); dbus_free(localMachineId); FILE* fp = FcitxXDGGetFileUserWithPrefix("dbus", addressFile, "w", NULL); free(addressFile); if (!fp) break; fprintf(fp, "%s", dbusmodule->daemon.address); fwrite("\0", sizeof(char), 1, fp); pid_t curPid = getpid(); fwrite(&dbusmodule->daemon.pid, sizeof(pid_t), 1, fp); fwrite(&curPid, sizeof(pid_t), 1, fp); fclose(fp); dbusmodule->privconn = privconn; char* command = fcitx_utils_get_fcitx_path_with_filename("bindir", "/fcitx-dbus-watcher"); char* pidstring = NULL; asprintf(&pidstring, "%d", dbusmodule->daemon.pid); char* args[] = { command, dbusmodule->daemon.address, pidstring, NULL }; fcitx_utils_start_process(args); free(command); free(pidstring); } while(0); if (!dbusmodule->privconn) { if (privconn) { dbus_connection_unref(privconn); DBusKill(&dbusmodule->daemon); } } FcitxModuleAddFunction(dbusaddon, DBusGetConnection); FcitxModuleAddFunction(dbusaddon, DBusGetPrivateConnection); dbus_error_free(&err); dbusmodule->serviceName = servicename; return dbusmodule; dbus_init_failed: dbus_error_free(&err); fcitx_utils_free(servicename); if (conn) dbus_connection_unref(conn); DBusKill(&dbusmodule->daemon); fcitx_utils_free(dbusmodule); return NULL; }
boolean LoadTableDict(TableMetaData* tableMetaData) { char strCode[MAX_CODE_LENGTH + 1]; char *strHZ = 0; FILE *fpDict; RECORD *recTemp; unsigned int i = 0; uint32_t iTemp, iTempCount; char cChar = 0, cTemp; int8_t iVersion = 1; int iRecordIndex; TableDict *tableDict; //读入码表 FcitxLog(DEBUG, _("Loading Table Dict")); int reload = 0; do { boolean error = false; if (!reload) { /** * kcm saves a absolute path here but it is then interpreted as * a relative path? **/ fpDict = FcitxXDGGetFileWithPrefix("table", tableMetaData->strPath, "r", NULL); } else { char *tablepath; char *path = fcitx_utils_get_fcitx_path("pkgdatadir"); fcitx_utils_alloc_cat_str(tablepath, path, "/table/", tableMetaData->strPath); fpDict = fopen(tablepath, "r"); free(tablepath); } if (!fpDict) return false; tableMetaData->tableDict = fcitx_utils_new(TableDict); tableDict = tableMetaData->tableDict; tableDict->pool = fcitx_memory_pool_create(); #define CHECK_LOAD_TABLE_ERROR(SIZE) if (size < (SIZE)) { error = true; goto table_load_error; } //先读取码表的信息 //判断版本信息 size_t size; size = fcitx_utils_read_uint32(fpDict, &iTemp); CHECK_LOAD_TABLE_ERROR(1); if (!iTemp) { size = fread(&iVersion, sizeof(int8_t), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); iVersion = (iVersion < INTERNAL_VERSION); size = fcitx_utils_read_uint32(fpDict, &iTemp); CHECK_LOAD_TABLE_ERROR(1); } tableDict->strInputCode = (char*)realloc(tableDict->strInputCode, sizeof(char) * (iTemp + 1)); size = fread(tableDict->strInputCode, sizeof(char), iTemp + 1, fpDict); CHECK_LOAD_TABLE_ERROR(iTemp + 1); /* * 建立索引,加26是为了为拼音编码预留空间 */ size_t tmp_len = strlen(tableDict->strInputCode) + 26; tableDict->recordIndex = (RECORD_INDEX*)fcitx_memory_pool_alloc(tableDict->pool, tmp_len * sizeof(RECORD_INDEX)); for (iTemp = 0; iTemp < tmp_len; iTemp++) { tableDict->recordIndex[iTemp].cCode = 0; tableDict->recordIndex[iTemp].record = NULL; } /********************************************************************/ size = fread(&(tableDict->iCodeLength), sizeof(uint8_t), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); UpdateTableMetaData(tableMetaData); if (!iVersion) { size = fread(&(tableDict->iPYCodeLength), sizeof(uint8_t), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); } else tableDict->iPYCodeLength = tableDict->iCodeLength; size = fcitx_utils_read_uint32(fpDict, &iTemp); CHECK_LOAD_TABLE_ERROR(1); tableDict->strIgnoreChars = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (iTemp + 1)); size = fread(tableDict->strIgnoreChars, sizeof(char), iTemp + 1, fpDict); CHECK_LOAD_TABLE_ERROR(iTemp + 1); size = fread(&(tableDict->bRule), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); if (tableDict->bRule) { //表示有组词规则 tableDict->rule = (RULE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RULE) * (tableDict->iCodeLength - 1)); for (i = 0; i < tableDict->iCodeLength - 1; i++) { size = fread(&(tableDict->rule[i].iFlag), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); size = fread(&(tableDict->rule[i].iWords), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); tableDict->rule[i].rule = (RULE_RULE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RULE_RULE) * tableDict->iCodeLength); for (iTemp = 0; iTemp < tableDict->iCodeLength; iTemp++) { size = fread(&(tableDict->rule[i].rule[iTemp].iFlag), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); size = fread(&(tableDict->rule[i].rule[iTemp].iWhich), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); size = fread(&(tableDict->rule[i].rule[iTemp].iIndex), sizeof(unsigned char), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); } } } tableDict->recordHead = (RECORD*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RECORD)); tableDict->currentRecord = tableDict->recordHead; size = fcitx_utils_read_uint32(fpDict, &tableDict->iRecordCount); CHECK_LOAD_TABLE_ERROR(1); for (i = 0; i < SINGLE_HZ_COUNT; i++) { tableDict->tableSingleHZ[i] = (RECORD*)NULL; tableDict->tableSingleHZCons[i] = (RECORD*)NULL; } iRecordIndex = 0; size_t bufSize = 0; for (i = 0; i < tableDict->iRecordCount; i++) { size = fread(strCode, sizeof(int8_t), tableDict->iPYCodeLength + 1, fpDict); CHECK_LOAD_TABLE_ERROR(tableDict->iPYCodeLength + 1); size = fcitx_utils_read_uint32(fpDict, &iTemp); CHECK_LOAD_TABLE_ERROR(1); /* we don't actually have such limit, but sometimes, broken table * may break this, so we need to give a limitation. */ if (iTemp > UTF8_MAX_LENGTH * 30) { error = true; goto table_load_error; } if (iTemp > bufSize) { bufSize = iTemp; strHZ = realloc(strHZ, bufSize); } size = fread(strHZ, sizeof(int8_t), iTemp, fpDict); CHECK_LOAD_TABLE_ERROR(iTemp); recTemp = (RECORD*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RECORD)); recTemp->strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iPYCodeLength + 1)); memset(recTemp->strCode, 0, sizeof(char) * (tableDict->iPYCodeLength + 1)); strcpy(recTemp->strCode, strCode); recTemp->strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * iTemp); strcpy(recTemp->strHZ, strHZ); if (!iVersion) { size = fread(&cTemp, sizeof(int8_t), 1, fpDict); CHECK_LOAD_TABLE_ERROR(1); recTemp->type = cTemp; } size = fcitx_utils_read_uint32(fpDict, &recTemp->iHit); CHECK_LOAD_TABLE_ERROR(1); size = fcitx_utils_read_uint32(fpDict, &recTemp->iIndex); CHECK_LOAD_TABLE_ERROR(1); if (recTemp->iIndex > tableDict->iTableIndex) tableDict->iTableIndex = recTemp->iIndex; /* 建立索引 */ if (cChar != recTemp->strCode[0]) { cChar = recTemp->strCode[0]; tableDict->recordIndex[iRecordIndex].cCode = cChar; tableDict->recordIndex[iRecordIndex].record = recTemp; iRecordIndex++; } /******************************************************************/ /** 为单字生成一个表 */ if (fcitx_utf8_strlen(recTemp->strHZ) == 1 && !IsIgnoreChar(tableDict, strCode[0])) { RECORD** tableSingleHZ = NULL; if (recTemp->type == RECORDTYPE_NORMAL) tableSingleHZ = tableDict->tableSingleHZ; else if (recTemp->type == RECORDTYPE_CONSTRUCT) tableSingleHZ = tableDict->tableSingleHZCons; if (tableSingleHZ) { iTemp = CalHZIndex(recTemp->strHZ); if (iTemp < SINGLE_HZ_COUNT) { if (tableSingleHZ[iTemp]) { if (strlen(strCode) > strlen(tableDict->tableSingleHZ[iTemp]->strCode)) tableSingleHZ[iTemp] = recTemp; } else tableSingleHZ[iTemp] = recTemp; } } } if (recTemp->type == RECORDTYPE_PINYIN) tableDict->bHasPinyin = true; if (recTemp->type == RECORDTYPE_PROMPT && strlen(recTemp->strCode) == 1) tableDict->promptCode[(uint8_t) recTemp->strCode[0]] = recTemp; tableDict->currentRecord->next = recTemp; recTemp->prev = tableDict->currentRecord; tableDict->currentRecord = recTemp; } if (strHZ) { free(strHZ); strHZ = NULL; } tableDict->currentRecord->next = tableDict->recordHead; tableDict->recordHead->prev = tableDict->currentRecord; table_load_error: fclose(fpDict); if (error) { fcitx_memory_pool_destroy(tableDict->pool); tableDict->pool = NULL; reload++; } else { break; } } while(reload < 2); if (!tableDict->pool) return false; FcitxLog(DEBUG, _("Load Table Dict OK")); //读取相应的特殊符号表 fpDict = FcitxXDGGetFileWithPrefix("table", tableMetaData->strSymbolFile, "r", NULL); if (fpDict) { tableDict->iFH = fcitx_utils_calculate_record_number(fpDict); tableDict->fh = (FH*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(FH) * tableDict->iFH); char* strBuf = NULL; size_t bufLen = 0; for (i = 0; i < tableDict->iFH; i++) { if (getline(&strBuf, &bufLen, fpDict) == -1) break; if (!fcitx_utf8_check_string(strBuf)) break; if (fcitx_utf8_strlen(strBuf) > FH_MAX_LENGTH) break; strcpy(tableDict->fh[i].strFH, strBuf); } fcitx_utils_free(strBuf); tableDict->iFH = i; fclose(fpDict); } tableDict->strNewPhraseCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1)); tableDict->strNewPhraseCode[tableDict->iCodeLength] = '\0'; tableDict->iAutoPhrase = 0; if (tableMetaData->bAutoPhrase) { tableDict->autoPhrase = (AUTOPHRASE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(AUTOPHRASE) * AUTO_PHRASE_COUNT); //读取上次保存的自动词组信息 FcitxLog(DEBUG, _("Loading Autophrase.")); char *temppath; fcitx_utils_alloc_cat_str(temppath, tableMetaData->uniqueName, "_LastAutoPhrase.tmp"); fpDict = FcitxXDGGetFileWithPrefix("table", temppath, "r", NULL); free(temppath); i = 0; if (fpDict) { size_t size = fcitx_utils_read_int32(fpDict, &tableDict->iAutoPhrase); if (size == 1) { for (; i < tableDict->iAutoPhrase; i++) { tableDict->autoPhrase[i].strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1)); tableDict->autoPhrase[i].strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1)); size = fread(tableDict->autoPhrase[i].strCode, tableDict->iCodeLength + 1, 1, fpDict); if (size != 1) { tableDict->iAutoPhrase = i; break; } size = fread(tableDict->autoPhrase[i].strHZ, PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1, 1, fpDict); tableDict->autoPhrase[i].strHZ[PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH] = 0; if (size != 1 || !fcitx_utf8_check_string(tableDict->autoPhrase[i].strHZ)) { tableDict->iAutoPhrase = i; break; } size = fcitx_utils_read_uint32(fpDict, &iTempCount); if (size != 1) { tableDict->iAutoPhrase = i; break; } tableDict->autoPhrase[i].iSelected = iTempCount; if (i == AUTO_PHRASE_COUNT - 1) tableDict->autoPhrase[i].next = &tableDict->autoPhrase[0]; else tableDict->autoPhrase[i].next = &tableDict->autoPhrase[i + 1]; } } fclose(fpDict); } for (; i < AUTO_PHRASE_COUNT; i++) { tableDict->autoPhrase[i].strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1)); tableDict->autoPhrase[i].strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1)); tableDict->autoPhrase[i].iSelected = 0; if (i == AUTO_PHRASE_COUNT - 1) tableDict->autoPhrase[i].next = &tableDict->autoPhrase[0]; else tableDict->autoPhrase[i].next = &tableDict->autoPhrase[i + 1]; } if (i == AUTO_PHRASE_COUNT) tableDict->insertPoint = &tableDict->autoPhrase[0]; else tableDict->insertPoint = &tableDict->autoPhrase[i - 1]; FcitxLog(DEBUG, _("Load Autophrase OK")); } else tableDict->autoPhrase = (AUTOPHRASE *) NULL; return true; }
int main (int argc, char* argv[]) { char *servicename = NULL; char *address = NULL; DBusMessage* message = NULL; DBusConnection* conn = NULL; int c; int ret = 1; int messageType = FCITX_DBUS_GET_CURRENT_STATE; char *imname = NULL; while ((c = getopt(argc, argv, "chortTeam:")) != -1) { switch (c) { case 'o': messageType = FCITX_DBUS_ACTIVATE; break; case 'c': messageType = FCITX_DBUS_INACTIVATE; break; case 'r': messageType = FCITX_DBUS_RELOAD_CONFIG; break; case 't': case 'T': messageType = FCITX_DBUS_TOGGLE; break; case 'e': messageType = FCITX_DBUS_EXIT; break; case 'm': messageType = FCITX_DBUS_GET_IM_ADDON; imname = strdup(optarg); break; case 'a': address = _fcitx_get_address(); if (address) { printf("%s\n", address); return 0; } else return 1; break; case 'h': usage(stdout); return 0; default: usage(stderr); return 1; break; } } #define CASE(ENUMNAME, MESSAGENAME) \ case FCITX_DBUS_##ENUMNAME: \ message = dbus_message_new_method_call(servicename, FCITX_IM_DBUS_PATH, FCITX_IM_DBUS_INTERFACE, #MESSAGENAME); \ break; asprintf(&servicename, "%s-%d", FCITX_DBUS_SERVICE, fcitx_utils_get_display_number()); switch(messageType) { CASE(ACTIVATE, ActivateIM); CASE(INACTIVATE, InactivateIM); CASE(RELOAD_CONFIG, ReloadConfig); CASE(EXIT, Exit); CASE(TOGGLE, ToggleIM); CASE(GET_CURRENT_STATE, GetCurrentState); CASE(GET_IM_ADDON, GetIMAddon); default: goto some_error; }; if (!message) { goto some_error; } address = _fcitx_get_address(); do { if (!address) break; conn = dbus_connection_open(address, NULL); if (!conn) break; if (!dbus_bus_register(conn, NULL)) { dbus_connection_unref(conn); conn = NULL; break; } } while(0); if (!conn) { conn = dbus_bus_get(DBUS_BUS_SESSION, NULL); if (!conn) { goto some_error; } dbus_connection_set_exit_on_disconnect(conn, FALSE); } if (messageType == FCITX_DBUS_GET_CURRENT_STATE) { DBusMessage* reply = dbus_connection_send_with_reply_and_block(conn, message, 1000, NULL); int result = 0; if (reply && dbus_message_get_args(reply, NULL, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID)) { printf("%d\n", result); ret = 0; } else { fprintf(stderr, "Not get reply\n"); } } else if (messageType == FCITX_DBUS_GET_IM_ADDON) { do { if (!fcitx_utf8_check_string(imname)) break; dbus_message_append_args(message, DBUS_TYPE_STRING, &imname, DBUS_TYPE_INVALID); DBusMessage* reply = dbus_connection_send_with_reply_and_block(conn, message, 1000, NULL); char *result = NULL; if (reply && dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &result, DBUS_TYPE_INVALID)) { printf("%s\n", result); ret = 0; } else { fprintf(stderr, "Not get reply\n"); } } while(0); } else { dbus_connection_send(conn, message, NULL); dbus_connection_flush(conn); ret = 0; } some_error: if (message) dbus_message_unref(message); if (conn) dbus_connection_unref(conn); fcitx_utils_free(address); fcitx_utils_free(servicename); fcitx_utils_free(imname); return ret; }
void RulesHandlerCharacters(void *ctx, const xmlChar *ch, int len) { FcitxXkbRulesHandler* ruleshandler = (FcitxXkbRulesHandler*) ctx; FcitxXkbRules* rules = ruleshandler->rules; char* temp = strndup(XMLCHAR_CAST ch, len); char* trimmed = fcitx_utils_trim(temp); free(temp); if ( strlen(trimmed) != 0 ) { char* strPath = fcitx_utils_join_string_list(ruleshandler->path, '/'); FcitxXkbLayoutInfo* layoutInfo = (FcitxXkbLayoutInfo*) utarray_back(rules->layoutInfos); FcitxXkbModelInfo* modelInfo = (FcitxXkbModelInfo*) utarray_back(rules->modelInfos); FcitxXkbOptionGroupInfo* optionGroupInfo = (FcitxXkbOptionGroupInfo*) utarray_back(rules->optionGroupInfos); if ( StringEndsWith(strPath, "layoutList/layout/configItem/name") ) { if ( layoutInfo != NULL ) layoutInfo->name = strdup(trimmed); } else if ( StringEndsWith(strPath, "layoutList/layout/configItem/description") ) { layoutInfo->description = strdup(trimmed); } else if ( StringEndsWith(strPath, "layoutList/layout/configItem/languageList/iso639Id") ) { utarray_push_back(layoutInfo->languages, &trimmed); } else if ( StringEndsWith(strPath, "layoutList/layout/variantList/variant/configItem/name") ) { FcitxXkbVariantInfo* variantInfo = (FcitxXkbVariantInfo*) utarray_back(layoutInfo->variantInfos); variantInfo->name = strdup(trimmed); } else if ( StringEndsWith(strPath, "layoutList/layout/variantList/variant/configItem/description") ) { FcitxXkbVariantInfo* variantInfo = (FcitxXkbVariantInfo*) utarray_back(layoutInfo->variantInfos); fcitx_utils_free(variantInfo->description); variantInfo->description = strdup(trimmed); } else if ( StringEndsWith(strPath, "layoutList/layout/variantList/variant/configItem/languageList/iso639Id") ) { FcitxXkbVariantInfo* variantInfo = (FcitxXkbVariantInfo*) utarray_back(layoutInfo->variantInfos); utarray_push_back(variantInfo->languages, &trimmed); } else if ( StringEndsWith(strPath, "modelList/model/configItem/name") ) { modelInfo->name = strdup(trimmed); } else if ( StringEndsWith(strPath, "modelList/model/configItem/description") ) { modelInfo->description = strdup(trimmed); } else if ( StringEndsWith(strPath, "modelList/model/configItem/vendor") ) { modelInfo->vendor = strdup(trimmed); } else if ( StringEndsWith(strPath, "optionList/group/configItem/name") ) { optionGroupInfo->name = strdup(trimmed); } else if ( StringEndsWith(strPath, "optionList/group/configItem/description") ) { optionGroupInfo->description = strdup(trimmed); } else if ( StringEndsWith(strPath, "optionList/group/option/configItem/name") ) { FcitxXkbOptionInfo* optionInfo = (FcitxXkbOptionInfo*) utarray_back(optionGroupInfo->optionInfos); optionInfo->name = strdup(trimmed); } else if ( StringEndsWith(strPath, "optionList/group/option/configItem/description") ) { FcitxXkbOptionInfo* optionInfo = (FcitxXkbOptionInfo*) utarray_back(optionGroupInfo->optionInfos); fcitx_utils_free(optionInfo->description); optionInfo->description = strdup(trimmed); } free(strPath); } free(trimmed); }
void FcitxIsoCodes3166EntryFree(FcitxIsoCodes3166Entry* entry) { fcitx_utils_free(entry->alpha_2_code); fcitx_utils_free(entry->name); free(entry); }
int main (int argc, char* argv[]) { if (argc != 3) return 1; pid_t pid = atoi(argv[2]); if (pid <= 0) return 1; fcitx_utils_init_as_daemon(); asprintf(&servicename, "%s-%d", FCITX_DBUS_SERVICE, fcitx_utils_get_display_number()); DBusError err; dbus_error_init(&err); DBusConnection* conn = dbus_connection_open(argv[1], NULL); if (!conn) goto some_error; FcitxDBusWatch* watches = NULL; if (!dbus_connection_set_watch_functions(conn, DBusAddWatch, DBusRemoveWatch, NULL, &watches, NULL)) { goto some_error; } dbus_connection_set_exit_on_disconnect(conn, TRUE); if (!dbus_bus_register(conn, NULL)) goto some_error; dbus_bus_add_match(conn, "type='signal'," "interface='" DBUS_INTERFACE_DBUS "'," "path='" DBUS_PATH_DBUS "'," "member='NameOwnerChanged'", &err); if (dbus_error_is_set(&err)) goto some_error; if (!dbus_connection_add_filter(conn, WatcherDBusFilter, NULL, NULL)) goto some_error; #ifndef NZERO #define NZERO 20 #endif nice(NZERO - 1); fd_set rfds, wfds, efds; FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); do { DBusProcessEventForWatches(watches, &rfds, &wfds, &efds); DBusProcessEventForConnection(conn); if (status != WATCHER_WAITING) break; FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); int maxfd = DBusUpdateFDSet(watches, &rfds, &wfds, &efds); if (maxfd == 0) break; select(maxfd + 1, &rfds, &wfds, &efds, NULL); } while(1); if (status == FCITX_DIE) { kill(pid, SIGTERM); } some_error: if (conn) dbus_connection_unref(conn); dbus_error_free(&err); fcitx_utils_free(servicename); return 1; }