Exemplo n.º 1
0
/**
 * @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;
}
Exemplo n.º 2
0
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;
}