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 FcitxKkcOnClose(void* arg, FcitxIMCloseEventType event) { FcitxKkc *kkc = (FcitxKkc*)arg; if (event == CET_LostFocus) { // TODO } else if (event == CET_ChangeByUser) { kkc_context_reset(kkc->context); } else if (event == CET_ChangeByInactivate) { KkcSegmentList* segments = kkc_context_get_segments(kkc->context); FcitxGlobalConfig* config = FcitxInstanceGetGlobalConfig(kkc->owner); if (config->bSendTextWhenSwitchEng) { FcitxMessagesSetMessageCount(kkc->tempMsg, 0); if (kkc_segment_list_get_cursor_pos(segments) >= 0) { int i = 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); FcitxMessagesAddMessageAtLast(kkc->tempMsg, MSG_INPUT, "%s", str); } } else { gchar* str = kkc_context_get_input(kkc->context); FcitxMessagesAddMessageAtLast(kkc->tempMsg, MSG_INPUT, "%s", str); g_free(str); } if (FcitxMessagesGetMessageCount(kkc->tempMsg) > 0) { char* commit = FcitxUIMessagesToCString(kkc->tempMsg); FcitxInstanceCommitString(kkc->owner, FcitxInstanceGetCurrentIC(kkc->owner), commit); free(commit); } } kkc_context_reset(kkc->context); } }
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; }
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 }
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; }
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; } }