void XimUpdatePreedit(void* arg, FcitxInputContext* ic) { FcitxXimFrontend* xim = (FcitxXimFrontend*) arg; FcitxInputState* input = FcitxInstanceGetInputState(xim->owner); char* strPreedit = FcitxUIMessagesToCString(FcitxInputStateGetClientPreedit(input)); char* str = FcitxInstanceProcessOutputFilter(xim->owner, strPreedit); if (str) { free(strPreedit); strPreedit = str; } if (strlen(strPreedit) == 0 && GetXimIC(ic)->bPreeditStarted == true) { XimPreeditCallbackDraw(xim, GetXimIC(ic), strPreedit, 0); XimPreeditCallbackDone(xim, GetXimIC(ic)); GetXimIC(ic)->bPreeditStarted = false; } if (strlen(strPreedit) != 0 && GetXimIC(ic)->bPreeditStarted == false) { XimPreeditCallbackStart(xim, GetXimIC(ic)); GetXimIC(ic)->bPreeditStarted = true; } if (strlen(strPreedit) != 0) { XimPreeditCallbackDraw(xim, GetXimIC(ic), strPreedit, FcitxInputStateGetClientCursorPos(input)); } free(strPreedit); }
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 TestbedCallback(void* arg, FcitxSimpleEvent* event) { #define TESTBED_CASE(NAME) \ case SSE_##NAME: \ fprintf(stderr, "UI:" #NAME "\n"); FcitxInputState* input = FcitxInstanceGetInputState(instance); switch (event->type) { TESTBED_CASE(ShowInputWindow) { char* candidateword = FcitxUICandidateWordToCString(instance); char* str = FcitxInstanceProcessOutputFilter(instance, candidateword); if (str) { free(candidateword); candidateword = str; } fprintf(stderr, "CANDIDATE:%s\n", candidateword); free(candidateword); break; } TESTBED_CASE(CloseInputWindow) break; TESTBED_CASE(RegisterComplexStatus) break; TESTBED_CASE(RegisterStatus) break; TESTBED_CASE(UpdateComplexStatus) break; TESTBED_CASE(UpdateStatus) break; TESTBED_CASE(RegisterMenu) break; TESTBED_CASE(ShowMenu) break; TESTBED_CASE(CommitString){ fprintf(stderr, "COMMIT:%s\n", event->commitString); break; } TESTBED_CASE(UpdatePreedit) { char* clientPreedit = FcitxUIMessagesToCString(FcitxInputStateGetClientPreedit(input)); char* str = FcitxInstanceProcessOutputFilter(instance, clientPreedit); if (str) { free(clientPreedit); clientPreedit = str; } fprintf(stderr, "PREEDIT:%s\n", clientPreedit); free(clientPreedit); break; } } #undef TESTBED_CASE }
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 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)); }
FCITX_EXPORT_API void FcitxUICommitPreedit(FcitxInstance* instance) { if (instance->CurrentIC && !instance->config->bDontCommitPreeditWhenUnfocus && !(instance->CurrentIC->contextCaps & CAPACITY_CLIENT_UNFOCUS_COMMIT)) { FcitxInputState* input = FcitxInstanceGetInputState(instance); FcitxMessages* clientPreedit = FcitxInputStateGetClientPreedit(input); if (FcitxMessagesGetMessageCount(clientPreedit) > 0) { char* str = FcitxUIMessagesToCStringForCommit(clientPreedit); if (str[0]) { FcitxInstanceCommitString(instance, instance->CurrentIC, str); } free(str); } FcitxMessagesSetMessageCount(clientPreedit, 0); } }
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; }
FCITX_EXPORT_API void FcitxUICommitPreedit(FcitxInstance* instance) { if (!instance->CurrentIC) return; boolean callOnClose = false; boolean doServerSideCommit = false; if (!instance->config->bDontCommitPreeditWhenUnfocus && !(instance->CurrentIC->contextCaps & CAPACITY_CLIENT_UNFOCUS_COMMIT)) { callOnClose = true; doServerSideCommit = true; } if (instance->CurrentIC->contextCaps & CAPACITY_CLIENT_UNFOCUS_COMMIT) { callOnClose = true; } if (callOnClose) { FcitxIM* im = FcitxInstanceGetCurrentIM(instance); if (im && im->OnClose) { im->OnClose(im->klass, CET_LostFocus); } } if (doServerSideCommit) { FcitxInputState* input = FcitxInstanceGetInputState(instance); FcitxMessages* clientPreedit = FcitxInputStateGetClientPreedit(input); if (FcitxMessagesGetMessageCount(clientPreedit) > 0) { char* str = FcitxUIMessagesToCStringForCommit(clientPreedit); if (str[0]) { FcitxInstanceCommitString(instance, instance->CurrentIC, str); } free(str); } FcitxMessagesSetMessageCount(clientPreedit, 0); } }
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; }
/** * @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 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; }
void XimPreeditCallbackDraw(FcitxXimFrontend* xim, FcitxXimIC* ic, const char* preedit_string, int cursorPos) { XTextProperty tp; uint i, len; if (preedit_string == NULL) return; len = fcitx_utf8_strlen(preedit_string); if (len + 1 > xim->feedback_len) { xim->feedback_len = len + 1; if (xim->feedback) { xim->feedback = realloc(xim->feedback, sizeof(XIMFeedback) * xim->feedback_len); } else { xim->feedback = fcitx_utils_malloc0(sizeof(XIMFeedback) * xim->feedback_len); } } FcitxInputState* input = FcitxInstanceGetInputState(xim->owner); FcitxMessages* clientPreedit = FcitxInputStateGetClientPreedit(input); int offset = 0; for (i = 0; i < FcitxMessagesGetMessageCount(clientPreedit) ; i ++) { int type = FcitxMessagesGetClientMessageType(clientPreedit, i); char* str = FcitxMessagesGetMessageString(clientPreedit, i); int j = 0; XIMFeedback fb = 0; if ((type & MSG_NOUNDERLINE) == 0) fb |= XIMUnderline; if (type & MSG_HIGHLIGHT) fb |= XIMReverse; for (; j < fcitx_utf8_strlen(str); j++) { xim->feedback[offset] = fb; offset ++; } } xim->feedback[len] = 0; IMPreeditCBStruct* pcb = fcitx_utils_new(IMPreeditCBStruct); XIMText* text = fcitx_utils_new(XIMText); pcb->major_code = XIM_PREEDIT_DRAW; pcb->connect_id = ic->connect_id; pcb->icid = ic->id; pcb->todo.draw.caret = fcitx_utf8_strnlen(preedit_string, cursorPos); pcb->todo.draw.chg_first = 0; pcb->todo.draw.chg_length = ic->onspot_preedit_length; pcb->todo.draw.text = text; text->feedback = xim->feedback; Xutf8TextListToTextProperty(xim->display, (char **)&preedit_string, 1, XCompoundTextStyle, &tp); text->encoding_is_wchar = 0; text->length = strlen((char*)tp.value); text->string.multi_byte = (char*)tp.value; XimPendingCall(xim, XCT_CALLCALLBACK, (XPointer) pcb); ic->onspot_preedit_length = len; }