/** * @brief Process Key Input and return the status * * @param keycode keycode from XKeyEvent * @param state state from XKeyEvent * @param count count from XKeyEvent * @return INPUT_RETURN_VALUE **/ __EXPORT_API INPUT_RETURN_VALUE FcitxLibpinyinDoInput(void* arg, FcitxKeySym sym, unsigned int state) { FcitxLibpinyin* libpinyin = (FcitxLibpinyin*) arg; FcitxLibpinyinConfig* config = &libpinyin->owner->config; FcitxInputState* input = FcitxInstanceGetInputState(libpinyin->owner->owner); if (FcitxHotkeyIsHotKeySimple(sym, state)) { /* there is some special case that ';' is used */ if (FcitxHotkeyIsHotKeyLAZ(sym, state) || sym == '\'' || (FcitxHotkeyIsHotKey(sym, state, FCITX_SEMICOLON) && libpinyin->type == LPT_Shuangpin && (config->spScheme == FCITX_SHUANG_PIN_MS || config->spScheme == FCITX_SHUANG_PIN_ZIGUANG)) || (libpinyin->type == LPT_Zhuyin && LibpinyinCheckZhuyinKey(sym, config->zhuyinLayout, config->useTone)) ) { if (strlen(libpinyin->buf) == 0 && (sym == '\'' || sym == ';')) return IRV_TO_PROCESS; if (strlen(libpinyin->buf) < MAX_PINYIN_INPUT) { size_t len = strlen(libpinyin->buf); if (libpinyin->buf[libpinyin->cursor_pos] != 0) { memmove(libpinyin->buf + libpinyin->cursor_pos + 1, libpinyin->buf + libpinyin->cursor_pos, len - libpinyin->cursor_pos); } libpinyin->buf[len + 1] = 0; libpinyin->buf[libpinyin->cursor_pos] = (char) (sym & 0xff); libpinyin->cursor_pos ++; size_t parselen = FcitxLibpinyinParse(libpinyin, libpinyin->buf); if (parselen == 0 && strlen(libpinyin->buf) == 1 && libpinyin->type != LPT_Shuangpin && !(libpinyin->type == LPT_Pinyin && !libpinyin->owner->config.incomplete) && !(libpinyin->type == LPT_Zhuyin && !libpinyin->owner->config.chewingIncomplete)) { FcitxLibpinyinReset(libpinyin); return IRV_TO_PROCESS; } return IRV_DISPLAY_CANDWORDS; } else return IRV_DO_NOTHING; } } if (FcitxHotkeyIsHotKey(sym, state, FCITX_SPACE) || (libpinyin->type == LPT_Zhuyin && FcitxHotkeyIsHotKey(sym, state, FCITX_ENTER))) { size_t len = strlen(libpinyin->buf); if (len == 0) return IRV_TO_PROCESS; return FcitxCandidateWordChooseByIndex(FcitxInputStateGetCandidateList(input), 0); } if (FcitxHotkeyIsHotKey(sym, state, FCITX_LIBPINYIN_SHIFT_ENTER)) { size_t len = strlen(libpinyin->buf); if (len == 0) return IRV_TO_PROCESS; strcpy(FcitxInputStateGetOutputString(input), libpinyin->buf); return IRV_COMMIT_STRING; } if (FcitxHotkeyIsHotKey(sym, state, FCITX_BACKSPACE) || FcitxHotkeyIsHotKey(sym, state, FCITX_DELETE)) { if (strlen(libpinyin->buf) > 0) { int offset = LibpinyinGetOffset(libpinyin); if (offset != 0 && FcitxHotkeyIsHotKey(sym, state, FCITX_BACKSPACE)) { g_array_remove_index_fast(libpinyin->fixed_string, libpinyin->fixed_string->len - 1); pinyin_clear_constraint(libpinyin->inst, LibpinyinGetOffset(libpinyin)); } else { if (FcitxHotkeyIsHotKey(sym, state, FCITX_BACKSPACE)) { if (libpinyin->cursor_pos > 0) libpinyin->cursor_pos -- ; else return IRV_DO_NOTHING; } size_t len = strlen(libpinyin->buf); if (libpinyin->cursor_pos == (int)len) return IRV_DO_NOTHING; memmove(libpinyin->buf + libpinyin->cursor_pos, libpinyin->buf + libpinyin->cursor_pos + 1, len - libpinyin->cursor_pos - 1); libpinyin->buf[strlen(libpinyin->buf) - 1] = 0; if (libpinyin->buf[0] == '\0') return IRV_CLEAN; else FcitxLibpinyinParse(libpinyin, libpinyin->buf); } return IRV_DISPLAY_CANDWORDS; } else return IRV_TO_PROCESS; } else { if (strlen(libpinyin->buf) > 0) { if (FcitxHotkeyIsHotKey(sym, state, FCITX_LEFT)) { if (libpinyin->cursor_pos > 0) { if ( libpinyin->cursor_pos == LibpinyinGetPinyinOffset(libpinyin)) { g_array_remove_index_fast(libpinyin->fixed_string, libpinyin->fixed_string->len - 1); pinyin_clear_constraint(libpinyin->inst, LibpinyinGetOffset(libpinyin)); return IRV_DISPLAY_CANDWORDS; } else { libpinyin->cursor_pos--; return IRV_DISPLAY_CANDWORDS; } } return IRV_DO_NOTHING; } else if (FcitxHotkeyIsHotKey(sym, state, FCITX_RIGHT)) { size_t len = strlen(libpinyin->buf); if (libpinyin->cursor_pos < (int) len) { libpinyin->cursor_pos ++ ; return IRV_DISPLAY_CANDWORDS; } return IRV_DO_NOTHING; } else if (FcitxHotkeyIsHotKey(sym, state, FCITX_HOME)) { int offset = LibpinyinGetPinyinOffset(libpinyin); if ( libpinyin->cursor_pos != offset) { libpinyin->cursor_pos = offset; return IRV_DISPLAY_CANDWORDS; } return IRV_DO_NOTHING; } else if (FcitxHotkeyIsHotKey(sym, state, FCITX_END)) { size_t len = strlen(libpinyin->buf); if (libpinyin->cursor_pos != (int) len) { libpinyin->cursor_pos = len ; return IRV_DISPLAY_CANDWORDS; } return IRV_DO_NOTHING; } } else { return IRV_TO_PROCESS; } } return IRV_TO_PROCESS; }
static PyObject * SimplePinyin_convert(SimplePinyin* self, PyObject *args, PyObject *kwds) { const char *pinyin = ""; const char *prefix = ""; static char *kwlist[] = {"pinyin", "prefix", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", kwlist, &pinyin, &prefix)) return NULL; // printf("DEBUG: pinyin=%s, prefix=%s.\n", pinyin, prefix); pinyin_parse_more_full_pinyins(self->instance, pinyin); pinyin_guess_sentence_with_prefix(self->instance, prefix); pinyin_guess_full_pinyin_candidates(self->instance, 0); guint num = 0; guint16 *arr = NULL; //FIXME: Use a name better than `arr` pinyin_get_n_pinyin(self->instance, &num); arr = PyMem_New(guint16, num); // printf("DEBUG: num=%i, arr=%p.\n", num, arr); for (size_t i = 0; i < num; ++i) { ChewingKeyRest *key_rest = NULL; pinyin_get_pinyin_key_rest(self->instance, i, &key_rest); pinyin_get_pinyin_key_rest_length(self->instance, key_rest, &arr[i]); if (i > 0) { arr[i] += arr[i-1]; } // printf("DEBUG: %i\n", arr[i]); } guint len = 0; pinyin_get_n_candidate(self->instance, &len); // printf("DEBUG: len=%i\n", len); PyObject *candidate_list = PyList_New(len); PyObject *match_len_list = PyList_New(len); for (size_t i = 0; i < len; ++i) { lookup_candidate_t * candidate = NULL; pinyin_get_candidate(self->instance, i, &candidate); const char * word = NULL; pinyin_get_candidate_string(self->instance, candidate, &word); PyObject *ob_word = NULL; ob_word = Py_BuildValue("s", word); PyList_SetItem(candidate_list, i, ob_word); lookup_candidate_type_t type; pinyin_get_candidate_type(self->instance, candidate, &type); // printf("DEBUG: type=%i\n", type); int cursor = pinyin_choose_candidate(self->instance, 0, candidate); int match_len = 0; int index = 0; switch (type) { case BEST_MATCH_CANDIDATE: match_len = strlen(pinyin); break; case DIVIDED_CANDIDATE: //FIXME: we assume that only one key get divided index = cursor-2; //FIXME: remove the below hack if possible if (index >= num) { index = num-1; } match_len = arr[index]; break; case RESPLIT_CANDIDATE: case NORMAL_CANDIDATE: index = cursor-1; match_len = arr[index]; default: break; } // printf("DEBUG: match_len=%i\n", match_len); PyObject *ob_match_len = NULL; ob_match_len = Py_BuildValue("i", match_len); PyList_SetItem(match_len_list, i, ob_match_len); pinyin_clear_constraint(self->instance, 0); // printf("DEBUG: %s %d\n", word, arr[cursor-1]); } PyMem_Del(arr); pinyin_reset(self->instance); PyObject *ob_pair = NULL; ob_pair = Py_BuildValue("(O,O)", candidate_list, match_len_list); return ob_pair; }