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 XimCommitString(void* arg, FcitxInputContext* ic, const char* str) { FcitxXimFrontend* xim = (FcitxXimFrontend*) arg; XTextProperty tp; IMCommitStruct cms; FcitxXimIC* ximic = (FcitxXimIC*) ic->privateic; /* avoid Seg fault */ if (!ic) return; /* * I'm not sure whether xim should commit string before preedit done * but this can fix opera's crash in specific input box * quite strange. */ if (GetXimIC(ic)->bPreeditStarted == true) { XimPreeditCallbackDraw(xim, GetXimIC(ic), "", 0); XimPreeditCallbackDone(xim, GetXimIC(ic)); GetXimIC(ic)->bPreeditStarted = false; } Xutf8TextListToTextProperty(xim->display, (char **) &str, 1, XCompoundTextStyle, &tp); memset(&cms, 0, sizeof(IMCommitStruct)); cms.major_code = XIM_COMMIT; cms.icid = ximic->id; cms.connect_id = ximic->connect_id; cms.flag = XimLookupChars; cms.commit_string = (char *) tp.value; IMCommitString(xim->ims, (XPointer) & cms); XFree(tp.value); }