INPUT_RETURN_VALUE QWGetCandWords(void *arg) { FcitxQWState* qwstate = (FcitxQWState*) arg; FcitxInputState* input = FcitxInstanceGetInputState(qwstate->owner); int iQu, iWei; int i; FcitxCandidateWordSetPageSize(FcitxInputStateGetCandidateList(input), 10); FcitxCandidateWordSetChoose(FcitxInputStateGetCandidateList(input), DIGIT_STR_CHOOSE); if (FcitxInputStateGetRawInputBufferSize(input) == 3) { iQu = (FcitxInputStateGetRawInputBuffer(input)[0] - '0') * 10 + FcitxInputStateGetRawInputBuffer(input)[1] - '0'; iWei = (FcitxInputStateGetRawInputBuffer(input)[2] - '0') * 10; for (i = 0; i < 10; i++) { FcitxCandidateWord candWord; candWord.callback = QWGetCandWord; candWord.owner = qwstate; candWord.priv = NULL; candWord.strExtra = NULL; candWord.strWord = strdup(GetQuWei(qwstate, iQu, iWei + i + 1)); candWord.wordType = MSG_OTHER; FcitxCandidateWordAppend(FcitxInputStateGetCandidateList(input), &candWord); } } FcitxInputStateSetCursorPos(input, FcitxInputStateGetRawInputBufferSize(input)); FcitxMessagesSetMessageCount(FcitxInputStateGetPreedit(input), 0); FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_INPUT, "%s", FcitxInputStateGetRawInputBuffer(input)); return IRV_DISPLAY_CANDWORDS; }
void IMSelectorGetCands(IMSelector* imselector) { FcitxInstance* instance = imselector->owner; FcitxInputState *input = FcitxInstanceGetInputState(instance); UT_array* imes = FcitxInstanceGetIMEs(instance); FcitxInstanceCleanInputWindow(instance); FcitxCandidateWordList* candList = FcitxInputStateGetCandidateList(input); FcitxCandidateWordSetPageSize(candList, 10); FcitxCandidateWordSetChoose(candList, DIGIT_STR_CHOOSE); FcitxInputStateSetShowCursor(input, false); FcitxCandidateWordSetOverrideDefaultHighlight(candList, false); FcitxCandidateWordSetLayoutHint(candList, CLH_Vertical); FcitxIM* im = FcitxInstanceGetCurrentIM(instance); FcitxInputContext* ic = FcitxInstanceGetCurrentIC(instance); FcitxInputContext2* ic2 = (FcitxInputContext2*) ic; if (!ic) return; FcitxMessages *aux_up = FcitxInputStateGetAuxUp(input); FcitxMessagesAddMessageStringsAtLast(aux_up, MSG_TIPS, imselector->global ? _("Select global input method: ") : _("Select local input method: ")); if (ic2->imname) { int idx = FcitxInstanceGetIMIndexByName(instance, ic2->imname); FcitxIM *im = fcitx_array_eltptr(imes, idx); if (im) { FcitxMessagesAddMessageStringsAtLast(aux_up, MSG_TIPS, _("Current local input method is "), im->strName); } } else { FcitxMessagesAddMessageStringsAtLast(aux_up, MSG_TIPS, _("No local input method")); } utarray_foreach(pim, imes, FcitxIM) { FcitxCandidateWord candWord; candWord.callback = IMSelectorGetCand; candWord.owner = imselector; candWord.strExtra = NULL; if (ic2->imname && strcmp(ic2->imname, pim->uniqueName) == 0) { candWord.priv = NULL; candWord.strWord = strdup(_("Clear local input method")); } else { candWord.priv = strdup(pim->uniqueName); candWord.strWord = strdup(pim->strName); } if (im && strcmp(im->uniqueName, pim->uniqueName) == 0) { candWord.wordType = MSG_CANDIATE_CURSOR; } else { candWord.wordType = MSG_OTHER; } FcitxCandidateWordAppend(candList, &candWord); }
/** * @brief initialize the extra input method * * @param arg * @return successful or not **/ __EXPORT_API void* FcitxChewingCreate(FcitxInstance* instance) { if (GetFcitxChewingConfigDesc() == NULL) return NULL; char* user_path = NULL; FILE* fp = FcitxXDGGetFileUserWithPrefix("chewing", ".place_holder", "w", NULL); if (fp) fclose(fp); FcitxXDGGetFileUserWithPrefix("chewing", "", NULL, &user_path); FcitxLog(INFO, "Chewing storage path %s", user_path); if (0 == chewing_Init(CHEWING_DATADIR, user_path)) { FcitxLog(DEBUG, "chewing init ok"); } else { FcitxLog(DEBUG, "chewing init failed"); return NULL; } FcitxChewing* chewing = (FcitxChewing*) fcitx_utils_malloc0(sizeof(FcitxChewing)); FcitxGlobalConfig* config = FcitxInstanceGetGlobalConfig(instance); FcitxInputState *input = FcitxInstanceGetInputState(instance); FcitxCandidateWordSetChoose(FcitxInputStateGetCandidateList(input), DIGIT_STR_CHOOSE); bindtextdomain("fcitx-chewing", LOCALEDIR); chewing->context = chewing_new(); ChewingContext * c = chewing->context; chewing->owner = instance; chewing_set_ChiEngMode(c, CHINESE_MODE); chewing_set_maxChiSymbolLen(c, 16); // chewing will crash without set page chewing_set_candPerPage(c, config->iMaxCandWord); FcitxCandidateWordSetPageSize(FcitxInputStateGetCandidateList(input), config->iMaxCandWord); chewing_set_selKey(c, selKey, 10); LoadChewingConfig(&chewing->config); ConfigChewing(chewing); FcitxInstanceRegisterIM( instance, chewing, "chewing", _("Chewing"), "chewing", FcitxChewingInit, FcitxChewingReset, FcitxChewingDoInput, FcitxChewingGetCandWords, NULL, NULL, FcitxChewingReloadConfig, NULL, 1, "zh_TW" ); return chewing; }
void IMSelectorGetCands(IMSelector* imselector) { FcitxInstance* instance = imselector->owner; FcitxInputState *input = FcitxInstanceGetInputState(instance); FcitxIM* pim; UT_array* imes = FcitxInstanceGetIMEs(instance); FcitxInstanceCleanInputWindow(instance); FcitxCandidateWordSetPageSize(FcitxInputStateGetCandidateList(input), 10); FcitxCandidateWordSetChoose(FcitxInputStateGetCandidateList(input), DIGIT_STR_CHOOSE); FcitxInputStateSetShowCursor(input, false); FcitxInputContext* ic = FcitxInstanceGetCurrentIC(instance); FcitxInputContext2* ic2 = (FcitxInputContext2*) ic; if (!ic) return; FcitxMessagesAddMessageStringsAtLast(FcitxInputStateGetAuxUp(input), MSG_TIPS, imselector->global ? _("Select global input method: ") : _("Select local input method: ")); if (ic2->imname) { int idx = FcitxInstanceGetIMIndexByName(instance, ic2->imname); FcitxIM* im = (FcitxIM*) utarray_eltptr(imes, idx); if (im) { FcitxMessagesAddMessageAtLast(FcitxInputStateGetAuxUp(input), MSG_TIPS, _("Current local input method is %s"), im->strName); } } else { FcitxMessagesAddMessageStringsAtLast(FcitxInputStateGetAuxUp(input), MSG_TIPS, _("No local input method")); } for (pim = (FcitxIM *) utarray_front(imes); pim != NULL; pim = (FcitxIM *) utarray_next(imes, pim)) { FcitxCandidateWord candWord; candWord.callback = IMSelectorGetCand; candWord.owner = imselector; candWord.strExtra = NULL; if (ic2->imname && strcmp(ic2->imname, pim->uniqueName) == 0) { candWord.priv = NULL; candWord.strWord = strdup(_("Clear local input method")); } else { candWord.priv = strdup(pim->uniqueName); candWord.strWord = strdup(pim->strName); } candWord.wordType = MSG_OTHER; FcitxCandidateWordAppend(FcitxInputStateGetCandidateList(input), &candWord); } }
boolean UnicodePreFilter(void* arg, FcitxKeySym sym, unsigned int state, INPUT_RETURN_VALUE *r) { INPUT_RETURN_VALUE retVal = IRV_TO_PROCESS; do { UnicodeModule *uni = arg; if (!uni->enable) { return false; } FcitxInstance *instance = uni->owner; FcitxInputState *input = FcitxInstanceGetInputState(instance); FcitxGlobalConfig *fc = FcitxInstanceGetGlobalConfig(instance); FcitxCandidateWordList *candList; FcitxCandidateWord *candWord; candList = FcitxInputStateGetCandidateList(input); FcitxCandidateWordSetPageSize(candList, fc->iMaxCandWord); FcitxCandidateWordSetChooseAndModifier(candList, DIGIT_STR_CHOOSE, FcitxKeyState_Alt); if (FcitxHotkeyIsHotKey(sym, state, FcitxConfigPrevPageKey(instance, fc))) { if (FcitxCandidateWordGoPrevPage(candList)) retVal = IRV_DISPLAY_MESSAGE; else retVal = IRV_DO_NOTHING; } else if (FcitxHotkeyIsHotKey(sym, state, FcitxConfigNextPageKey(instance, fc))) { if (FcitxCandidateWordGoNextPage(candList)) retVal = IRV_DISPLAY_MESSAGE; else retVal = IRV_DO_NOTHING; } else if (FcitxHotkeyIsHotKey(sym, state, FCITX_BACKSPACE)) { size_t len = strlen(uni->buffer); if (len > 0) uni->buffer[--len] = '\0'; if (len == 0) { retVal = IRV_CLEAN; } else { retVal = UnicodeGetCandWords(uni); } } else if (FcitxHotkeyIsHotKey(sym, state, FCITX_ESCAPE)) { retVal = IRV_CLEAN; } else if (FcitxHotkeyIsHotKey(sym, state, fc->nextWord)) { candWord = FcitxCandidateWordGetFocus(candList, true); candWord = FcitxCandidateWordGetNext(candList, candWord); if (!candWord) { FcitxCandidateWordSetPage(candList, 0); candWord = FcitxCandidateWordGetFirst(candList); } else { FcitxCandidateWordSetFocus( candList, FcitxCandidateWordGetIndex(candList, candWord)); } if (candWord) { FcitxCandidateWordSetType(candWord, MSG_CANDIATE_CURSOR); retVal = IRV_FLAG_UPDATE_INPUT_WINDOW; } } else if (FcitxHotkeyIsHotKey(sym, state, fc->prevWord)) { candWord = FcitxCandidateWordGetFocus(candList, true); candWord = FcitxCandidateWordGetPrev(candList, candWord); if (!candWord) { FcitxCandidateWordSetPage( candList, FcitxCandidateWordPageCount(candList) - 1); candWord = FcitxCandidateWordGetLast(candList); } else { FcitxCandidateWordSetFocus( candList, FcitxCandidateWordGetIndex(candList, candWord)); } if (candWord) { FcitxCandidateWordSetType(candWord, MSG_CANDIATE_CURSOR); retVal = IRV_FLAG_UPDATE_INPUT_WINDOW; } } else if (FcitxHotkeyIsHotKey(sym, state, FCITX_ENTER)) { candWord = FcitxCandidateWordGetFocus(candList, true); if (candWord) { retVal = FcitxCandidateWordChooseByTotalIndex( candList, FcitxCandidateWordGetIndex(candList, candWord)); } } if (retVal == IRV_TO_PROCESS) { int index = FcitxCandidateWordCheckChooseKey(candList, sym, state); if (index >= 0) retVal = FcitxCandidateWordChooseByIndex(candList, index); } FcitxKeySym keymain = FcitxHotkeyPadToMain(sym); if (retVal == IRV_TO_PROCESS && FcitxHotkeyIsHotKeySimple(keymain, state)) { char buf[2]; buf[0] = keymain; buf[1] = '\0'; if (strlen(uni->buffer) < MAX_USER_INPUT) strcat(uni->buffer, buf); retVal = UnicodeGetCandWords(uni); } } while(0); if (retVal == IRV_TO_PROCESS) { retVal = IRV_DO_NOTHING; } *r = retVal; return true; }
static boolean ClipboardPostHook(void *arg, FcitxKeySym sym, unsigned int state, INPUT_RETURN_VALUE *ret_val) { FcitxClipboard *clipboard = arg; FcitxClipboardConfig *config = &clipboard->config; if (!((clipboard->primary.len && config->use_primary) || clipboard->clp_hist_len)) return false; FcitxInstance *instance = clipboard->owner; FcitxInputState *input = FcitxInstanceGetInputState(instance); if (FcitxInputStateGetRawInputBufferSize(input)) return false; if (!FcitxHotkeyIsHotKey(sym, state, config->trigger_key)) return false; clipboard->active = true; FcitxCandidateWordList *cand_list = FcitxInputStateGetCandidateList(input); FcitxGlobalConfig *gconfig = FcitxInstanceGetGlobalConfig(instance); FcitxMessages *msg; FcitxCandidateWord cand_word = { .callback = ClipboardCommitCallback, .wordType = MSG_OTHER, .owner = clipboard }; FcitxInstanceCleanInputWindow(instance); FcitxCandidateWordSetLayoutHint(cand_list, CLH_Vertical); FcitxCandidateWordSetPageSize(cand_list, gconfig->iMaxCandWord); FcitxCandidateWordSetChooseAndModifier( cand_list, DIGIT_STR_CHOOSE, cmodifiers[config->choose_modifier]); if (clipboard->clp_hist_len) { ClipboardSetCandWord(clipboard, &cand_word, clipboard->clp_hist_lst); FcitxCandidateWordAppend(cand_list, &cand_word); } int primary_found; if (clipboard->primary.len && config->use_primary) { primary_found = ClipboardSelectionClipboardFind( clipboard, clipboard->primary.str, clipboard->primary.len); if (primary_found == 0) goto skip_primary; ClipboardSetCandWord(clipboard, &cand_word, &clipboard->primary); FcitxCandidateWordAppend(cand_list, &cand_word); } else { primary_found = -1; } skip_primary: msg = FcitxInputStateGetAuxUp(input); FcitxInputStateSetShowCursor(input, false); FcitxMessagesSetMessageCount(msg, 0); FcitxMessagesAddMessageStringsAtLast(msg, MSG_TIPS, _("Select to paste")); unsigned int i; for (i = 1;i < clipboard->clp_hist_len;i++) { if ((int)i == primary_found) continue; ClipboardSetCandWord(clipboard, &cand_word, clipboard->clp_hist_lst + i); FcitxCandidateWordAppend(cand_list, &cand_word); } *ret_val = IRV_FLAG_UPDATE_INPUT_WINDOW; return true; }
FCITX_EXPORT_API FcitxInstance* FcitxInstanceCreateWithFD(sem_t *sem, int argc, char* argv[], int fd) { FcitxInstance* instance = fcitx_utils_malloc0(sizeof(FcitxInstance)); FcitxAddonsInit(&instance->addons); FcitxInstanceInitIM(instance); FcitxFrontendsInit(&instance->frontends); InitFcitxModules(&instance->modules); InitFcitxModules(&instance->eventmodules); utarray_init(&instance->uistats, &stat_icd); utarray_init(&instance->uicompstats, &compstat_icd); utarray_init(&instance->uimenus, &menup_icd); utarray_init(&instance->timeout, &timeout_icd); utarray_init(&instance->icdata, &icdata_icd); instance->input = FcitxInputStateCreate(); instance->sem = sem; instance->config = fcitx_utils_malloc0(sizeof(FcitxGlobalConfig)); instance->profile = fcitx_utils_malloc0(sizeof(FcitxProfile)); instance->globalIMName = strdup(""); if (fd > 0) { fcntl(fd, F_SETFL, O_NONBLOCK); instance->fd = fd; } if (!FcitxGlobalConfigLoad(instance->config)) goto error_exit; FcitxCandidateWordSetPageSize(instance->input->candList, instance->config->iMaxCandWord); if (!ProcessOption(instance, argc, argv)) goto error_exit; instance->timeStart = time(NULL); instance->globalState = instance->config->defaultIMState; instance->totaltime = 0; FcitxInitThread(instance); if (!FcitxProfileLoad(instance->profile, instance)) goto error_exit; if (FcitxAddonGetConfigDesc() == NULL) goto error_exit; if (GetIMConfigDesc() == NULL) goto error_exit; FcitxAddonsLoad(&instance->addons); FcitxInstanceFillAddonOwner(instance, NULL); FcitxInstanceResolveAddonDependency(instance); FcitxInstanceInitBuiltInHotkey(instance); FcitxInstanceInitBuiltContext(instance); FcitxModuleLoad(instance); if (instance->loadingFatalError) return instance; if (!FcitxInstanceLoadAllIM(instance)) { FcitxInstanceEnd(instance); return instance; } FcitxInstanceInitIMMenu(instance); FcitxUIRegisterMenu(instance, &instance->imMenu); FcitxUIRegisterStatus(instance, instance, "remind", instance->profile->bUseRemind ? _("Use remind") : _("No remind"), _("Toggle Remind"), ToggleRemindState, GetRemindEnabled); FcitxUISetStatusVisable(instance, "remind", false); FcitxUILoad(instance); instance->iIMIndex = FcitxInstanceGetIMIndexByName(instance, instance->profile->imName); FcitxInstanceSwitchIMByIndex(instance, instance->iIMIndex); if (!FcitxInstanceLoadFrontend(instance)) { FcitxInstanceEnd(instance); return instance; } /* make in order to use block X, query is not good here */ pthread_create(&instance->pid, NULL, RunInstance, instance); return instance; error_exit: FcitxInstanceEnd(instance); return instance; }
void* RunInstance(void* arg) { FcitxInstance* instance = (FcitxInstance*) arg; FcitxAddonsInit(&instance->addons); FcitxInstanceInitIM(instance); FcitxInstanceInitNoPreeditApps(instance); FcitxFrontendsInit(&instance->frontends); InitFcitxModules(&instance->modules); InitFcitxModules(&instance->eventmodules); utarray_init(&instance->uistats, &stat_icd); utarray_init(&instance->uicompstats, &compstat_icd); utarray_init(&instance->uimenus, fcitx_ptr_icd); utarray_init(&instance->timeout, &timeout_icd); utarray_init(&instance->icdata, &icdata_icd); instance->input = FcitxInputStateCreate(); instance->config = fcitx_utils_malloc0(sizeof(FcitxGlobalConfig)); instance->profile = fcitx_utils_malloc0(sizeof(FcitxProfile)); instance->globalIMName = strdup(""); if (instance->fd >= 0) { fcntl(instance->fd, F_SETFL, O_NONBLOCK); } else { instance->fd = -1; } if (!FcitxGlobalConfigLoad(instance->config)) goto error_exit; FcitxCandidateWordSetPageSize(instance->input->candList, instance->config->iMaxCandWord); int overrideDelay = instance->overrideDelay; if (overrideDelay < 0) overrideDelay = instance->config->iDelayStart; if (overrideDelay > 0) sleep(overrideDelay); instance->timeStart = time(NULL); instance->globalState = instance->config->defaultIMState; instance->totaltime = 0; FcitxInitThread(instance); if (!FcitxProfileLoad(instance->profile, instance)) goto error_exit; if (FcitxAddonGetConfigDesc() == NULL) goto error_exit; if (GetIMConfigDesc() == NULL) goto error_exit; FcitxAddonsLoad(&instance->addons); FcitxInstanceFillAddonOwner(instance, NULL); FcitxInstanceResolveAddonDependency(instance); FcitxInstanceInitBuiltInHotkey(instance); FcitxInstanceInitBuiltContext(instance); FcitxModuleLoad(instance); if (instance->loadingFatalError) return NULL; if (!FcitxInstanceLoadAllIM(instance)) { goto error_exit; } FcitxInstanceInitIMMenu(instance); FcitxUIRegisterMenu(instance, &instance->imMenu); FcitxUIRegisterStatus(instance, instance, "remind", instance->profile->bUseRemind ? _("Use remind") : _("No remind"), _("Toggle Remind"), ToggleRemindState, GetRemindEnabled); FcitxUISetStatusVisable(instance, "remind", false); FcitxUILoad(instance); instance->iIMIndex = FcitxInstanceGetIMIndexByName(instance, instance->profile->imName); if (instance->iIMIndex < 0) { instance->iIMIndex = 0; } FcitxInstanceSwitchIMByIndex(instance, instance->iIMIndex); if (!FcitxInstanceLoadFrontend(instance)) { goto error_exit; } /* fcitx is running in a standalone thread or not */ if (instance->sem) { sem_post(&instance->notifySem); sem_wait(&instance->startUpSem); } else { instance->initialized = true; } uint64_t curtime = 0; while (1) { FcitxAddon** pmodule; uint8_t signo = 0; if (instance->fd >= 0) { while (read(instance->fd, &signo, sizeof(char)) > 0) { if (signo == SIGINT || signo == SIGTERM || signo == SIGQUIT || signo == SIGXCPU) FcitxInstanceEnd(instance); else if (signo == SIGHUP) FcitxInstanceRestart(instance); else if (signo == SIGUSR1) FcitxInstanceReloadConfig(instance); } } do { instance->eventflag &= (~FEF_PROCESS_EVENT_MASK); for (pmodule = (FcitxAddon**) utarray_front(&instance->eventmodules); pmodule != NULL; pmodule = (FcitxAddon**) utarray_next(&instance->eventmodules, pmodule)) { FcitxModule* module = (*pmodule)->module; module->ProcessEvent((*pmodule)->addonInstance); } struct timeval current_time; gettimeofday(¤t_time, NULL); curtime = (current_time.tv_sec * 1000LL) + (current_time.tv_usec / 1000LL); unsigned int idx = 0; while(idx < utarray_len(&instance->timeout)) { TimeoutItem* ti = (TimeoutItem*) utarray_eltptr(&instance->timeout, idx); uint64_t id = ti->idx; if (ti->time + ti->milli <= curtime) { ti->callback(ti->arg); ti = (TimeoutItem*) utarray_eltptr(&instance->timeout, idx); /* faster remove */ if (ti && ti->idx == id) utarray_remove_quick(&instance->timeout, idx); else { FcitxInstanceRemoveTimeoutById(instance, id); idx = 0; } } else { idx++; } } if (instance->eventflag & FEF_UI_MOVE) FcitxUIMoveInputWindowReal(instance); if (instance->eventflag & FEF_UI_UPDATE) FcitxUIUpdateInputWindowReal(instance); } while ((instance->eventflag & FEF_PROCESS_EVENT_MASK) != FEF_NONE); setjmp(FcitxRecover); if (instance->destroy || instance->restart) { FcitxInstanceRealEnd(instance); break; } if (instance->eventflag & FEF_RELOAD_ADDON) { instance->eventflag &= ~(FEF_RELOAD_ADDON); FcitxInstanceReloadAddon(instance); } FD_ZERO(&instance->rfds); FD_ZERO(&instance->wfds); FD_ZERO(&instance->efds); instance->maxfd = 0; if (instance->fd > 0) { instance->maxfd = instance->fd; FD_SET(instance->fd, &instance->rfds); } for (pmodule = (FcitxAddon**) utarray_front(&instance->eventmodules); pmodule != NULL; pmodule = (FcitxAddon**) utarray_next(&instance->eventmodules, pmodule)) { FcitxModule* module = (*pmodule)->module; module->SetFD((*pmodule)->addonInstance); } if (instance->maxfd == 0) break; struct timeval tval; struct timeval* ptval = NULL; if (utarray_len(&instance->timeout) != 0) { unsigned long int min_time = LONG_MAX; TimeoutItem* ti; for (ti = (TimeoutItem*)utarray_front(&instance->timeout);ti; ti = (TimeoutItem*)utarray_next(&instance->timeout, ti)) { if (ti->time + ti->milli - curtime < min_time) { min_time = ti->time + ti->milli - curtime; } } tval.tv_usec = (min_time % 1000) * 1000; tval.tv_sec = min_time / 1000; ptval = &tval; } select(instance->maxfd + 1, &instance->rfds, &instance->wfds, &instance->efds, ptval); } if (instance->restart) { fcitx_utils_restart_in_place(); } return NULL; error_exit: sem_post(&instance->startUpSem); FcitxInstanceEnd(instance); return NULL; }
/** * @brief function DoInput has done everything for us. * * @param searchMode * @return INPUT_RETURN_VALUE **/ __EXPORT_API INPUT_RETURN_VALUE FcitxLibpinyinGetCandWords(void* arg) { FcitxLibpinyin* libpinyin = (FcitxLibpinyin* )arg; FcitxInstance* instance = libpinyin->owner->owner; FcitxInputState* input = FcitxInstanceGetInputState(instance); FcitxGlobalConfig* config = FcitxInstanceGetGlobalConfig(libpinyin->owner->owner); FcitxLibpinyinConfig* pyConfig = &libpinyin->owner->config; struct _FcitxCandidateWordList* candList = FcitxInputStateGetCandidateList(input); FcitxCandidateWordSetPageSize(candList, config->iMaxCandWord); FcitxUICloseInputWindow(instance); strcpy(FcitxInputStateGetRawInputBuffer(input), libpinyin->buf); FcitxInputStateSetRawInputBufferSize(input, strlen(libpinyin->buf)); FcitxInputStateSetShowCursor(input, true); FcitxInputStateSetClientCursorPos(input, 0); if (libpinyin->type == LPT_Zhuyin) { FcitxKeyState state = candidateModifierMap[pyConfig->candidateModifiers]; FcitxCandidateWordSetChooseAndModifier(candList, "1234567890", state); } else FcitxCandidateWordSetChoose(candList, "1234567890"); /* add punc */ if (libpinyin->type == LPT_Zhuyin && strlen(libpinyin->buf) == 1 && LibpinyinCheckZhuyinKey((FcitxKeySym) libpinyin->buf[0], pyConfig->zhuyinLayout, pyConfig->useTone) && (libpinyin->buf[0] >= ' ' && libpinyin->buf[0] <= '\x7e') /* simple */ && !(libpinyin->buf[0] >= 'a' && libpinyin->buf[0] <= 'z') /* not a-z */ && !(libpinyin->buf[0] >= 'A' && libpinyin->buf[0] <= 'Z') /* not A-Z /*/ && !(libpinyin->buf[0] >= '0' && libpinyin->buf[0] <= '9') /* not digit */ ) { int c = libpinyin->buf[0]; char *result = FcitxPuncGetPunc(instance, &c); if (result) { FcitxCandidateWord candWord; FcitxLibpinyinCandWord* pyCand = (FcitxLibpinyinCandWord*) fcitx_utils_malloc0(sizeof(FcitxLibpinyinCandWord)); pyCand->ispunc = true; candWord.callback = FcitxLibpinyinGetCandWord; candWord.extraType = MSG_OTHER; candWord.owner = libpinyin; candWord.priv = pyCand; candWord.strExtra = NULL; candWord.strWord = strdup(result); candWord.wordType = MSG_OTHER; FcitxCandidateWordAppend(FcitxInputStateGetCandidateList(input), &candWord); } } char* sentence = NULL; pinyin_guess_sentence(libpinyin->inst); sentence = LibpinyinGetSentence(libpinyin); if (sentence) { FcitxLibpinyinUpdatePreedit(libpinyin, sentence); FcitxMessagesAddMessageAtLast(FcitxInputStateGetClientPreedit(input), MSG_INPUT, "%s", sentence); g_free(sentence); } else { FcitxInputStateSetCursorPos(input, libpinyin->cursor_pos); FcitxMessagesAddMessageAtLast(FcitxInputStateGetClientPreedit(input), MSG_INPUT, "%s", libpinyin->buf); FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_INPUT, "%s", libpinyin->buf); } if (libpinyin->candidate) g_array_free(libpinyin->candidate, TRUE); libpinyin->candidate = g_array_new(FALSE, FALSE, sizeof(lookup_candidate_t)); pinyin_get_candidates(libpinyin->inst, LibpinyinGetOffset(libpinyin), libpinyin->candidate); int i = 0; for (i = 0 ; i < libpinyin->candidate->len; i ++) { lookup_candidate_t token = g_array_index(libpinyin->candidate, lookup_candidate_t, i); FcitxCandidateWord candWord; FcitxLibpinyinCandWord* pyCand = (FcitxLibpinyinCandWord*) fcitx_utils_malloc0(sizeof(FcitxLibpinyinCandWord)); pyCand->ispunc = false; pyCand->idx = i; candWord.callback = FcitxLibpinyinGetCandWord; candWord.extraType = MSG_OTHER; candWord.owner = libpinyin; candWord.priv = pyCand; candWord.strExtra = NULL; candWord.strWord = strdup(token.m_phrase_string); candWord.wordType = MSG_OTHER; FcitxCandidateWordAppend(FcitxInputStateGetCandidateList(input), &candWord); } return IRV_DISPLAY_CANDWORDS; }
/** * @brief function DoInput has done everything for us. * * @param searchMode * @return INPUT_RETURN_VALUE **/ __EXPORT_API INPUT_RETURN_VALUE FcitxChewingGetCandWords(void* arg) { FcitxChewing* chewing = (FcitxChewing*) arg; FcitxInputState *input = FcitxInstanceGetInputState(chewing->owner); FcitxMessages *msgPreedit = FcitxInputStateGetPreedit(input); FcitxMessages *clientPreedit = FcitxInputStateGetClientPreedit(input); ChewingContext * c = chewing->context; FcitxGlobalConfig* config = FcitxInstanceGetGlobalConfig(chewing->owner); chewing_set_candPerPage(c, config->iMaxCandWord); FcitxCandidateWordSetPageSize(FcitxInputStateGetCandidateList(input), config->iMaxCandWord); //clean up window asap FcitxInstanceCleanInputWindow(chewing->owner); char * buf_str = chewing_buffer_String(c); char * zuin_str = chewing_zuin_String(c, NULL); ConfigChewing(chewing); FcitxLog(DEBUG, "%s %s", buf_str, zuin_str); /* if not check done, so there is candidate word */ if (!chewing_cand_CheckDone(c)) { //get candidate word chewing_cand_Enumerate(c); int index = 0; while (chewing_cand_hasNext(c)) { char* str = chewing_cand_String(c); FcitxCandidateWord cw; ChewingCandWord* w = (ChewingCandWord*) fcitx_utils_malloc0(sizeof(ChewingCandWord)); w->index = index; cw.callback = FcitxChewingGetCandWord; cw.owner = chewing; cw.priv = w; cw.strExtra = NULL; cw.strWord = strdup(str); cw.wordType = MSG_OTHER; FcitxCandidateWordAppend(FcitxInputStateGetCandidateList(input), &cw); chewing_free(str); index ++; } } // setup cursor FcitxInputStateSetShowCursor(input, true); int buf_len = chewing_buffer_Len(c); int cur = chewing_cursor_Current(c); FcitxLog(DEBUG, "buf len: %d, cur: %d", buf_len, cur); int rcur = FcitxChewingGetRawCursorPos(buf_str, cur); FcitxInputStateSetCursorPos(input, rcur); FcitxInputStateSetClientCursorPos(input, rcur); // insert zuin in the middle char * half1 = strndup(buf_str, rcur); char * half2 = strdup(buf_str + rcur); FcitxMessagesAddMessageAtLast(msgPreedit, MSG_INPUT, "%s%s%s", half1, zuin_str, half2); FcitxMessagesAddMessageAtLast(clientPreedit, MSG_INPUT, "%s%s%s", half1, zuin_str, half2); chewing_free(buf_str); chewing_free(zuin_str); free(half1); free(half2); return IRV_DISPLAY_CANDWORDS; }
INPUT_RETURN_VALUE FcitxRimeGetCandWords(void* arg) { FcitxRime *rime = (FcitxRime *)arg; FcitxInputState *input = FcitxInstanceGetInputState(rime->owner); FcitxInstanceCleanInputWindow(rime->owner); RIME_STRUCT(RimeContext, context); if (!rime->api->get_context(rime->session_id, &context)) { return IRV_DISPLAY_CANDWORDS; } if (context.composition.length == 0) { rime->api->free_context(&context); return IRV_DISPLAY_CANDWORDS; } FcitxMessages* msgPreedit = FcitxInputStateGetPreedit(input); FcitxMessages* msgClientPreedit = FcitxInputStateGetClientPreedit(input); FcitxInputStateSetShowCursor(input, true); FcitxInputStateSetCursorPos(input, context.composition.cursor_pos); if (context.commit_text_preview) { FcitxInputStateSetClientCursorPos(input, strlen(context.commit_text_preview)); } /* converted text */ if (context.composition.sel_start > 0) { char* temp = strndup(context.composition.preedit, context.composition.sel_start); FcitxMessagesAddMessageAtLast(msgPreedit, MSG_OTHER, "%s", temp); free(temp); if (context.commit_text_preview) { temp = strndup(context.commit_text_preview, context.composition.sel_start); FcitxMessagesAddMessageAtLast(msgClientPreedit, MSG_INPUT, "%s", temp); free(temp); } } /* converting candidate */ if (context.composition.sel_start < context.composition.sel_end) { char* temp = strndup(&context.composition.preedit[context.composition.sel_start], context.composition.sel_end - context.composition.sel_start); FcitxMessagesAddMessageAtLast(msgPreedit, MSG_HIGHLIGHT | MSG_CODE, "%s", temp); free(temp); if (context.commit_text_preview) { FcitxMessagesAddMessageAtLast(msgClientPreedit, MSG_HIGHLIGHT, "%s", &context.commit_text_preview[context.composition.sel_start]); } } /* remaining input to convert */ if (context.composition.sel_end < strlen(context.composition.preedit)) { FcitxMessagesAddMessageAtLast(msgPreedit, MSG_CODE, "%s", &context.composition.preedit[context.composition.sel_end]); } if (context.menu.num_candidates) { FcitxCandidateWordList* candList = FcitxInputStateGetCandidateList(input); const char* digit = DIGIT_STR_CHOOSE; char strChoose[11]; strChoose[10] = '\0'; FcitxCandidateWordSetPageSize(candList, 10); int num_select_keys = context.menu.select_keys ? strlen(context.menu.select_keys) : 0; int i; for (i = 0; i < context.menu.num_candidates; ++i) { FcitxCandidateWord candWord; candWord.strWord = strdup (context.menu.candidates[i].text); if (i == context.menu.highlighted_candidate_index) candWord.wordType = MSG_CANDIATE_CURSOR; else candWord.wordType = MSG_OTHER; candWord.strExtra = context.menu.candidates[i].comment ? strdup (context.menu.candidates[i].comment) : NULL; candWord.extraType = MSG_CODE; candWord.callback = FcitxRimeGetCandWord; candWord.owner = rime; int* priv = fcitx_utils_new(int); *priv = i; candWord.priv = priv; FcitxCandidateWordAppend(candList, &candWord); if (i < 10) { if (i < num_select_keys) { strChoose[i] = context.menu.select_keys[i]; } else { strChoose[i] = digit[i]; } } } FcitxCandidateWordSetChoose(candList, strChoose); FcitxCandidateWordSetOverridePaging(candList, context.menu.page_no != 0, !context.menu.is_last_page, FcitxRimePaging, rime, NULL); }
INPUT_RETURN_VALUE QuickPhraseGetCandWords(QuickPhraseState* qpstate) { int iInputLen; QUICK_PHRASE searchKey, *pKey, *currentQuickPhrase, *lastQuickPhrase; FcitxInputState *input = FcitxInstanceGetInputState(qpstate->owner); FcitxInstance *instance = qpstate->owner; FcitxGlobalConfig* config = FcitxInstanceGetGlobalConfig(instance); FcitxInstanceCleanInputWindowDown(qpstate->owner); FcitxCandidateWordSetPageSize(FcitxInputStateGetCandidateList(input), config->iMaxCandWord); FcitxCandidateWordSetChoose(FcitxInputStateGetCandidateList(input), DIGIT_STR_CHOOSE); pKey = &searchKey; { FcitxModuleFunctionArg arg; char *text = FcitxInputStateGetRawInputBuffer(input); arg.args[0] = text; arg.args[1] = QuickPhraseGetLuaCandWord; arg.args[2] = qpstate; InvokeFunction(qpstate->owner, FCITX_LUA, CALLCOMMAND, arg); } if (!qpstate->quickPhrases) return IRV_DISPLAY_MESSAGE; iInputLen = strlen(FcitxInputStateGetRawInputBuffer(input)); if (iInputLen > QUICKPHRASE_CODE_LEN) return IRV_DISPLAY_MESSAGE; strcpy(searchKey.strCode, FcitxInputStateGetRawInputBuffer(input)); currentQuickPhrase = utarray_custom_bsearch(pKey, qpstate->quickPhrases, false, PhraseCmp); qpstate->iFirstQuickPhrase = utarray_eltidx(qpstate->quickPhrases, currentQuickPhrase); lastQuickPhrase = utarray_custom_bsearch(pKey, qpstate->quickPhrases, false, PhraseCmpA); qpstate->iLastQuickPhrase = utarray_eltidx(qpstate->quickPhrases, lastQuickPhrase); if (qpstate->iLastQuickPhrase < 0) qpstate->iLastQuickPhrase = utarray_len(qpstate->quickPhrases); if (!currentQuickPhrase || strncmp(FcitxInputStateGetRawInputBuffer(input), currentQuickPhrase->strCode, iInputLen)) { currentQuickPhrase = NULL; return IRV_DISPLAY_MESSAGE; } for (currentQuickPhrase = (QUICK_PHRASE*) utarray_eltptr(qpstate->quickPhrases, qpstate->iFirstQuickPhrase); currentQuickPhrase != NULL; currentQuickPhrase = (QUICK_PHRASE*) utarray_next(qpstate->quickPhrases, currentQuickPhrase)) { if (!strncmp(FcitxInputStateGetRawInputBuffer(input), currentQuickPhrase->strCode, iInputLen)) { QuickPhraseCand* qpcand = fcitx_utils_malloc0(sizeof(QuickPhraseCand)); qpcand->cand = currentQuickPhrase; FcitxCandidateWord candWord; candWord.callback = QuickPhraseGetCandWord; candWord.owner = qpstate; candWord.priv = qpcand; candWord.strExtra = strdup(currentQuickPhrase->strCode + iInputLen); candWord.strWord = strdup(currentQuickPhrase->strPhrase); candWord.wordType = MSG_OTHER; candWord.extraType = MSG_CODE; FcitxCandidateWordAppend(FcitxInputStateGetCandidateList(input), &candWord); } } return IRV_DISPLAY_MESSAGE; }
boolean UnicodePreFilter(void* arg, FcitxKeySym sym, unsigned int state, INPUT_RETURN_VALUE *r) { INPUT_RETURN_VALUE retVal = IRV_TO_PROCESS; do { UnicodeModule *uni = arg; if (!uni->enable) break; FcitxInstance *instance = uni->owner; FcitxInputState *input = FcitxInstanceGetInputState(instance); FcitxGlobalConfig *fc = FcitxInstanceGetGlobalConfig(instance); FcitxCandidateWordList *candList; candList = FcitxInputStateGetCandidateList(input); FcitxCandidateWordSetPageSize(candList, 4); FcitxCandidateWordSetChooseAndModifier(candList, DIGIT_STR_CHOOSE, FcitxKeyState_Alt); if (FcitxHotkeyIsHotKey(sym, state, FcitxConfigNextPageKey(instance, fc))) { if (FcitxCandidateWordGoPrevPage(candList)) retVal = IRV_DISPLAY_MESSAGE; else retVal = IRV_DO_NOTHING; } else if (FcitxHotkeyIsHotKey(sym, state, FcitxConfigNextPageKey(instance, fc))) { if (FcitxCandidateWordGoNextPage(candList)) retVal = IRV_DISPLAY_MESSAGE; else retVal = IRV_DO_NOTHING; } else if (FcitxHotkeyIsHotKey(sym, state, FCITX_BACKSPACE)) { size_t len = strlen(uni->buffer); if (len > 0) uni->buffer[--len] = '\0'; if (len == 0) { retVal = IRV_CLEAN; } else { retVal = UnicodeGetCandWords(uni); } } else if (FcitxHotkeyIsHotKey(sym, state, FCITX_ESCAPE)) { retVal = IRV_CLEAN; } if (retVal == IRV_TO_PROCESS) { int index = FcitxCandidateWordCheckChooseKey(candList, sym, state); if (index >= 0) retVal = FcitxCandidateWordChooseByIndex(candList, index); } FcitxKeySym keymain = FcitxHotkeyPadToMain(sym); if (retVal == IRV_TO_PROCESS && FcitxHotkeyIsHotKeySimple(keymain, state)) { char buf[2]; buf[0] = keymain; buf[1] = '\0'; if (strlen(uni->buffer) < MAX_USER_INPUT) strcat(uni->buffer, buf); retVal = UnicodeGetCandWords(uni); } } while(0); *r = retVal; if (retVal == IRV_TO_PROCESS) return false; return true; }
INPUT_RETURN_VALUE FcitxKkcGetCandWords(void* arg) { FcitxKkc *kkc = (FcitxKkc*)arg; FcitxInputState* input = FcitxInstanceGetInputState(kkc->owner); FcitxCandidateWordList* candList = FcitxInputStateGetCandidateList(input); FcitxMessages* clientPreedit = FcitxInputStateGetClientPreedit(input); FcitxMessages* preedit = FcitxInputStateGetPreedit(input); FcitxInstanceCleanInputWindow(kkc->owner); FcitxMessages* message = FcitxInstanceICSupportPreedit(kkc->owner, FcitxInstanceGetCurrentIC(kkc->owner)) ? clientPreedit : preedit; FcitxCandidateWordSetChoose(candList, DIGIT_STR_CHOOSE); FcitxCandidateWordSetPageSize(candList, kkc->config.pageSize); FcitxCandidateWordSetLayoutHint(candList, kkc->config.candidateLayout); FcitxInputStateSetShowCursor(input, true); KkcSegmentList* segments = kkc_context_get_segments(kkc->context); if (kkc_segment_list_get_cursor_pos(segments) >= 0) { int i = 0; int offset = 0; for (i = 0; i < kkc_segment_list_get_size(segments); i ++) { KkcSegment* segment = kkc_segment_list_get(segments, i); const gchar* str = kkc_segment_get_output(segment); FcitxMessageType messageType = MSG_INPUT; if (i < kkc_segment_list_get_cursor_pos(segments)) { offset += strlen(str); } if (i == kkc_segment_list_get_cursor_pos(segments)) { messageType = (FcitxMessageType) (MSG_HIGHLIGHT | MSG_OTHER); } FcitxMessagesAddMessageAtLast(message, messageType, "%s", str); } if (message == clientPreedit) { FcitxInputStateSetClientCursorPos(input, offset); } else { FcitxInputStateSetCursorPos(input, offset); } } else { gchar* str = kkc_context_get_input(kkc->context); if (str && str[0]) { FcitxMessagesAddMessageAtLast(message, MSG_INPUT, "%s", str); if (message == clientPreedit) { FcitxInputStateSetClientCursorPos(input, strlen(str)); } else { FcitxInputStateSetCursorPos(input, strlen(str)); } } g_free(str); } KkcCandidateList* kkcCandidates = kkc_context_get_candidates(kkc->context); if (kkc_candidate_list_get_page_visible(kkcCandidates)) { int i, j; guint size = kkc_candidate_list_get_size(kkcCandidates); gint cursor_pos = kkc_candidate_list_get_cursor_pos(kkcCandidates); guint page_start = kkc_candidate_list_get_page_start(kkcCandidates); guint page_size = kkc_candidate_list_get_page_size(kkcCandidates); for (i = kkc_candidate_list_get_page_start(kkcCandidates), j = 0; i < size; i ++, j++) { FcitxCandidateWord word; word.callback = FcitxKkcGetCandWord; word.extraType = MSG_OTHER; word.owner = kkc; int* id = fcitx_utils_new(int); *id = j; word.priv = id; word.strExtra = NULL; word.strExtra = MSG_TIPS; KkcCandidate* kkcCandidate = kkc_candidate_list_get(kkcCandidates, i); if (kkc->config.showAnnotation && kkc_candidate_get_annotation(kkcCandidate)) { fcitx_utils_alloc_cat_str(word.strExtra, " [", kkc_candidate_get_annotation(kkcCandidate), "]"); } word.strWord = strdup(kkc_candidate_get_text(kkcCandidate)); if (i == cursor_pos) { word.wordType = MSG_CANDIATE_CURSOR; } else { word.wordType = MSG_OTHER; } FcitxCandidateWordAppend(candList, &word); } FcitxCandidateWordSetFocus(candList, cursor_pos - page_start); FcitxCandidateWordSetOverridePaging(candList, (cursor_pos - page_start) >= page_size, (size - page_start) / page_size != (cursor_pos - page_start) / page_size, FcitxKkcPaging, kkc, NULL); } if (kkc_context_has_output(kkc->context)) { gchar* str = kkc_context_poll_output(kkc->context); FcitxInstanceCommitString(kkc->owner, FcitxInstanceGetCurrentIC(kkc->owner), str); g_free(str); } return IRV_DISPLAY_CANDWORDS; }
FCITX_EXPORT_API FcitxInstance* FcitxInstanceCreate(sem_t *sem, int argc, char* argv[]) { FcitxInstance* instance = fcitx_utils_malloc0(sizeof(FcitxInstance)); FcitxAddonsInit(&instance->addons); FcitxInstanceInitIM(instance); FcitxFrontendsInit(&instance->frontends); InitFcitxModules(&instance->eventmodules); utarray_init(&instance->uistats, &stat_icd); utarray_init(&instance->uimenus, &menup_icd); instance->input = FcitxInputStateCreate(); instance->sem = sem; instance->config = fcitx_utils_malloc0(sizeof(FcitxGlobalConfig)); instance->profile = fcitx_utils_malloc0(sizeof(FcitxProfile)); if (!FcitxGlobalConfigLoad(instance->config)) goto error_exit; FcitxCandidateWordSetPageSize(instance->input->candList, instance->config->iMaxCandWord); if (!ProcessOption(instance, argc, argv)) goto error_exit; instance->timeStart = time(NULL); instance->globalState = instance->config->defaultIMState; instance->totaltime = 0; FcitxInitThread(instance); if (!FcitxProfileLoad(instance->profile, instance)) goto error_exit; if (FcitxAddonGetConfigDesc() == NULL) goto error_exit; if (GetIMConfigDesc() == NULL) goto error_exit; FcitxAddonsLoad(&instance->addons); /* FIXME: a walkaround for not have instance in function FcitxModuleInvokeFunction */ FcitxAddon* addon; for (addon = (FcitxAddon *) utarray_front(&instance->addons); addon != NULL; addon = (FcitxAddon *) utarray_next(&instance->addons, addon)) { addon->owner = instance; } FcitxInstanceResolveAddonDependency(instance); FcitxInstanceInitBuiltInHotkey(instance); FcitxInstanceInitBuiltContext(instance); FcitxModuleLoad(instance); if (!FcitxInstanceLoadAllIM(instance)) { FcitxInstanceEnd(instance); return instance; } FcitxInstanceInitIMMenu(instance); FcitxUIRegisterMenu(instance, &instance->imMenu); FcitxUIRegisterStatus(instance, instance, "remind", _("Remind"), _("Remind"), ToggleRemindState, GetRemindEnabled); FcitxUILoad(instance); instance->iIMIndex = FcitxInstanceGetIMIndexByName(instance, instance->profile->imName); FcitxInstanceSwitchIM(instance, instance->iIMIndex); instance->lastIMIndex = instance->iIMIndex; if (!FcitxInstanceLoadFrontend(instance)) { FcitxInstanceEnd(instance); return instance; } if (instance->config->bFirstRun) { instance->config->bFirstRun = false; FcitxGlobalConfigSave(instance->config); const char *imname = "fcitx"; char *strTemp; asprintf(&strTemp, "@im=%s", imname); if ((getenv("XMODIFIERS") != NULL && CHECK_ENV("XMODIFIERS", strTemp, true)) || (CHECK_ENV("GTK_IM_MODULE", "xim", false) && CHECK_ENV("GTK_IM_MODULE", "fcitx", false)) || (CHECK_ENV("QT_IM_MODULE", "xim", false) && CHECK_ENV("QT_IM_MODULE", "fcitx", false))) { char *msg[12]; msg[0] = _("Please check your environment varibles."); msg[1] = _("You can use tools provided by your distribution."); msg[2] = _("Or You may need to set environment varibles below to make fcitx work correctly."); msg[3] = "export XMODIFIERS=\"@im=fcitx\""; msg[4] = "export QT_IM_MODULE=xim"; msg[5] = "export GTK_IM_MODULE=xim"; msg[6] = _("Or (Depends on you install im module or not)"); msg[7] = "export XMODIFIERS=\"@im=fcitx\""; msg[8] = "export QT_IM_MODULE=fcitx"; msg[9] = "export GTK_IM_MODULE=fcitx"; msg[10] = _("If you use login manager like gdm or kdm, put those lines in your ~/.xprofile."); msg[11] = _("If you use ~/.xinitrc and startx, put those lines in ~/.xinitrc."); FcitxUIDisplayMessage(instance, _("Setting Hint"), msg, 12); } free(strTemp); } /* make in order to use block X, query is not good here */ pthread_create(&instance->pid, NULL, RunInstance, instance); return instance; error_exit: FcitxInstanceEnd(instance); return instance; }