Пример #1
0
Файл: ui.c Проект: eguopt/fcitx
FCITX_EXPORT_API
int FcitxUINewMessageToOldStyleMessage(FcitxInstance* instance, FcitxMessages* msgUp, FcitxMessages* msgDown)
{
    int i = 0;
    FcitxInputState* input = instance->input;
    int extraLength = input->iCursorPos;
    FcitxMessagesSetMessageCount(msgUp, 0);
    FcitxMessagesSetMessageCount(msgDown, 0);

    for (i = 0; i < FcitxMessagesGetMessageCount(input->msgAuxUp) ; i ++) {
        FcitxMessagesAddMessageAtLast(msgUp, FcitxMessagesGetMessageType(input->msgAuxUp, i), "%s", FcitxMessagesGetMessageString(input->msgAuxUp, i));
        extraLength += strlen(FcitxMessagesGetMessageString(input->msgAuxUp, i));
    }

    for (i = 0; i < FcitxMessagesGetMessageCount(input->msgPreedit) ; i ++)
        FcitxMessagesAddMessageAtLast(msgUp, FcitxMessagesGetMessageType(input->msgPreedit, i), "%s", FcitxMessagesGetMessageString(input->msgPreedit, i));

    for (i = 0; i < FcitxMessagesGetMessageCount(input->msgAuxDown) ; i ++)
        FcitxMessagesAddMessageAtLast(msgDown, FcitxMessagesGetMessageType(input->msgAuxDown, i), "%s", FcitxMessagesGetMessageString(input->msgAuxDown, i));

    FcitxCandidateWord* candWord = NULL;

    for (candWord = FcitxCandidateWordGetCurrentWindow(input->candList), i = 0;
            candWord != NULL;
            candWord = FcitxCandidateWordGetCurrentWindowNext(input->candList, candWord), i ++) {
        char strTemp[3] = { '\0', '\0', '\0' };
        strTemp[0] = FcitxCandidateWordGetChoose(input->candList)[i];

        if (instance->config->bPointAfterNumber)
            strTemp[1] = '.';

        unsigned int mod = FcitxCandidateWordGetModifier(input->candList);

        FcitxMessagesAddMessageAtLast(msgDown, MSG_INDEX, "%s%s%s%s%s",
                                      (mod & FcitxKeyState_Super) ? "M-" : "",
                                      (mod & FcitxKeyState_Ctrl) ? "C-" : "",
                                      (mod & FcitxKeyState_Alt) ? "A-" : "",
                                      (mod & FcitxKeyState_Shift) ? "S-" : "",
                                      strTemp);

        FcitxMessageType type = candWord->wordType;

        if (i == 0
            && FcitxCandidateWordGetCurrentPage(input->candList) == 0
            && type == MSG_OTHER
            && !FcitxInstanceGetContextBoolean(instance, CONTEXT_DISABLE_AUTO_FIRST_CANDIDATE_HIGHTLIGHT)
        )
            type = MSG_FIRSTCAND;

        FcitxMessagesAddMessageAtLast(msgDown, type, "%s", candWord->strWord);

        if (candWord->strExtra && strlen(candWord->strExtra) != 0)
            FcitxMessagesAddMessageAtLast(msgDown, candWord->extraType, "%s", candWord->strExtra);

        FcitxMessagesAddMessageAtLast(msgDown, MSG_OTHER, " ");
    }

    return extraLength;
}
Пример #2
0
Файл: ui.c Проект: pkg-ime/fcitx
FCITX_EXPORT_API
int FcitxUINewMessageToOldStyleMessage(FcitxInstance* instance, FcitxMessages* msgUp, FcitxMessages* msgDown)
{
    int i = 0;
    FcitxInputState* input = instance->input;
    int extraLength = input->iCursorPos;
    FcitxMessagesSetMessageCount(msgUp, 0);
    FcitxMessagesSetMessageCount(msgDown, 0);

    for (i = 0; i < FcitxMessagesGetMessageCount(input->msgAuxUp) ; i ++) {
        FcitxMessagesAddMessageAtLast(msgUp, FcitxMessagesGetMessageType(input->msgAuxUp, i), "%s", FcitxMessagesGetMessageString(input->msgAuxUp, i));
        extraLength += strlen(FcitxMessagesGetMessageString(input->msgAuxUp, i));
    }

    for (i = 0; i < FcitxMessagesGetMessageCount(input->msgPreedit) ; i ++)
        FcitxMessagesAddMessageAtLast(msgUp, FcitxMessagesGetMessageType(input->msgPreedit, i), "%s", FcitxMessagesGetMessageString(input->msgPreedit, i));

    for (i = 0; i < FcitxMessagesGetMessageCount(input->msgAuxDown) ; i ++)
        FcitxMessagesAddMessageAtLast(msgDown, FcitxMessagesGetMessageType(input->msgAuxDown, i), "%s", FcitxMessagesGetMessageString(input->msgAuxDown, i));

    FcitxCandidateWord* candWord = NULL;

    for (candWord = FcitxCandidateWordGetCurrentWindow(input->candList), i = 0;
            candWord != NULL;
            candWord = FcitxCandidateWordGetCurrentWindowNext(input->candList, candWord), i ++) {
        char strTemp[3] = { '\0', '\0', '\0' };
        strTemp[0] = FcitxCandidateWordGetChoose(input->candList)[i];

        if (instance->config->bPointAfterNumber)
            strTemp[1] = '.';

        FcitxMessagesAddMessageAtLast(msgDown, MSG_INDEX, "%s", strTemp);

        FcitxMessageType type = candWord->wordType;

        if (i == 0
            && FcitxCandidateWordGetCurrentPage(input->candList) == 0
            && type == MSG_OTHER)
            type = MSG_FIRSTCAND;

        FcitxMessagesAddMessageAtLast(msgDown, type, "%s", candWord->strWord);

        if (candWord->strExtra && strlen(candWord->strExtra) != 0)
            FcitxMessagesAddMessageAtLast(msgDown, candWord->extraType, "%s", candWord->strExtra);

        FcitxMessagesAddMessageAtLast(msgDown, MSG_OTHER, " ");
    }

    return extraLength;
}
Пример #3
0
char* FcitxUIMessagesToCStringForCommit(FcitxMessages* messages)
{
    int length = 0;
    int i = 0;
    int count = FcitxMessagesGetMessageCount(messages);
    char *message_strs[count];
    int msg_count = 0;

    for (i = 0;i < count;i++) {
        if ((FcitxMessagesGetClientMessageType(messages, i) &
             MSG_DONOT_COMMIT_WHEN_UNFOCUS) == 0) {
            char *msg_str = FcitxMessagesGetMessageString(messages, i);
            message_strs[msg_count++] = msg_str;
            length += strlen(msg_str);
        }
    }

    char* str = fcitx_utils_malloc0(sizeof(char) * (length + 1));

    for (i = 0;i < msg_count;i++) {
        strcat(str, message_strs[i]);
    }

    return str;
}
Пример #4
0
Файл: ui.c Проект: pkg-ime/fcitx
FCITX_EXPORT_API
char* FcitxUIMessagesToCString(FcitxMessages* messages)
{
    int length = 0;
    int i = 0;

    for (i = 0; i < FcitxMessagesGetMessageCount(messages) ; i ++)
        length += strlen(FcitxMessagesGetMessageString(messages, i));

    char* str = fcitx_utils_malloc0(sizeof(char) * (length + 1));

    for (i = 0; i < FcitxMessagesGetMessageCount(messages) ; i ++)
        strcat(str, FcitxMessagesGetMessageString(messages, i));

    return str;
}
Пример #5
0
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);
    }
}
Пример #6
0
void FcitxUIUpdateInputWindowReal(FcitxInstance *instance)
{
    FcitxInputState* input = instance->input;
    FcitxInputContext* ic = FcitxInstanceGetCurrentIC(instance);
    FcitxCapacityFlags flags = CAPACITY_NONE;
    if (ic != NULL)
        flags = ic->contextCaps;

    if (flags & CAPACITY_CLIENT_SIDE_UI) {
        FcitxInstanceUpdateClientSideUI(instance, ic);
        return;
    }

    FcitxInstanceUpdatePreedit(instance, ic);

    boolean toshow = false;

    if (FcitxMessagesGetMessageCount(input->msgAuxUp) != 0
        || FcitxMessagesGetMessageCount(input->msgAuxDown) != 0)
        toshow = true;

    if (FcitxCandidateWordGetListSize(input->candList) > 1)
        toshow = true;

    if (FcitxCandidateWordGetListSize(input->candList) == 1
            && (!instance->config->bHideInputWindowWhenOnlyPreeditString
                || !instance->config->bHideInputWindowWhenOnlyOneCandidate))
        toshow = true;

    if (FcitxMessagesGetMessageCount(input->msgPreedit) != 0
            && !((flags & CAPACITY_PREEDIT) && instance->config->bHideInputWindowWhenOnlyPreeditString && instance->profile->bUsePreedit))
        toshow = true;

    if (!toshow) {
        if (UI_FUNC_IS_VALID(CloseInputWindow))
            instance->ui->ui->CloseInputWindow(instance->ui->addonInstance);
    } else
        FcitxUIShowInputWindow(instance);

    FcitxMessagesSetMessageChanged(input->msgAuxUp, false);
    FcitxMessagesSetMessageChanged(input->msgAuxDown, false);
    FcitxMessagesSetMessageChanged(input->msgPreedit, false);
    FcitxMessagesSetMessageChanged(input->msgClientPreedit, false);
}
Пример #7
0
Файл: ui.c Проект: eguopt/fcitx
char* FcitxUIMessagesToCStringForCommit(FcitxMessages* messages)
{
    int length = 0;
    int i = 0;

    for (i = 0; i < FcitxMessagesGetMessageCount(messages) ; i ++) {
        if ((FcitxMessagesGetClientMessageType(messages, i) & MSG_DONOT_COMMIT_WHEN_UNFOCUS) == 0)
            length += strlen(FcitxMessagesGetMessageString(messages, i));
    }

    char* str = fcitx_utils_malloc0(sizeof(char) * (length + 1));

    for (i = 0; i < FcitxMessagesGetMessageCount(messages) ; i ++) {
        if ((FcitxMessagesGetClientMessageType(messages, i) & MSG_DONOT_COMMIT_WHEN_UNFOCUS) == 0)
            strcat(str, FcitxMessagesGetMessageString(messages, i));
    }

    return str;
}
Пример #8
0
FCITX_EXPORT_API
void FcitxUICommitPreedit(FcitxInstance* instance)
{
    if (instance->CurrentIC
        && !instance->config->bDontCommitPreeditWhenUnfocus
        && !(instance->CurrentIC->contextCaps & CAPACITY_CLIENT_UNFOCUS_COMMIT)) {
        FcitxInputState* input = FcitxInstanceGetInputState(instance);
        FcitxMessages* clientPreedit = FcitxInputStateGetClientPreedit(input);

        if (FcitxMessagesGetMessageCount(clientPreedit) > 0) {
            char* str = FcitxUIMessagesToCStringForCommit(clientPreedit);
            if (str[0]) {
                FcitxInstanceCommitString(instance, instance->CurrentIC, str);
            }
            free(str);
        }
        FcitxMessagesSetMessageCount(clientPreedit, 0);
    }
}
Пример #9
0
FCITX_EXPORT_API
void FcitxUICommitPreedit(FcitxInstance* instance)
{
    if (!instance->CurrentIC)
        return;

    boolean callOnClose = false;
    boolean doServerSideCommit = false;
    if (!instance->config->bDontCommitPreeditWhenUnfocus
        && !(instance->CurrentIC->contextCaps & CAPACITY_CLIENT_UNFOCUS_COMMIT)) {
        callOnClose = true;
        doServerSideCommit = true;
    }

    if (instance->CurrentIC->contextCaps & CAPACITY_CLIENT_UNFOCUS_COMMIT) {
        callOnClose = true;
    }

    if (callOnClose) {
        FcitxIM* im = FcitxInstanceGetCurrentIM(instance);
        if (im && im->OnClose) {
            im->OnClose(im->klass, CET_LostFocus);
        }
    }

    if (doServerSideCommit) {
        FcitxInputState* input = FcitxInstanceGetInputState(instance);
        FcitxMessages* clientPreedit = FcitxInputStateGetClientPreedit(input);

        if (FcitxMessagesGetMessageCount(clientPreedit) > 0) {
            char* str = FcitxUIMessagesToCStringForCommit(clientPreedit);
            if (str[0]) {
                FcitxInstanceCommitString(instance, instance->CurrentIC, str);
            }
            free(str);
        }
        FcitxMessagesSetMessageCount(clientPreedit, 0);
    }

}
Пример #10
0
FCITX_EXPORT_API
char* FcitxUIMessagesToCString(FcitxMessages* messages)
{
    int length = 0;
    int i = 0;
    int count = FcitxMessagesGetMessageCount(messages);
    char *message_strs[count];
    int msg_count = 0;

    for (i = 0;i < count;i++) {
        char *msg_str = FcitxMessagesGetMessageString(messages, i);
        message_strs[msg_count++] = msg_str;
        length += strlen(msg_str);
    }

    char *str = fcitx_utils_malloc0(sizeof(char) * (length + 1));

    for (i = 0;i < msg_count;i++) {
        strcat(str, message_strs[i]);
    }

    return str;
}
Пример #11
0
void DrawInputBar(FcitxSkin* sc, InputWindow* inputWindow, int iCursorPos, FcitxMessages * msgup, FcitxMessages *msgdown , unsigned int * iheight, unsigned int *iwidth)
{
    int i;
    char *strUp[MAX_MESSAGE_COUNT];
    char *strDown[MAX_MESSAGE_COUNT];
    int posUpX[MAX_MESSAGE_COUNT], posUpY[MAX_MESSAGE_COUNT];
    int posDownX[MAX_MESSAGE_COUNT], posDownY[MAX_MESSAGE_COUNT];
    int oldHeight = *iheight, oldWidth = *iwidth;
    int newHeight = 0, newWidth = 0;
    int cursor_pos = 0;
    int inputWidth = 0, outputWidth = 0;
    int outputHeight = 0;
    cairo_t *c = NULL;
    FcitxInputState* input = FcitxInstanceGetInputState(inputWindow->owner->owner);
    FcitxInstance* instance = inputWindow->owner->owner;
    FcitxClassicUI* classicui = inputWindow->owner;
    int iChar = iCursorPos;
    int strWidth = 0, strHeight = 0;

    SkinImage *inputimg, *prev, *next;
    inputimg = LoadImage(sc, sc->skinInputBar.backImg, false);
    prev = LoadImage(sc, sc->skinInputBar.backArrow, false);
    next = LoadImage(sc, sc->skinInputBar.forwardArrow, false);

    if (!FcitxMessagesIsMessageChanged(msgup) && !FcitxMessagesIsMessageChanged(msgdown))
        return;

    inputWidth = 0;
    int dpi = sc->skinFont.respectDPI? classicui->dpi : 0;
    FCITX_UNUSED(dpi);
#ifdef _ENABLE_PANGO /* special case which only macro unable to handle */
    SetFontContext(dummy, inputWindow->owner->font, inputWindow->owner->fontSize > 0 ? inputWindow->owner->fontSize : sc->skinFont.fontSize, dpi);
#endif

    int fontHeight = FontHeightWithContext(inputWindow->c_font[0], dpi);
    for (i = 0; i < FcitxMessagesGetMessageCount(msgup) ; i++) {
        char *trans = FcitxInstanceProcessOutputFilter(instance, FcitxMessagesGetMessageString(msgup, i));
        if (trans)
            strUp[i] = trans;
        else
            strUp[i] = FcitxMessagesGetMessageString(msgup, i);
        posUpX[i] = sc->skinInputBar.marginLeft + inputWidth;

        StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], dpi, strUp[i], &strWidth, &strHeight);

        if (sc->skinFont.respectDPI)
            posUpY[i] = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos;
        else
            posUpY[i] = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos - strHeight;
        inputWidth += strWidth;
        if (FcitxInputStateGetShowCursor(input)) {
            int length = strlen(FcitxMessagesGetMessageString(msgup, i));
            if (iChar >= 0) {
                if (iChar < length) {
                    char strTemp[MESSAGE_MAX_LENGTH];
                    char *strGBKT = NULL;
                    strncpy(strTemp, strUp[i], iChar);
                    strTemp[iChar] = '\0';
                    strGBKT = strTemp;
                    StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], dpi, strGBKT, &strWidth, &strHeight);
                    cursor_pos = posUpX[i]
                                 + strWidth + 2;
                }
                iChar -= length;
            }
        }

    }

    if (iChar >= 0)
        cursor_pos = inputWidth + sc->skinInputBar.marginLeft;

    outputWidth = 0;
    outputHeight = 0;
    int currentX = 0;
    int offsetY;
    if (sc->skinFont.respectDPI)
        offsetY = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos + fontHeight + (FcitxMessagesGetMessageCount(msgdown) ? sc->skinInputBar.iOutputPos : 0);
    else
        offsetY = sc->skinInputBar.marginTop + sc->skinInputBar.iOutputPos - fontHeight;
    for (i = 0; i < FcitxMessagesGetMessageCount(msgdown) ; i++) {
        char *trans = FcitxInstanceProcessOutputFilter(instance, FcitxMessagesGetMessageString(msgdown, i));
        if (trans)
            strDown[i] = trans;
        else
            strDown[i] = FcitxMessagesGetMessageString(msgdown, i);

        if (inputWindow->owner->bVerticalList) { /* vertical */
            if (FcitxMessagesGetMessageType(msgdown, i) == MSG_INDEX) {
                if (currentX > outputWidth)
                    outputWidth = currentX;
                if (i != 0) {
                    currentX = 0;
                }
            }
            posDownX[i] = sc->skinInputBar.marginLeft + currentX;
            StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], dpi, strDown[i], &strWidth, &strHeight);
            if (FcitxMessagesGetMessageType(msgdown, i) == MSG_INDEX && i != 0)
                outputHeight += fontHeight + 2;
            currentX += strWidth;
        } else { /* horizontal */
            posDownX[i] = sc->skinInputBar.marginLeft + outputWidth;
            StringSizeWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], dpi, strDown[i], &strWidth, &strHeight);
            outputWidth += strWidth;
        }
        posDownY[i] = offsetY + outputHeight;
    }
    if (inputWindow->owner->bVerticalList && currentX > outputWidth)
        outputWidth = currentX;

    newHeight = offsetY + outputHeight + sc->skinInputBar.marginBottom + (FcitxMessagesGetMessageCount(msgdown) || !sc->skinFont.respectDPI ? fontHeight : 0);

    newWidth = (inputWidth < outputWidth) ? outputWidth : inputWidth;
    newWidth += sc->skinInputBar.marginLeft + sc->skinInputBar.marginRight;

    /* round to ROUND_SIZE in order to decrease resize */
    newWidth = (newWidth / ROUND_SIZE) * ROUND_SIZE + ROUND_SIZE;

    if (inputWindow->owner->bVerticalList) { /* vertical */
        newWidth = (newWidth < INPUT_BAR_VMIN_WIDTH) ? INPUT_BAR_VMIN_WIDTH : newWidth;
    } else {
        newWidth = (newWidth < INPUT_BAR_HMIN_WIDTH) ? INPUT_BAR_HMIN_WIDTH : newWidth;
    }

    *iwidth = newWidth;
    *iheight = newHeight;

    EnlargeCairoSurface(&inputWindow->cs_input_back, newWidth, newHeight);
    if (EnlargeCairoSurface(&inputWindow->cs_input_bar, newWidth, newHeight)) {
        LoadInputMessage(&classicui->skin, classicui->inputWindow, classicui->font);
    }

    if (oldHeight != newHeight || oldWidth != newWidth) {
        c = cairo_create(inputWindow->cs_input_back);
        DrawResizableBackground(c, inputimg->image, newHeight, newWidth,
                                sc->skinInputBar.marginLeft,
                                sc->skinInputBar.marginTop,
                                sc->skinInputBar.marginRight,
                                sc->skinInputBar.marginBottom,
                                sc->skinInputBar.fillV,
                                sc->skinInputBar.fillH
                               );
        cairo_destroy(c);
    }

    c = cairo_create(inputWindow->cs_input_bar);
    cairo_set_source_surface(c, inputWindow->cs_input_back, 0, 0);
    cairo_save(c);
    cairo_rectangle(c, 0, 0, newWidth, newHeight);
    cairo_set_operator(c, CAIRO_OPERATOR_SOURCE);
    cairo_clip(c);
    cairo_paint(c);
    cairo_restore(c);

    cairo_set_operator(c, CAIRO_OPERATOR_OVER);


    if (FcitxInputStateGetShowCursor(input)) {
        //画向前向后箭头
        if (prev && next) {
            cairo_set_source_surface(inputWindow->c_back, prev->image,
                                     newWidth - sc->skinInputBar.iBackArrowX ,
                                     sc->skinInputBar.iBackArrowY);
            if (FcitxCandidateWordHasPrev(FcitxInputStateGetCandidateList(input)))
                cairo_paint(inputWindow->c_back);
            else
                cairo_paint_with_alpha(inputWindow->c_back, 0.5);

            //画向前箭头
            cairo_set_source_surface(inputWindow->c_back, next->image,
                                     newWidth - sc->skinInputBar.iForwardArrowX ,
                                     sc->skinInputBar.iForwardArrowY);
            if (FcitxCandidateWordHasNext(FcitxInputStateGetCandidateList(input)))
                cairo_paint(inputWindow->c_back);
            else
                cairo_paint_with_alpha(inputWindow->c_back, 0.5);
        }
    }

    for (i = 0; i < FcitxMessagesGetMessageCount(msgup) ; i++) {
        OutputStringWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgup, i)], dpi, strUp[i], posUpX[i], posUpY[i]);
        if (strUp[i] != FcitxMessagesGetMessageString(msgup, i))
            free(strUp[i]);
    }

    for (i = 0; i < FcitxMessagesGetMessageCount(msgdown) ; i++) {
        OutputStringWithContext(inputWindow->c_font[FcitxMessagesGetMessageType(msgdown, i)], dpi, strDown[i], posDownX[i], posDownY[i]);
        if (strDown[i] != FcitxMessagesGetMessageString(msgdown, i))
            free(strDown[i]);
    }

    int cursorY1, cursorY2;
    if (sc->skinFont.respectDPI) {
        cursorY1 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos;
        cursorY2 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos + fontHeight;
    }
    else {
        cursorY1 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos - fontHeight - 4;
        cursorY2 = sc->skinInputBar.marginTop + sc->skinInputBar.iInputPos;
    }

    //画光标
    if (FcitxInputStateGetShowCursor(input)) {
        cairo_move_to(inputWindow->c_cursor, cursor_pos, cursorY1);
        cairo_line_to(inputWindow->c_cursor, cursor_pos, cursorY2);
        cairo_stroke(inputWindow->c_cursor);
    }

    ResetFontContext();

    cairo_destroy(c);
    FcitxMessagesSetMessageChanged(msgup, false);
    FcitxMessagesSetMessageChanged(msgdown, false);
}
Пример #12
0
void InputWindowCalculateContentSize(FcitxXlibWindow* window, unsigned int* width, unsigned int* height)
{
    InputWindow* inputWindow = (InputWindow*) window;
    FcitxInstance* instance = window->owner->owner;
    FcitxInputState* input = FcitxInstanceGetInputState(instance);
    FcitxCandidateWordList* candList = FcitxInputStateGetCandidateList(input);
    FcitxCandidateLayoutHint layout = FcitxCandidateWordGetLayoutHint(candList);
    FcitxClassicUI* classicui = window->owner;

    inputWindow->cursorPos = FcitxUINewMessageToOldStyleMessage(instance, inputWindow->msgUp, inputWindow->msgDown);

    boolean vertical = window->owner->bVerticalList;
    if (layout == CLH_Vertical)
        vertical = true;
    else if (layout == CLH_Horizontal)
        vertical = false;

    inputWindow->vertical = vertical;

    /* begin evalulation */
    FcitxMessages* msgup = inputWindow->msgUp;
    FcitxMessages* msgdown = inputWindow->msgDown;
    FcitxSkin* sc = &classicui->skin;

    int i;
    FcitxRect* candRect = inputWindow->candRect;
    char **strUp = inputWindow->strUp;
    char **strDown = inputWindow->strDown;
    int *posUpX = inputWindow->posUpX, *posUpY = inputWindow->posUpY;
    int *posDownX = inputWindow->posDownX, *posDownY = inputWindow->posDownY;
    int newHeight = 0, newWidth = 0;
    int pixelCursorPos = 0;
    int inputWidth = 0, outputWidth = 0;
    int outputHeight = 0;
    int iChar = inputWindow->cursorPos;
    int strWidth = 0, strHeight = 0;

    inputWidth = 0;
    int dpi = sc->skinFont.respectDPI? classicui->dpi : 0;
    FCITX_UNUSED(dpi);

    FcitxCairoTextContext* ctc = FcitxCairoTextContextCreate(NULL);
    FcitxCairoTextContextSet(ctc, window->owner->font, window->owner->fontSize > 0 ? window->owner->fontSize : sc->skinFont.fontSize, dpi);

    int fontHeight = FcitxCairoTextContextFontHeight(ctc);
    inputWindow->fontHeight = fontHeight;
    for (i = 0; i < FcitxMessagesGetMessageCount(msgup) ; i++) {
        char *trans = FcitxInstanceProcessOutputFilter(instance, FcitxMessagesGetMessageString(msgup, i));
        if (trans)
            strUp[i] = trans;
        else
            strUp[i] = FcitxMessagesGetMessageString(msgup, i);
        posUpX[i] = inputWidth;

        FcitxCairoTextContextStringSize(ctc, strUp[i], &strWidth, &strHeight);

        if (sc->skinFont.respectDPI)
            posUpY[i] = sc->skinInputBar.iInputPos + fontHeight - strHeight;
        else
            posUpY[i] = sc->skinInputBar.iInputPos - strHeight;
        inputWidth += strWidth;
        if (FcitxInputStateGetShowCursor(input)) {
            int length = strlen(FcitxMessagesGetMessageString(msgup, i));
            if (iChar >= 0) {
                if (iChar < length) {
                    char strTemp[MESSAGE_MAX_LENGTH];
                    char *strGBKT = NULL;
                    strncpy(strTemp, strUp[i], iChar);
                    strTemp[iChar] = '\0';
                    strGBKT = strTemp;
                    FcitxCairoTextContextStringSize(ctc, strGBKT, &strWidth, &strHeight);
                    // if the cursor is between two part, add extra pixel for pretty output
                    pixelCursorPos = posUpX[i] + strWidth;
                }
                iChar -= length;
            }
        }

    }

    if (iChar >= 0)
        pixelCursorPos = inputWidth;

    inputWindow->pixelCursorPos = pixelCursorPos;

    outputWidth = 0;
    outputHeight = 0;
    int currentX = 0;
    int offsetY;
    if (sc->skinFont.respectDPI)
        offsetY = (FcitxMessagesGetMessageCount(msgup) ? (sc->skinInputBar.iInputPos + fontHeight) : 0)
                 + (FcitxMessagesGetMessageCount(msgdown) ? sc->skinInputBar.iOutputPos : 0);
    else
        offsetY = sc->skinInputBar.iOutputPos - fontHeight;
    int candidateIndex = -1;
    int lastRightBottomX = 0, lastRightBottomY = 0;
    for (i = 0; i < FcitxMessagesGetMessageCount(msgdown) ; i++) {
        char *trans = FcitxInstanceProcessOutputFilter(instance, FcitxMessagesGetMessageString(msgdown, i));
        if (trans)
            strDown[i] = trans;
        else
            strDown[i] = FcitxMessagesGetMessageString(msgdown, i);

        if (vertical) { /* vertical */
            if (FcitxMessagesGetMessageType(msgdown, i) == MSG_INDEX) {
                if (currentX > outputWidth)
                    outputWidth = currentX;
                if (i != 0) {
                    currentX = 0;
                }
            }
            posDownX[i] = currentX;
            FcitxCairoTextContextStringSize(ctc, strDown[i], &strWidth, &strHeight);
            if (FcitxMessagesGetMessageType(msgdown, i) == MSG_INDEX && i != 0)
                outputHeight += fontHeight + 2;
            currentX += strWidth;
        } else { /* horizontal */
            posDownX[i] = outputWidth;
            FcitxCairoTextContextStringSize(ctc, strDown[i], &strWidth, &strHeight);
            outputWidth += strWidth;
        }
        posDownY[i] = offsetY + outputHeight;

        if (FcitxMessagesGetMessageType(msgdown, i) == MSG_INDEX) {
            candidateIndex ++;

            if (candidateIndex > 0 && candidateIndex - 1 < 10) {
                candRect[candidateIndex - 1].x2 = lastRightBottomX;
                candRect[candidateIndex - 1].y2 = lastRightBottomY;
            }

            if (candidateIndex < 10) {
                candRect[candidateIndex].x1 = posDownX[i];
                candRect[candidateIndex].y1 = posDownY[i];
            }
        }

        lastRightBottomX = posDownX[i] + strWidth;
        lastRightBottomY = posDownY[i] + strHeight;
    }

    if (candidateIndex >= 0 && candidateIndex < 10) {
        candRect[candidateIndex].x2 = lastRightBottomX;
        candRect[candidateIndex].y2 = lastRightBottomY;
    }

    if (vertical && currentX > outputWidth)
        outputWidth = currentX;

    newHeight = offsetY + outputHeight + (FcitxMessagesGetMessageCount(msgdown) || !sc->skinFont.respectDPI ? fontHeight : 0);

    newWidth = (inputWidth < outputWidth) ? outputWidth : inputWidth;

    /* round to ROUND_SIZE in order to decrease resize */
    newWidth = (newWidth / ROUND_SIZE) * ROUND_SIZE + ROUND_SIZE;

    if (vertical) { /* vertical */
        newWidth = (newWidth < INPUT_BAR_VMIN_WIDTH) ? INPUT_BAR_VMIN_WIDTH : newWidth;
    } else {
        newWidth = (newWidth < INPUT_BAR_HMIN_WIDTH) ? INPUT_BAR_HMIN_WIDTH : newWidth;
    }

    FcitxCairoTextContextFree(ctc);

    *width = newWidth;
    *height = newHeight;
}
Пример #13
0
void InputWindowPaint(FcitxXlibWindow* window, cairo_t* c)
{
    InputWindow* inputWindow = (InputWindow*) window;
    FcitxClassicUI* classicui = window->owner;
    FcitxInstance* instance = classicui->owner;
    FcitxInputState* input = FcitxInstanceGetInputState(instance);
    FcitxCandidateWordList* candList = FcitxInputStateGetCandidateList(input);
    FcitxSkin* sc = &window->owner->skin;

    FcitxMessages* msgup = inputWindow->msgUp;
    FcitxMessages* msgdown = inputWindow->msgDown;
    char **strUp = inputWindow->strUp;
    char **strDown = inputWindow->strDown;
    int *posUpX = inputWindow->posUpX, *posUpY = inputWindow->posUpY;
    int *posDownX = inputWindow->posDownX, *posDownY = inputWindow->posDownY;

    cairo_save(c);
    cairo_set_operator(c, CAIRO_OPERATOR_OVER);

    SkinImage* prev = LoadImage(sc, sc->skinInputBar.backArrow, false);
    SkinImage* next = LoadImage(sc, sc->skinInputBar.forwardArrow, false);

    inputWindow->prevRect.x1 = inputWindow->prevRect.y1 = inputWindow->prevRect.x2 = inputWindow->prevRect.y2 = 0;
    inputWindow->nextRect.x1 = inputWindow->nextRect.y1 = inputWindow->nextRect.x2 = inputWindow->nextRect.y2 = 0;

    if (FcitxCandidateWordHasPrev(candList)
        || FcitxCandidateWordHasNext(candList)
    ) {
        if (prev && next) {
            int x, y;
            x = window->contentWidth - sc->skinInputBar.iBackArrowX + window->background->marginRight - window->background->marginLeft;
            y = sc->skinInputBar.iBackArrowY - window->background->marginTop;
            cairo_set_source_surface(c, prev->image, x, y);
            if (FcitxCandidateWordHasPrev(candList)) {
                inputWindow->prevRect.x1 = x;
                inputWindow->prevRect.y1 = y;
                inputWindow->prevRect.x2 = x + cairo_image_surface_get_width(prev->image);
                inputWindow->prevRect.y2 = y + cairo_image_surface_get_height(prev->image);

                if (inputWindow->highlight == PREVNEXT_HIGHLIGHT(true)) {
                    cairo_paint_with_alpha(c, 0.7);
                } else {
                    cairo_paint(c);
                }
            }
            else {
                cairo_paint_with_alpha(c, 0.3);
            }

            x = window->contentWidth - sc->skinInputBar.iForwardArrowX + window->background->marginRight - window->background->marginLeft;
            y = sc->skinInputBar.iForwardArrowY - window->background->marginTop;
            cairo_set_source_surface(c, next->image, x, y);
            if (FcitxCandidateWordHasNext(candList)) {
                inputWindow->nextRect.x1 = x;
                inputWindow->nextRect.y1 = y;
                inputWindow->nextRect.x2 = x + cairo_image_surface_get_width(prev->image);
                inputWindow->nextRect.y2 = y + cairo_image_surface_get_height(prev->image);
                if (inputWindow->highlight == PREVNEXT_HIGHLIGHT(false)) {
                    cairo_paint_with_alpha(c, 0.7);
                } else {
                    cairo_paint(c);
                }
            } else {
                cairo_paint_with_alpha(c, 0.3);
            }
        }
    }
    cairo_restore(c);
    cairo_save(c);

    /* draw text */
    FcitxCairoTextContext* ctc = FcitxCairoTextContextCreate(c);
    int dpi = sc->skinFont.respectDPI? classicui->dpi : 0;
    FcitxCairoTextContextSet(ctc, window->owner->font, window->owner->fontSize > 0 ? window->owner->fontSize : sc->skinFont.fontSize, dpi);

    int i;
    for (i = 0; i < FcitxMessagesGetMessageCount(msgup) ; i++) {
        FcitxCairoTextContextOutputString(ctc, strUp[i], posUpX[i], posUpY[i], &sc->skinFont.fontColor[FcitxMessagesGetMessageType(msgup, i) % 7]);
        if (strUp[i] != FcitxMessagesGetMessageString(msgup, i))
            free(strUp[i]);
    }

    int candidateIndex = -1;
    for (i = 0; i < FcitxMessagesGetMessageCount(msgdown) ; i++) {

        if (FcitxMessagesGetMessageType(msgdown, i) == MSG_INDEX) {
            candidateIndex ++;
        }

        FcitxConfigColor color = sc->skinFont.fontColor[FcitxMessagesGetMessageType(msgdown, i) % 7];
        double alpha = 1.0;
        if (CANDIDATE_HIGHLIGHT(candidateIndex) == inputWindow->highlight) {
            /* cal highlight color */
            color.r = (color.r + 0.5) / 2;
            color.g = (color.g + 0.5) / 2;
            color.b = (color.b + 0.5) / 2;
            alpha = 0.8;
        }
        cairo_set_source_rgba(c, color.r, color.g, color.b, alpha);

        FcitxCairoTextContextOutputString(ctc, strDown[i], posDownX[i], posDownY[i], NULL);
        if (strDown[i] != FcitxMessagesGetMessageString(msgdown, i))
            free(strDown[i]);
    }
    FcitxCairoTextContextFree(ctc);

    cairo_restore(c);

    // draw cursor
    if (FcitxMessagesGetMessageCount(msgup) && FcitxInputStateGetShowCursor(input)) {
        cairo_save(c);
        int cursorY1, cursorY2;
        if (sc->skinFont.respectDPI) {
            cursorY1 = sc->skinInputBar.iInputPos;
            cursorY2 = sc->skinInputBar.iInputPos + inputWindow->fontHeight;
        }
        else {
            cursorY1 = sc->skinInputBar.iInputPos - inputWindow->fontHeight;
            cursorY2 = sc->skinInputBar.iInputPos;
        }

        fcitx_cairo_set_color(c, &sc->skinInputBar.cursorColor);
        cairo_set_line_width(c, 1);
        cairo_move_to(c, inputWindow->pixelCursorPos + 0.5, cursorY1);
        cairo_line_to(c, inputWindow->pixelCursorPos + 0.5, cursorY2);
        cairo_stroke(c);

        cairo_restore(c);
    }

    FcitxMessagesSetMessageChanged(msgup, false);
    FcitxMessagesSetMessageChanged(msgdown, false);
}
Пример #14
0
void
XimPreeditCallbackDraw(FcitxXimFrontend* xim, FcitxXimIC* ic, const char* preedit_string, int cursorPos)
{
    XTextProperty tp;

    uint i, len;

    if (preedit_string == NULL)
        return;

    len = fcitx_utf8_strlen(preedit_string);

    if (len + 1 > xim->feedback_len) {
        xim->feedback_len = len + 1;
        if (xim->feedback) {
            xim->feedback = realloc(xim->feedback, sizeof(XIMFeedback) * xim->feedback_len);
        } else {
            xim->feedback = fcitx_utils_malloc0(sizeof(XIMFeedback) * xim->feedback_len);
        }
    }

    FcitxInputState* input = FcitxInstanceGetInputState(xim->owner);
    FcitxMessages* clientPreedit = FcitxInputStateGetClientPreedit(input);
    int offset = 0;
    for (i = 0; i < FcitxMessagesGetMessageCount(clientPreedit) ; i ++) {
        int type = FcitxMessagesGetClientMessageType(clientPreedit, i);
        char* str = FcitxMessagesGetMessageString(clientPreedit, i);
        int j = 0;
        XIMFeedback fb = 0;
        if ((type & MSG_NOUNDERLINE) == 0)
            fb |= XIMUnderline;
        if (type & MSG_HIGHLIGHT)
            fb |= XIMReverse;
        for (; j < fcitx_utf8_strlen(str); j++) {
            xim->feedback[offset] = fb;
            offset ++;
        }
    }
    xim->feedback[len] = 0;

    IMPreeditCBStruct* pcb = fcitx_utils_new(IMPreeditCBStruct);
    XIMText* text = fcitx_utils_new(XIMText);
    pcb->major_code = XIM_PREEDIT_DRAW;
    pcb->connect_id = ic->connect_id;
    pcb->icid = ic->id;

    pcb->todo.draw.caret = fcitx_utf8_strnlen(preedit_string, cursorPos);
    pcb->todo.draw.chg_first = 0;
    pcb->todo.draw.chg_length = ic->onspot_preedit_length;
    pcb->todo.draw.text = text;

    text->feedback = xim->feedback;

    Xutf8TextListToTextProperty(xim->display,
                                (char **)&preedit_string,
                                1, XCompoundTextStyle, &tp);
    text->encoding_is_wchar = 0;
    text->length = strlen((char*)tp.value);
    text->string.multi_byte = (char*)tp.value;
    XimPendingCall(xim, XCT_CALLCALLBACK, (XPointer) pcb);
    ic->onspot_preedit_length = len;
}