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; }
INPUT_RETURN_VALUE UnicodeGetCandWords(UnicodeModule* uni) { FcitxInputState *input = FcitxInstanceGetInputState(uni->owner); FcitxInstanceCleanInputWindow(uni->owner); FcitxMessagesAddMessageStringsAtLast(FcitxInputStateGetPreedit(input), MSG_INPUT, uni->buffer); FcitxInputStateSetShowCursor(input, true); FcitxInputStateSetCursorPos(input, strlen(uni->buffer)); FcitxCandidateWordList* candList = FcitxInputStateGetCandidateList(input); FcitxCandidateWordSetLayoutHint(candList, CLH_Vertical); UT_array* result = CharSelectDataFind(uni->charselectdata, uni->buffer); utarray_foreach(c, result, uint32_t) { char* s = fcitx_utils_malloc0(sizeof(char) * (UTF8_MAX_LENGTH + 1)); fcitx_ucs4_to_utf8(*c, s); FcitxCandidateWord candWord; candWord.callback = UnicodeGetCandWord; candWord.owner = uni; candWord.priv = NULL; candWord.extraType = MSG_OTHER; candWord.wordType = MSG_CODE; candWord.strWord = s; char* name = CharSelectDataName(uni->charselectdata, *c); fcitx_utils_alloc_cat_str(candWord.strExtra, " ", name); free(name); FcitxCandidateWordAppend(candList, &candWord); }
void ShowQuickPhraseMessage(QuickPhraseState *qpstate) { FcitxInputState *input = FcitxInstanceGetInputState(qpstate->owner); FcitxInputStateSetCursorPos(input, strlen(FcitxInputStateGetRawInputBuffer(input))); FcitxInstanceCleanInputWindowUp(qpstate->owner); FcitxMessagesAddMessageAtLast(FcitxInputStateGetAuxUp(input), MSG_TIPS, "%s", _("Quick Phrase: ")); FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_INPUT, "%s", FcitxInputStateGetRawInputBuffer(input)); FcitxMessagesAddMessageAtLast(FcitxInputStateGetClientPreedit(input), MSG_INPUT, "%s", FcitxInputStateGetRawInputBuffer(input)); }
static void ShowAutoEngMessage(FcitxAutoEngState *autoEngState, INPUT_RETURN_VALUE *retval) { FcitxInputState* input = FcitxInstanceGetInputState(autoEngState->owner); char *raw_buff; int buff_len; FcitxInstanceCleanInputWindow(autoEngState->owner); if (autoEngState->buf[0] == '\0') return; raw_buff = FcitxInputStateGetRawInputBuffer(input); buff_len = strlen(autoEngState->buf); strncpy(raw_buff, autoEngState->buf, MAX_USER_INPUT); if (buff_len > MAX_USER_INPUT) { raw_buff[MAX_USER_INPUT] = '\0'; FcitxInputStateSetRawInputBufferSize(input, MAX_USER_INPUT); } else { FcitxInputStateSetRawInputBufferSize(input, buff_len); } if (buff_len > AUTOENG_MAX_PREEDIT) { FcitxMessagesAddMessageStringsAtLast(FcitxInputStateGetPreedit(input), MSG_INPUT, autoEngState->buf + buff_len - AUTOENG_MAX_PREEDIT); FcitxInputStateSetCursorPos(input, AUTOENG_MAX_PREEDIT); } else { FcitxMessagesAddMessageStringsAtLast(FcitxInputStateGetPreedit(input), MSG_INPUT, autoEngState->buf); FcitxInputStateSetCursorPos(input, autoEngState->index); } FcitxMessagesAddMessageStringsAtLast(FcitxInputStateGetClientPreedit(input), MSG_INPUT, autoEngState->buf); FcitxInputStateSetClientCursorPos(input, autoEngState->index); FcitxInputStateSetShowCursor(input, true); // AutoEngGetSpellHint(autoEngState); FcitxMessagesAddMessageStringsAtLast(FcitxInputStateGetAuxDown(input), MSG_TIPS, //_("Press Enter to input text")); " "); *retval |= IRV_FLAG_UPDATE_INPUT_WINDOW; }
static boolean AutoEngCheckPreedit(FcitxAutoEngState *autoEngState) { FcitxInputState *input; char *preedit; input = FcitxInstanceGetInputState(autoEngState->owner); preedit = FcitxUIMessagesToCString(FcitxInputStateGetPreedit(input)); boolean res = !(preedit && *fcitx_utils_get_ascii_end(preedit)); free(preedit); return res; }
char* PinyinEnhanceGetSelected(PinyinEnhance *pyenhance) { FcitxInputState *input; char *string; input = FcitxInstanceGetInputState(pyenhance->owner); string = FcitxUIMessagesToCString(FcitxInputStateGetPreedit(input)); /** * Haven't found a way to handle the case when the word before the current * one is not handled by im-engine (e.g. a invalid pinyin in sunpinyin). * (a possible solution is to deal with different im-engine separately). * Not very important though.... **/ *fcitx_utils_get_ascii_part(string) = '\0'; return string; }
void ShowAutoEngMessage(FcitxAutoEngState* autoEngState) { FcitxInputState* input = FcitxInstanceGetInputState(autoEngState->owner); FcitxInstanceCleanInputWindow(autoEngState->owner); if (autoEngState->buf[0] == '\0') return; FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_INPUT, "%s", autoEngState->buf); strcpy(FcitxInputStateGetRawInputBuffer(input), autoEngState->buf); FcitxInputStateSetRawInputBufferSize(input, strlen(autoEngState->buf)); FcitxInputStateSetCursorPos(input, FcitxInputStateGetRawInputBufferSize(input)); FcitxInputStateSetShowCursor(input, true); FcitxMessagesAddMessageAtLast(FcitxInputStateGetAuxDown(input), MSG_TIPS, _("Press Enter to input text")); }
void ShowQuickPhraseMessage(QuickPhraseState *qpstate) { char c[2]; QuickPhraseFillKeyString(qpstate, c); FcitxInputState *input = FcitxInstanceGetInputState(qpstate->owner); FcitxInputStateSetCursorPos(input, strlen(qpstate->buffer)); FcitxInputStateSetClientCursorPos(input, strlen(qpstate->buffer) + strlen(c)); FcitxInstanceCleanInputWindowUp(qpstate->owner); FcitxMessagesAddMessageStringsAtLast(FcitxInputStateGetAuxUp(input), MSG_TIPS, _("Quick Phrase: "), (qpstate->append) ? c : ""); FcitxMessagesAddMessageStringsAtLast(FcitxInputStateGetPreedit(input), MSG_INPUT, qpstate->buffer); FcitxMessagesAddMessageStringsAtLast(FcitxInputStateGetClientPreedit(input), MSG_INPUT, (qpstate->append) ? c : "", qpstate->buffer); }
static INPUT_RETURN_VALUE AutoEngCheckSelect(FcitxAutoEngState *autoEngState, FcitxKeySym sym, unsigned int state) { FcitxInstance *instance = autoEngState->owner; FcitxCandidateWordList *cand_list = FcitxInputStateGetCandidateList( FcitxInstanceGetInputState(autoEngState->owner)); if (!FcitxCandidateWordGetListSize(cand_list)) return IRV_TO_PROCESS; FcitxInputState *input = FcitxInstanceGetInputState(instance); FcitxGlobalConfig *fc = FcitxInstanceGetGlobalConfig(instance); int key; FcitxCandidateWord *cand_word; if (FcitxHotkeyIsHotKey(sym, state, fc->nextWord)) { if (!autoEngState->cursor_moved) { cand_word = FcitxCandidateWordGetCurrentWindow(cand_list); } else { cand_word = FcitxCandidateWordGetFocus(cand_list, true); cand_word = FcitxCandidateWordGetNext(cand_list, cand_word); if (!cand_word) { FcitxCandidateWordSetPage(cand_list, 0); } else { FcitxCandidateWordSetFocus( cand_list, FcitxCandidateWordGetIndex(cand_list, cand_word)); } } } else if (FcitxHotkeyIsHotKey(sym, state, fc->prevWord)) { if (!autoEngState->cursor_moved) { cand_word = FcitxCandidateWordGetByIndex( cand_list, FcitxCandidateWordGetCurrentWindowSize(cand_list) - 1); } else { cand_word = FcitxCandidateWordGetFocus(cand_list, true); cand_word = FcitxCandidateWordGetPrev(cand_list, cand_word); if (cand_word) { FcitxCandidateWordSetFocus( cand_list, FcitxCandidateWordGetIndex(cand_list, cand_word)); } } } else if (FcitxHotkeyIsHotKey(sym, state, FcitxConfigPrevPageKey(instance, fc))) { boolean has_prev_page; cand_word = FcitxCandidateWordGetFocus(cand_list, true); has_prev_page = FcitxCandidateWordGoPrevPage(cand_list); if (!autoEngState->cursor_moved) { cand_word = NULL; } else if (has_prev_page) { cand_word = FcitxCandidateWordGetCurrentWindow(cand_list) + FcitxCandidateWordGetCurrentWindowSize(cand_list) - 1; } } else if (FcitxHotkeyIsHotKey(sym, state, FcitxConfigNextPageKey(instance, fc))) { boolean has_next_page; cand_word = FcitxCandidateWordGetFocus(cand_list, true); has_next_page = FcitxCandidateWordGoNextPage(cand_list); if (!autoEngState->cursor_moved) { cand_word = NULL; } else if (has_next_page) { cand_word = FcitxCandidateWordGetCurrentWindow(cand_list); } } else if ((key = FcitxCandidateWordCheckChooseKey(cand_list, sym, state)) >= 0) { return FcitxCandidateWordChooseByIndex(cand_list, key); } else { return IRV_TO_PROCESS; } if (cand_word) { FcitxCandidateWordSetType(cand_word, MSG_CANDIATE_CURSOR); if (!autoEngState->cursor_moved) AutoEngSwapBuff(autoEngState); AutoEngSetBuff(autoEngState, cand_word->strWord, '\0'); autoEngState->cursor_moved = true; } else if (autoEngState->cursor_moved) { AutoEngSwapBuff(autoEngState); autoEngState->cursor_moved = false; } else { return IRV_FLAG_UPDATE_INPUT_WINDOW; } FcitxMessages *client_preedit = FcitxInputStateGetClientPreedit(input); FcitxMessages *preedit = FcitxInputStateGetPreedit(input); FcitxMessagesSetMessageCount(client_preedit, 0); FcitxMessagesSetMessageCount(preedit, 0); FcitxMessagesAddMessageStringsAtLast(client_preedit, MSG_INPUT, autoEngState->buf); FcitxMessagesAddMessageStringsAtLast(preedit, MSG_INPUT, autoEngState->buf); FcitxInputStateSetCursorPos(input, autoEngState->index); FcitxInputStateSetClientCursorPos(input, autoEngState->index); return IRV_FLAG_UPDATE_INPUT_WINDOW; }
/** * @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; }
void FcitxLibpinyinUpdatePreedit(FcitxLibpinyin* libpinyin, char* sentence) { FcitxInstance* instance = libpinyin->owner->owner; FcitxInputState* input = FcitxInstanceGetInputState(instance); int offset = LibpinyinGetOffset(libpinyin); if (libpinyin->type == LPT_Pinyin) { int libpinyinLen = strlen(libpinyin->inst->m_raw_full_pinyin); int fcitxLen = strlen(libpinyin->buf); if (fcitxLen != libpinyinLen) { strcpy(libpinyin->buf, libpinyin->inst->m_raw_full_pinyin); libpinyin->cursor_pos += libpinyinLen - fcitxLen; } } int pyoffset = LibpinyinGetPinyinOffset(libpinyin); if (pyoffset > libpinyin->cursor_pos) libpinyin->cursor_pos = pyoffset; int hzlen = 0; if (fcitx_utf8_strlen(sentence) > offset) hzlen = fcitx_utf8_get_nth_char(sentence, offset) - sentence; else hzlen = strlen(sentence); if (hzlen > 0) { char* buf = (char*) fcitx_utils_malloc0((hzlen + 1) * sizeof(char)); strncpy(buf, sentence, hzlen); buf[hzlen] = 0; FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_INPUT, "%s", buf); free(buf); } int charcurpos = hzlen; int lastpos = pyoffset; int curoffset = pyoffset; for (int i = offset; i < libpinyin->inst->m_pinyin_keys->len; i ++) { PinyinKey* pykey = &g_array_index(libpinyin->inst->m_pinyin_keys, PinyinKey, i); PinyinKeyPos* pykeypos = &g_array_index(libpinyin->inst->m_pinyin_key_rests, PinyinKeyPos, i); if (lastpos > 0) { FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), " "); if (curoffset < libpinyin->cursor_pos) charcurpos ++; for (int j = lastpos; j < pykeypos->m_raw_begin; j ++) { char temp[2] = {'\0', '\0'}; temp[0] = libpinyin->buf[j]; FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), temp); if (curoffset < libpinyin->cursor_pos) { curoffset ++; charcurpos ++; } } } lastpos = pykeypos->m_raw_end; switch (libpinyin->type) { case LPT_Pinyin: { gchar* pystring = pykey->get_pinyin_string(); FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", pystring); size_t pylen = strlen(pystring); if (curoffset + pylen < libpinyin->cursor_pos) { curoffset += pylen; charcurpos += pylen; } else { charcurpos += libpinyin->cursor_pos - curoffset; curoffset = libpinyin->cursor_pos; } g_free(pystring); break; } case LPT_Shuangpin: { if (pykeypos->length() == 2) { const char* initial = 0; if (pykey->m_initial == CHEWING_ZERO_INITIAL) initial = "'"; else initial = get_initial_string(pykey); if (curoffset + 1 <= libpinyin->cursor_pos) { curoffset += 1; charcurpos += strlen(initial); } FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", initial); if (curoffset + 1 <= libpinyin->cursor_pos) { curoffset += 1; charcurpos += strlen(get_middle_string(pykey)) + strlen(get_final_string(pykey)); } FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s%s", get_middle_string(pykey), get_final_string(pykey)); } else if (pykeypos->length() == 1) { gchar* pystring = pykey->get_pinyin_string(); if (curoffset + 1 <= libpinyin->cursor_pos) { curoffset += 1; charcurpos += strlen(pystring); } FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", pystring); g_free(pystring); } break; } case LPT_Zhuyin: { gchar* pystring = pykey->get_chewing_string(); FcitxMessagesAddMessageAtLast(FcitxInputStateGetPreedit(input), MSG_CODE, "%s", pystring); if (curoffset + pykeypos->length() <= libpinyin->cursor_pos) { curoffset += pykeypos->length(); charcurpos += strlen(pystring); } else { int diff = libpinyin->cursor_pos - curoffset; curoffset = libpinyin->cursor_pos; size_t len = fcitx_utf8_strlen(pystring); if (pykey->m_tone != CHEWING_ZERO_TONE) len --; if (diff > len) charcurpos += strlen(pystring); else { charcurpos += fcitx_utf8_get_nth_char(pystring, diff) - pystring; } } g_free(pystring); break; } } } int buflen = strlen(libpinyin->buf); if (lastpos < buflen) { FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), " "); if (lastpos < libpinyin->cursor_pos) charcurpos ++; for (int i = lastpos; i < buflen; i ++) { char temp[2] = {'\0', '\0'}; temp[0] = libpinyin->buf[i]; FcitxMessagesMessageConcatLast (FcitxInputStateGetPreedit(input), temp); if (lastpos < libpinyin->cursor_pos) { charcurpos ++; lastpos++; } } } FcitxInputStateSetCursorPos(input, charcurpos); }
/** * @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); }
char *GetCurrentString(FcitxCloudPinyin* cloudpinyin) { FcitxIM* im = FcitxInstanceGetCurrentIM(cloudpinyin->owner); if (!im) return NULL; FcitxInputState* input = FcitxInstanceGetInputState(cloudpinyin->owner); char* string = FcitxUIMessagesToCString(FcitxInputStateGetPreedit(input)); char p[MAX_USER_INPUT + 1], *pinyin, *lastpos; pinyin = SplitHZAndPY(string); lastpos = pinyin; boolean endflag; int hzlength = pinyin - string; size_t plength = hzlength; strncpy(p, string, hzlength); p[hzlength] = '\0'; do { endflag = (*pinyin != '\0'); if (*pinyin == ' ' || *pinyin == '\'' || *pinyin == '\0') { *pinyin = 0; if (*lastpos != '\0') { char* result = NULL; FcitxModuleFunctionArg arg; arg.args[0] = lastpos; boolean isshuangpin = false; if (strcmp(im->uniqueName, "sunpinyin") == 0) { boolean issp = false; arg.args[1] = &issp; result = FcitxModuleInvokeFunctionByName(cloudpinyin->owner, "fcitx-sunpinyin", 0, arg); isshuangpin = issp; } else if (strcmp(im->uniqueName, "shuangpin") == 0) { isshuangpin = true; result = InvokeFunction(cloudpinyin->owner, FCITX_PINYIN, SP2QP, arg); } if (isshuangpin) { if (result) { if (plength + strlen(result) < MAX_USER_INPUT) { strcat(p + plength, result); plength += strlen(result); free(result); } else { p[hzlength] = '\0'; break; } } } else { if (plength + strlen(lastpos) < MAX_USER_INPUT) { strcat(p + plength, lastpos); plength += strlen(lastpos); } else { p[hzlength] = '\0'; break; } } } lastpos = pinyin + 1; } pinyin ++; } while(endflag); free(string); /* no pinyin append, return NULL for off it */ if (p[hzlength] == '\0') return NULL; else return strdup(p); }
char *GetCurrentString(FcitxCloudPinyin* cloudpinyin, char **ascii_part) { FcitxIM* im = FcitxInstanceGetCurrentIM(cloudpinyin->owner); if (!im) { *ascii_part = NULL; return NULL; } FcitxInputState* input = FcitxInstanceGetInputState(cloudpinyin->owner); char* string = FcitxUIMessagesToCString(FcitxInputStateGetPreedit(input)); char p[MAX_USER_INPUT + 1], *pinyin, *lastpos; pinyin = fcitx_utils_get_ascii_part(string); lastpos = pinyin; boolean endflag; int hzlength = pinyin - string; size_t plength = hzlength; strncpy(p, string, hzlength); p[hzlength] = '\0'; // lastpos points to the start of a pinyin // pinyin points to the end of current pinyin // for example // xi'an // | | // l p // and we check the separator by supportSeparator for each engine. // shuangpin-libpinyin returns full pinyin in preedit, so we also treat space as separator. do { endflag = (*pinyin != '\0'); if (*pinyin == ' ' || *pinyin == '\'' || *pinyin == '\0') { boolean isSeparator = false; // skip all continous separator while (*pinyin == ' ' || *pinyin == '\'') { isSeparator = isSeparator || (*pinyin) == '\'' || (strcmp(im->uniqueName, "shuangpin-libpinyin") == 0 && (*pinyin) == ' '); *pinyin = 0; pinyin++; } if (*lastpos != '\0') { char* result = NULL; boolean isshuangpin = false; if (strcmp(im->uniqueName, "sunpinyin") == 0) { FCITX_DEF_MODULE_ARGS(args, lastpos, &isshuangpin); result = FcitxSunPinyinInvokeGetFullPinyin(cloudpinyin->owner, args); } else if (strcmp(im->uniqueName, "shuangpin") == 0) { isshuangpin = true; result = FcitxPinyinSP2QP(cloudpinyin->owner, lastpos); } if (isshuangpin) { if (result) { if (plength + strlen(result) + (engine[cloudpinyin->config.source].supportSeparator ? 1 : 0) < MAX_USER_INPUT) { strcat(p + plength, result); plength += strlen(result); if (engine[cloudpinyin->config.source].supportSeparator) { strcat(p + plength, "'"); plength += 1; } free(result); } else { p[hzlength] = '\0'; break; } } } else { #define PINYIN_USE_SEPARATOR_CASE (isSeparator && engine[cloudpinyin->config.source].supportSeparator) if (plength + strlen(lastpos) + (PINYIN_USE_SEPARATOR_CASE ? 1 : 0) < MAX_USER_INPUT) { strcat(p + plength, lastpos); plength += strlen(lastpos); if (PINYIN_USE_SEPARATOR_CASE) { strcat(p + plength, "'"); plength += 1; } } else { p[hzlength] = '\0'; break; } } isSeparator = false; } lastpos = pinyin; } else { pinyin ++; } } while(endflag); free(string); /* no pinyin append, return NULL for off it */ if (p[hzlength] == '\0') { *ascii_part = NULL; return NULL; } else { if (plength >= 1 && p[plength - 1] == '\'') { p[plength - 1] = '\0'; } char *res = strdup(p); *ascii_part = res + hzlength; return res; } }
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; }