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); }
boolean XimCheckICFromSameApplication(void* arg, FcitxInputContext* icToCheck, FcitxInputContext* ic) { FCITX_UNUSED(arg); FcitxXimIC* ximictoCheck = GetXimIC(icToCheck); FcitxXimIC* ximic = GetXimIC(ic); return ximictoCheck->connect_id == ximic->connect_id; }
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); }
pid_t XimGetPid(void* arg, FcitxInputContext* ic) { FcitxXimFrontend* xim = (FcitxXimFrontend*) arg; Window w; FcitxXimIC* ximic = GetXimIC(ic); if (!(w = ximic->focus_win)) w = ximic->client_win; return XimFindApplicationPid(xim, w); }
Bool XIMUnsetFocusHandler(FcitxXimFrontend* xim, IMChangeICStruct * call_data) { FcitxInputContext* ic = FcitxInstanceGetCurrentIC(xim->owner); if (ic && GetXimIC(ic)->id == call_data->icid) { FcitxUICommitPreedit(xim->owner); FcitxUICloseInputWindow(xim->owner); FcitxInstanceSetCurrentIC(xim->owner, NULL); FcitxUIOnInputUnFocus(xim->owner); } return True; }
void XimForwardKey(void *arg, FcitxInputContext* ic, FcitxKeyEventType event, FcitxKeySym sym, unsigned int state) { FcitxXimFrontend* xim = (FcitxXimFrontend*) arg; Window win; if (!(win = GetXimIC(ic)->focus_win)) win = GetXimIC(ic)->client_win; XEvent xEvent; memset(&xEvent, 0, sizeof(xEvent)); xEvent.xkey.type = (event == FCITX_PRESS_KEY) ? KeyPress : KeyRelease; xEvent.xkey.serial = xim->currentSerialNumberKey; xEvent.xkey.send_event = False; xEvent.xkey.display = xim->display; xEvent.xkey.window = win; xEvent.xkey.root = DefaultRootWindow(xim->display); xEvent.xkey.subwindow = None; xEvent.xkey.time = CurrentTime; xEvent.xkey.state = state; xEvent.xkey.keycode = XKeysymToKeycode(xim->display, sym); xEvent.xkey.same_screen = False; XimForwardKeyInternal(xim, GetXimIC(ic), &xEvent); }
void XimSetWindowOffset(void* arg, FcitxInputContext* ic, int x, int y) { FcitxXimFrontend* xim = (FcitxXimFrontend*) arg; FcitxXimIC* ximic = GetXimIC(ic); Window window, dst; if (!(window = ximic->focus_win)) window = ximic->client_win; if (window != None) { XTranslateCoordinates(xim->display, RootWindow(xim->display, xim->iScreen), window, x, y, &ic->offset_x, &ic->offset_y, &dst ); } }
void SetTrackPos(FcitxXimFrontend* xim, FcitxInputContext* ic, IMChangeICStruct * call_data) { if (ic == NULL) return; int i; FcitxXimIC* ximic = GetXimIC(ic); if (call_data) { XICAttribute *pre_attr = ((IMChangeICStruct *) call_data)->preedit_attr; for (i = 0; i < (int)((IMChangeICStruct *) call_data)->preedit_attr_num; i++, pre_attr++) { if (!strcmp(XNSpotLocation, pre_attr->name)) { ximic->bHasCursorLocation = true; ximic->offset_x = (*(XPoint *) pre_attr->value).x; ximic->offset_y = (*(XPoint *) pre_attr->value).y; } } } Window window; if (!(window = ximic->focus_win)) window = ximic->client_win; if (window != None) { Window dst; XWindowAttributes attr; XGetWindowAttributes(xim->display, window, &attr); if (ximic->offset_x < 0 && ximic->offset_y < 0) { XTranslateCoordinates(xim->display, window, RootWindow(xim->display, xim->iScreen), 0, attr.height, &ic->offset_x, &ic->offset_y, &dst ); } else { XTranslateCoordinates(xim->display, window, RootWindow(xim->display, xim->iScreen), ximic->offset_x, ximic->offset_y, &ic->offset_x, &ic->offset_y, &dst); } } if (ic == FcitxInstanceGetCurrentIC(xim->owner)) FcitxUIMoveInputWindow(xim->owner); }
void XIMProcessKey(FcitxXimFrontend* xim, IMForwardEventStruct * call_data) { KeySym originsym; FcitxKeySym sym; XKeyEvent *kev; int keyCount; uint32_t state; char strbuf[STRBUFLEN]; FcitxInputContext* ic = FcitxInstanceGetCurrentIC(xim->owner); FcitxGlobalConfig* config = FcitxInstanceGetGlobalConfig(xim->owner); FcitxInputState* input = FcitxInstanceGetInputState(xim->owner); if (ic == NULL) { ic = FcitxInstanceFindIC(xim->owner, xim->frontendid, &call_data->icid); if (FcitxInstanceSetCurrentIC(xim->owner, ic) && ic) FcitxUIOnInputFocus(xim->owner); } if (ic == NULL) return; if (ic->frontendid != xim->frontendid || GetXimIC(ic)->id != call_data->icid) { ic = FcitxInstanceFindIC(xim->owner, xim->frontendid, &call_data->icid); if (ic == NULL) return; if (FcitxInstanceSetCurrentIC(xim->owner, ic)) FcitxUIOnInputFocus(xim->owner); } kev = (XKeyEvent *) & call_data->event; memset(strbuf, 0, STRBUFLEN); keyCount = XLookupString(kev, strbuf, STRBUFLEN, &originsym, NULL); const uint32_t originstate = kev->state; state = kev->state - (kev->state & FcitxKeyState_NumLock) - (kev->state & FcitxKeyState_CapsLock) - (kev->state & FcitxKeyState_ScrollLock); state &= FcitxKeyState_UsedMask; FcitxHotkeyGetKey((FcitxKeySym) originsym, state, &sym, &state); FcitxLog(DEBUG, "KeyRelease=%d state=%d KEYCODE=%d KEYSYM=%d keyCount=%d", (call_data->event.type == KeyRelease), state, kev->keycode, (int) sym, keyCount); xim->currentSerialNumberCallData = call_data->serial_number; xim->currentSerialNumberKey = kev->serial; FcitxKeyEventType type = (call_data->event.type == KeyRelease) ? (FCITX_RELEASE_KEY) : (FCITX_PRESS_KEY); if (ic->state == IS_CLOSED) { if (type == FCITX_PRESS_KEY && FcitxHotkeyIsHotKey(sym, state, config->hkTrigger)) { FcitxInstanceEnableIM(xim->owner, ic, false); return; } else { XimForwardKeyInternal(xim, GetXimIC(ic), &call_data->event ); return; } } FcitxInputStateSetKeyCode(input, kev->keycode); FcitxInputStateSetKeySym(input, originsym); FcitxInputStateSetKeyState(input, originstate); INPUT_RETURN_VALUE retVal = FcitxInstanceProcessKey(xim->owner, type, kev->time, sym, state); FcitxInputStateSetKeyCode(input, 0); FcitxInputStateSetKeySym(input, 0); FcitxInputStateSetKeyState(input, 0); if ((retVal & IRV_FLAG_FORWARD_KEY) || retVal == IRV_TO_PROCESS) { XimForwardKeyInternal(xim, GetXimIC(ic), &call_data->event ); } else { if (!GetXimIC(ic)->bHasCursorLocation) SetTrackPos(xim, ic, NULL); } xim->currentSerialNumberCallData = xim->currentSerialNumberKey = 0L; }