diff --git a/RimeWithWeasel/RimeWithWeasel.cpp b/RimeWithWeasel/RimeWithWeasel.cpp index b4991328a..8d19cf764 100644 --- a/RimeWithWeasel/RimeWithWeasel.cpp +++ b/RimeWithWeasel/RimeWithWeasel.cpp @@ -7,6 +7,19 @@ #include #include #include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#pragma comment(lib, "capnp-x64.lib") +#pragma comment(lib, "kj-x64.lib") +#else +#pragma comment(lib, "capnp.lib") +#pragma comment(lib, "kj.lib") +#endif #define TRANSPARENT_COLOR 0x00000000 #define ARGB2ABGR(value) ((value & 0xff000000) | ((value & 0x000000ff) << 16) | (value & 0x0000ff00) | ((value & 0x00ff0000) >> 16)) @@ -26,6 +39,7 @@ typedef enum #define TRIMHEAD_REGEX std::regex("0x", std::regex::icase) #endif using namespace weasel; +using namespace std; int expand_ibus_modifier(int m) { @@ -372,7 +386,7 @@ bool RimeWithWeaselHandler::_IsDeployerRunning() void RimeWithWeaselHandler::_UpdateUI(UINT session_id) { - Status weasel_status; + weasel::Status weasel_status; Context weasel_context; bool is_tsf = _IsSessionTSF(session_id); @@ -577,15 +591,395 @@ inline std::string _GetLabelText(const std::vector &labels, int id, const return wstring_to_string(std::wstring(buffer), CP_UTF8); } +void RimeWithWeaselHandler::_prepare(UINT session_id) +{ + capnp::MallocMessageBuilder msg; + WeaselRespondData::Builder rspbdr = msg.initRoot(); + // commit + RIME_STRUCT(RimeCommit, commit); + if (RimeGetCommit(session_id, &commit)) + { + if (!commit.text) { + auto _commit = rspbdr.initCommit(); + _commit.setText(commit.text); + } + RimeFreeCommit(&commit); + } + + // status + bool is_composing = false; + RIME_STRUCT(RimeStatus, status); + if (RimeGetStatus(session_id, &status)) + { + is_composing = !!status.is_composing; + auto _sta = rspbdr.initStatus(); + _sta.setIsAsciiMode(status.is_ascii_mode); + _sta.setIsAsciiPunct(status.is_ascii_punct); + _sta.setIsComposing(status.is_composing); + _sta.setIsDisabled(status.is_disabled); + _sta.setIsFullShape(status.is_full_shape); + _sta.setIsSimplified(status.is_simplified); + _sta.setIsTraditional(status.is_traditional); + _sta.setSchemaId(status.schema_id); + _sta.setSchemaName(status.schema_name); + RimeFreeStatus(&status); + } + // context + RIME_STRUCT(RimeContext, ctx); + if (RimeGetContext(session_id, &ctx)) + { + auto _ctx = rspbdr.initContext(); + const auto getlabel = [ctx, this](int i) + { + auto format = wstring_to_string(m_ui->style().label_text_format, CP_UTF8).c_str(); + char buffer[128]; + if (RIME_STRUCT_HAS_MEMBER(ctx, ctx.select_labels) && ctx.select_labels) + { + sprintf_s<128>(buffer, format, ctx.select_labels[i]); + return std::string(buffer); + } + else if (ctx.menu.select_keys) + { + sprintf_s<128>(buffer, format, wstring_to_string(std::wstring(1, ctx.menu.select_keys[i]), CP_UTF8).c_str()); + return std::string(buffer); + } + else + return std::to_string((i + 1) % 10); + }; + if(is_composing) { + auto _preedit = _ctx.initPreedit(); + switch(m_ui->style().preedit_type) { + case UIStyle::PREVIEW: { + if(ctx.commit_text_preview != NULL) { + std::string first = ctx.commit_text_preview; + _preedit.setStr(first); + _preedit.setStart(utf8towcslen(first.c_str(), 0)); + _preedit.setEnd(utf8towcslen(first.c_str(), first.size())); + _preedit.setCursor(utf8towcslen(first.c_str(), first.size())); + } + break; + } + case UIStyle::COMPOSITION: { + _preedit.setStr(ctx.composition.preedit); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start)); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end)); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.cursor_pos)); + break; + } + case UIStyle::PREVIEW_ALL: { + std::string preedit_ = ctx.composition.preedit + std::string(" ["); + for(auto i=0; i < ctx.menu.num_candidates; i++) { + std::string label = m_ui->style().label_font_point > 0 ? getlabel(i) : ""; + std::string comment = m_ui->style().comment_font_point > 0 ? ctx.menu.candidates->comment : ""; + std::string mark_text = m_ui->style().mark_text.empty() ? "*" : wstring_to_string(m_ui->style().mark_text, CP_UTF8); + std::string prefix = (i != ctx.menu.highlighted_candidate_index) ? "" : mark_text; + preedit_ += " " + prefix + label + std::string(ctx.menu.candidates[i].text) + " " + comment; + } + preedit_.append(" ]"); + _preedit.setStr(preedit_); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start)); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end)); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.cursor_pos)); + break; + } + } + } + if(ctx.menu.num_candidates) { + auto cinfo = _ctx.initCandidateInfo(); + cinfo.setCurrentPage(ctx.menu.page_no); + cinfo.setHighlighted(ctx.menu.highlighted_candidate_index); + cinfo.setIsLastPage(ctx.menu.is_last_page); + auto labels = cinfo.initLabels(ctx.menu.num_candidates); + auto candies = cinfo.initCandies(ctx.menu.num_candidates); + auto comments = cinfo.initComments(ctx.menu.num_candidates); + for(auto i = 0; i < ctx.menu.num_candidates; i++) { + labels.set(i, getlabel(i)); + candies.set(i, ctx.menu.candidates->text); + comments.set(i, ctx.menu.candidates->comment); + } + } + RimeFreeContext(&ctx); + } + + // style + bool has_synced = RimeGetOption(session_id, "__synced"); + if (!has_synced) { + auto _style = rspbdr.initStyle(); + weasel::UIStyle& style(m_ui->style()); + _style.setAntialiasMode(static_cast(style.antialias_mode)); + _style.setAlgnType(static_cast(style.align_type)); + _style.setPreeditType(static_cast(style.preedit_type)); + _style.setLayoutType(static_cast(style.layout_type)); + _style.setVerticalTextLeftToRight(style.vertical_text_left_to_right); + _style.setVerticalTextWithWrap(style.vertical_text_with_wrap); + _style.setPagingOnScroll(style.paging_on_scroll); + _style.setFontFace(wstring_to_string(style.font_face, CP_UTF8)); + _style.setLabelFontFace(wstring_to_string(style.label_font_face, CP_UTF8)); + _style.setCommentFontFace(wstring_to_string(style.comment_font_face, CP_UTF8)); + _style.setMouseHoverMs(style.mouse_hover_ms); + _style.setFontPoint(style.font_point); + _style.setLabelFontPoint(style.label_font_point); + _style.setCommentFontPoint(style.comment_font_point); + _style.setInlinePreedit(style.inline_preedit); + _style.setDisplayTrayIcon(style.display_tray_icon); + _style.setAsciiTipFollowCursor(style.ascii_tip_follow_cursor); + _style.setCurrentZhungIcon(wstring_to_string(style.current_zhung_icon, CP_UTF8)); + _style.setCurrentAsciiIcon(wstring_to_string(style.current_ascii_icon, CP_UTF8)); + _style.setCurrentHalfIcon(wstring_to_string(style.current_half_icon, CP_UTF8)); + _style.setCurrentFullIcon(wstring_to_string(style.current_full_icon, CP_UTF8)); + _style.setEnhancedPosition(style.enhanced_position); + _style.setLabelTextFormat(wstring_to_string(style.label_text_format, CP_UTF8)); + _style.setMarkText(wstring_to_string(style.mark_text, CP_UTF8)); + _style.setMinWidth(style.min_width); + _style.setMaxWidth(style.max_width); + _style.setMinHeight(style.min_height); + _style.setMaxHeight(style.max_height); + _style.setBorder(style.border); + _style.setMarginX(style.margin_x); + _style.setMarginY(style.margin_y); + _style.setSpacing(style.spacing); + _style.setCandidateSpacing(style.candidate_spacing); + _style.setHiliteSpacing(style.hilite_spacing); + _style.setHilitePaddingX(style.hilite_padding_x); + _style.setHilitePaddingY(style.hilite_padding_y); + _style.setRoundCorner(style.round_corner); + _style.setRoundCornerEx(style.round_corner_ex); + _style.setShadowRadius(style.shadow_radius); + _style.setShadowOffsetX(style.shadow_offset_x); + _style.setShadowOffsetY(style.shadow_offset_y); + _style.setVerticalAutoReverse(style.vertical_auto_reverse); + _style.setTextColor(style.text_color); + _style.setCandidateTextColor(style.candidate_text_color); + _style.setCandidateBackColor(style.candidate_back_color); + _style.setCandidateShadowColor(style.candidate_shadow_color); + _style.setCandidateBorderColor(style.candidate_border_color); + _style.setLabelTextColor(style.label_text_color); + _style.setCommentTextColor(style.comment_text_color); + _style.setBackColor(style.back_color); + _style.setShadowColor(style.shadow_color); + _style.setBorderColor(style.border_color); + _style.setHilitedTextColor(style.hilited_text_color); + _style.setHilitedBackColor(style.hilited_back_color); + _style.setHilitedShadowColor(style.hilited_shadow_color); + _style.setHilitedCandidateTextColor(style.hilited_candidate_text_color); + _style.setHilitedCandidateBackColor(style.hilited_candidate_back_color); + _style.setHilitedCandidateShadowColor(style.hilited_candidate_shadow_color); + _style.setHilitedCandidateBorderColor(style.hilited_candidate_border_color); + _style.setHilitedLabelTextColor(style.hilited_label_text_color); + _style.setHilitedCommentTextColor(style.hilited_comment_text_color); + _style.setHilitedMarkColor(style.hilited_mark_color); + _style.setPrevpageColor(style.prevpage_color); + _style.setNextpageColor(style.nextpage_color); + _style.setClientCaps(style.client_caps); + } + + rspbdr.setInlinePreedit(m_ui->style().inline_preedit); + + auto m = capnp::messageToFlatArray(msg); + auto encoded_array_ptr = m.asChars(); + auto encoded_char_array = encoded_array_ptr.begin(); + auto size = encoded_array_ptr.size(); +} + bool RimeWithWeaselHandler::_Respond(UINT session_id, EatLine eat) { std::set actions; std::list messages; - + _prepare(session_id); // load App inline_preedit setting if app_name changed _LoadAppInlinePreeditSet(session_id); // extract information +#if 0 + capnp::MallocMessageBuilder msg; + WeaselRespondData::Builder rspbdr = msg.initRoot(); + // commit + RIME_STRUCT(RimeCommit, commit); + if (RimeGetCommit(session_id, &commit)) + { + if (!commit.text) { + auto _commit = rspbdr.initCommit(); + _commit.setText(commit.text); + } + RimeFreeCommit(&commit); + } + + // status + bool is_composing = false; + RIME_STRUCT(RimeStatus, status); + if (RimeGetStatus(session_id, &status)) + { + is_composing = !!status.is_composing; + auto _sta = rspbdr.initStatus(); + _sta.setIsAsciiMode(status.is_ascii_mode); + _sta.setIsAsciiPunct(status.is_ascii_punct); + _sta.setIsComposing(status.is_composing); + _sta.setIsDisabled(status.is_disabled); + _sta.setIsFullShape(status.is_full_shape); + _sta.setIsSimplified(status.is_simplified); + _sta.setIsTraditional(status.is_traditional); + _sta.setSchemaId(status.schema_id); + _sta.setSchemaName(status.schema_name); + RimeFreeStatus(&status); + } + // context + RIME_STRUCT(RimeContext, ctx); + if (RimeGetContext(session_id, &ctx)) + { + auto _ctx = rspbdr.initContext(); + const auto getlabel = [ctx, this](int i) + { + auto format = wstring_to_string(m_ui->style().label_text_format, CP_UTF8).c_str(); + char buffer[128]; + if (RIME_STRUCT_HAS_MEMBER(ctx, ctx.select_labels) && ctx.select_labels) + { + sprintf_s<128>(buffer, format, ctx.select_labels[i]); + return std::string(buffer); + } + else if (ctx.menu.select_keys) + { + sprintf_s<128>(buffer, format, wstring_to_string(std::wstring(1, ctx.menu.select_keys[i]), CP_UTF8).c_str()); + return std::string(buffer); + } + else + return std::to_string((i + 1) % 10); + }; + if(is_composing) { + auto _preedit = _ctx.initPreedit(); + switch(m_ui->style().preedit_type) { + case UIStyle::PREVIEW: { + if(ctx.commit_text_preview != NULL) { + std::string first = ctx.commit_text_preview; + _preedit.setStr(first); + _preedit.setStart(utf8towcslen(first.c_str(), 0)); + _preedit.setEnd(utf8towcslen(first.c_str(), first.size())); + _preedit.setCursor(utf8towcslen(first.c_str(), first.size())); + } + break; + } + case UIStyle::COMPOSITION: { + _preedit.setStr(ctx.composition.preedit); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start)); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end)); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.cursor_pos)); + break; + } + case UIStyle::PREVIEW_ALL: { + std::string preedit_ = ctx.composition.preedit + std::string(" ["); + for(auto i=0; i < ctx.menu.num_candidates; i++) { + std::string label = m_ui->style().label_font_point > 0 ? getlabel(i) : ""; + std::string comment = m_ui->style().comment_font_point > 0 ? ctx.menu.candidates->comment : ""; + std::string mark_text = m_ui->style().mark_text.empty() ? "*" : wstring_to_string(m_ui->style().mark_text, CP_UTF8); + std::string prefix = (i != ctx.menu.highlighted_candidate_index) ? "" : mark_text; + preedit_ += " " + prefix + label + std::string(ctx.menu.candidates[i].text) + " " + comment; + } + preedit_.append(" ]"); + _preedit.setStr(preedit_); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start)); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end)); + _preedit.setStart(utf8towcslen(ctx.composition.preedit, ctx.composition.cursor_pos)); + break; + } + } + } + if(ctx.menu.num_candidates) { + auto cinfo = _ctx.initCandidateInfo(); + cinfo.setCurrentPage(ctx.menu.page_no); + cinfo.setHighlighted(ctx.menu.highlighted_candidate_index); + cinfo.setIsLastPage(ctx.menu.is_last_page); + auto labels = cinfo.initLabels(ctx.menu.num_candidates); + auto candies = cinfo.initCandies(ctx.menu.num_candidates); + auto comments = cinfo.initComments(ctx.menu.num_candidates); + for(auto i = 0; i < ctx.menu.num_candidates; i++) { + labels.set(i, getlabel(i)); + candies.set(i, ctx.menu.candidates->text); + comments.set(i, ctx.menu.candidates->comment); + } + } + RimeFreeContext(&ctx); + } + + // style + bool has_synced = RimeGetOption(session_id, "__synced"); + if (!has_synced) { + auto _style = rspbdr.initStyle(); + weasel::UIStyle& style(m_ui->style()); + _style.setAntialiasMode(static_cast(style.antialias_mode)); + _style.setAlgnType(static_cast(style.align_type)); + _style.setPreeditType(static_cast(style.preedit_type)); + _style.setLayoutType(static_cast(style.layout_type)); + _style.setVerticalTextLeftToRight(style.vertical_text_left_to_right); + _style.setVerticalTextWithWrap(style.vertical_text_with_wrap); + _style.setPagingOnScroll(style.paging_on_scroll); + _style.setFontFace(wstring_to_string(style.font_face, CP_UTF8)); + _style.setLabelFontFace(wstring_to_string(style.label_font_face, CP_UTF8)); + _style.setCommentFontFace(wstring_to_string(style.comment_font_face, CP_UTF8)); + _style.setMouseHoverMs(style.mouse_hover_ms); + _style.setFontPoint(style.font_point); + _style.setLabelFontPoint(style.label_font_point); + _style.setCommentFontPoint(style.comment_font_point); + _style.setInlinePreedit(style.inline_preedit); + _style.setDisplayTrayIcon(style.display_tray_icon); + _style.setAsciiTipFollowCursor(style.ascii_tip_follow_cursor); + _style.setCurrentZhungIcon(wstring_to_string(style.current_zhung_icon, CP_UTF8)); + _style.setCurrentAsciiIcon(wstring_to_string(style.current_ascii_icon, CP_UTF8)); + _style.setCurrentHalfIcon(wstring_to_string(style.current_half_icon, CP_UTF8)); + _style.setCurrentFullIcon(wstring_to_string(style.current_full_icon, CP_UTF8)); + _style.setEnhancedPosition(style.enhanced_position); + _style.setLabelTextFormat(wstring_to_string(style.label_text_format, CP_UTF8)); + _style.setMarkText(wstring_to_string(style.mark_text, CP_UTF8)); + _style.setMinWidth(style.min_width); + _style.setMaxWidth(style.max_width); + _style.setMinHeight(style.min_height); + _style.setMaxHeight(style.max_height); + _style.setBorder(style.border); + _style.setMarginX(style.margin_x); + _style.setMarginY(style.margin_y); + _style.setSpacing(style.spacing); + _style.setCandidateSpacing(style.candidate_spacing); + _style.setHiliteSpacing(style.hilite_spacing); + _style.setHilitePaddingX(style.hilite_padding_x); + _style.setHilitePaddingY(style.hilite_padding_y); + _style.setRoundCorner(style.round_corner); + _style.setRoundCornerEx(style.round_corner_ex); + _style.setShadowRadius(style.shadow_radius); + _style.setShadowOffsetX(style.shadow_offset_x); + _style.setShadowOffsetY(style.shadow_offset_y); + _style.setVerticalAutoReverse(style.vertical_auto_reverse); + _style.setTextColor(style.text_color); + _style.setCandidateTextColor(style.candidate_text_color); + _style.setCandidateBackColor(style.candidate_back_color); + _style.setCandidateShadowColor(style.candidate_shadow_color); + _style.setCandidateBorderColor(style.candidate_border_color); + _style.setLabelTextColor(style.label_text_color); + _style.setCommentTextColor(style.comment_text_color); + _style.setBackColor(style.back_color); + _style.setShadowColor(style.shadow_color); + _style.setBorderColor(style.border_color); + _style.setHilitedTextColor(style.hilited_text_color); + _style.setHilitedBackColor(style.hilited_back_color); + _style.setHilitedShadowColor(style.hilited_shadow_color); + _style.setHilitedCandidateTextColor(style.hilited_candidate_text_color); + _style.setHilitedCandidateBackColor(style.hilited_candidate_back_color); + _style.setHilitedCandidateShadowColor(style.hilited_candidate_shadow_color); + _style.setHilitedCandidateBorderColor(style.hilited_candidate_border_color); + _style.setHilitedLabelTextColor(style.hilited_label_text_color); + _style.setHilitedCommentTextColor(style.hilited_comment_text_color); + _style.setHilitedMarkColor(style.hilited_mark_color); + _style.setPrevpageColor(style.prevpage_color); + _style.setNextpageColor(style.nextpage_color); + _style.setClientCaps(style.client_caps); + } + + rspbdr.setInlinePreedit(m_ui->style().inline_preedit); + + auto m = capnp::messageToFlatArray(msg); + auto encoded_array_ptr = m.asChars(); + static auto encoded_char_array = encoded_array_ptr.begin(); + auto size = encoded_array_ptr.size(); + return eat(encoded_char_array, size); + +#endif RIME_STRUCT(RimeCommit, commit); if (RimeGetCommit(session_id, &commit)) { diff --git a/RimeWithWeasel/RimeWithWeasel.vcxproj b/RimeWithWeasel/RimeWithWeasel.vcxproj index 04ae9169e..403269b86 100644 --- a/RimeWithWeasel/RimeWithWeasel.vcxproj +++ b/RimeWithWeasel/RimeWithWeasel.vcxproj @@ -184,6 +184,7 @@ + Create diff --git a/RimeWithWeasel/RimeWithWeasel.vcxproj.filters b/RimeWithWeasel/RimeWithWeasel.vcxproj.filters index 91998a146..c40490f26 100644 --- a/RimeWithWeasel/RimeWithWeasel.vcxproj.filters +++ b/RimeWithWeasel/RimeWithWeasel.vcxproj.filters @@ -24,6 +24,9 @@ Source Files + + Source Files + diff --git a/RimeWithWeasel/prepare.bat b/RimeWithWeasel/prepare.bat new file mode 100644 index 000000000..d4a2e854f --- /dev/null +++ b/RimeWithWeasel/prepare.bat @@ -0,0 +1,5 @@ +set PATH=%PATH%;C:\Users\DELL\Desktop\Dev\weasel_new\capnp\win32\bin +capnp compile -oc++ protocal.capnp +move /Y protocal.capnp.c++ protocal.capnp.cpp +echo #include "stdafx.h" >> protocal.capnp.cpp +move /Y protocal.capnp.h ..\include\ \ No newline at end of file diff --git a/RimeWithWeasel/protocal.capnp b/RimeWithWeasel/protocal.capnp new file mode 100644 index 000000000..a66e05d9f --- /dev/null +++ b/RimeWithWeasel/protocal.capnp @@ -0,0 +1,150 @@ +@0xd43fa5654901f1dc; + +struct WeaselCommit { + # Text to commit to input field. + text @0 :Text; +} + +struct WeaselCandidate { + text @0 :Text; + comment @1 :Text; + label @2 :Text; +} + +struct WeaselStatus { + schemaId @0 :Text; + schemaName @1 :Text; + isDisabled @2 :Bool; + isComposing @3 :Bool; + isAsciiMode @4 :Bool; + isFullShape @5 :Bool; + isSimplified @6 :Bool; + isTraditional @7 :Bool; + isAsciiPunct @8 :Bool; +} + +struct WeaselContext { + # Input context. + struct WeaselPreedit { + str @0:Text; + start @1:UInt32; + end @2:UInt32; + cursor@3:UInt32; + } + + struct WeaselCandidateInfo { + currentPage@0: UInt32; + isLastPage@1: Bool; + totalPages@2: UInt32; + highlighted@3: UInt32; + candies@4: List(Text); + comments@5: List(Text); + labels@6: List(Text); + } + preedit@0: WeaselPreedit; + candidateInfo@1: WeaselCandidateInfo; +} + +struct WeaselUIStyle { + #UIStyle + enum CAntiAliasMode { + default @0; + clearType @1; + grayScale @2; + aliased @3; + forceDword@4; + } + enum CPreeditType { + composition @0; + preview @1; + previewAll @2; + } + enum CLayoutType { + layoutVertical @0; + layoutHorizontal @1; + layoutVerticalText @2; + layoutVerticalFullscreen @3; + layoutHorizontalFullscreen @4; + layoutTypeLast @5; + } + enum CLayoutAlignType { + alignBottom @0; + alignCenter @1; + alignTop @2; + } + antialiasMode @0:CAntiAliasMode; + algnType @1:CLayoutAlignType; + preeditType @2:CPreeditType; + layoutType @3:CLayoutType; + verticalTextLeftToRight @4:Bool; + verticalTextWithWrap @5:Bool; + pagingOnScroll @6:Bool; + fontFace @7:Text; + labelFontFace @8:Text; + commentFontFace @9:Text; + mouseHoverMs @10:Int32; + fontPoint @11:Int32; + labelFontPoint @12:Int32; + commentFontPoint @13:Int32; + inlinePreedit @14:Bool; + displayTrayIcon @15:Bool; + asciiTipFollowCursor @16:Bool; + currentZhungIcon @17:Text; + currentAsciiIcon @18:Text; + currentHalfIcon @19:Text; + currentFullIcon @20:Text; + enhancedPosition @21:Bool; + labelTextFormat @22:Text; + markText @23:Text; + minWidth @24:Int32; + maxWidth @25:Int32; + minHeight @26:Int32; + maxHeight @27:Int32; + border @28:Int32; + marginX @29:Int32; + marginY @30:Int32; + spacing @31:Int32; + candidateSpacing @32:Int32; + hiliteSpacing@33:Int32; + hilitePaddingX@34:Int32; + hilitePaddingY@35:Int32; + roundCorner@36:Int32; + roundCornerEx@37:Int32; + shadowRadius@38:Int32; + shadowOffsetX@39:Int32; + shadowOffsetY@40:Int32; + verticalAutoReverse@41:Bool; + + textColor@42:Int32; + candidateTextColor@43:Int32; + candidateBackColor@44:Int32; + candidateShadowColor@45:Int32; + candidateBorderColor@46:Int32; + labelTextColor@47:Int32; + commentTextColor@48:Int32; + backColor@49:Int32; + shadowColor@50:Int32; + borderColor@51:Int32; + hilitedTextColor@52:Int32; + hilitedBackColor@53:Int32; + hilitedShadowColor@54:Int32; + hilitedCandidateTextColor@55:Int32; + hilitedCandidateBackColor@56:Int32; + hilitedCandidateShadowColor@57:Int32; + hilitedCandidateBorderColor@58:Int32; + hilitedLabelTextColor@59:Int32; + hilitedCommentTextColor@60:Int32; + hilitedMarkColor@61:Int32; + prevpageColor@62:Int32; + nextpageColor@63:Int32; + clientCaps@64:Int32; +} + +struct WeaselRespondData { + commit @0:WeaselCommit; + status @1:WeaselStatus; + context @2:WeaselContext; + inlinePreedit@3:Bool; + style@4:WeaselUIStyle; + +} diff --git a/WeaselIPC/ResponseParser.cpp b/WeaselIPC/ResponseParser.cpp index 5095705ee..0ff1129c2 100644 --- a/WeaselIPC/ResponseParser.cpp +++ b/WeaselIPC/ResponseParser.cpp @@ -2,9 +2,24 @@ #include #include #include "Deserializer.h" +#include +#include +#include +#include "protocal.capnp.h" +#ifdef _WIN64 +#pragma comment(lib, "capnp-x64.lib") +#pragma comment(lib, "kj-x64.lib") +#else +#pragma comment(lib, "capnp.lib") +#pragma comment(lib, "kj.lib") +#endif + +using namespace capnp; using namespace weasel; +#define TO_WSTRING(str) string_to_wstring(str, CP_UTF8) + ResponseParser::ResponseParser(std::wstring* commit, Context* context, Status* status, Config* config, UIStyle* style) : p_commit(commit), p_context(context), p_status(status), p_config(config), p_style(style) { @@ -30,6 +45,125 @@ bool ResponseParser::operator() (LPWSTR buffer, UINT length) return bs.good(); } +bool ResponseParser::operator() (char* buffer, UINT length) +{ + auto received_array = kj::ArrayPtr(reinterpret_cast(buffer), length / sizeof(capnp::word)); + capnp::FlatArrayMessageReader msg_char_reader(received_array); + auto reader = msg_char_reader.getRoot(); + // get commit + if (reader.hasCommit()) { + auto _str = std::string(reader.getCommit().getText()); + *p_commit = string_to_wstring(_str, CP_UTF8); + } + // get status + if (reader.hasStatus()) { + auto _sta = reader.getStatus(); + p_status->ascii_mode = _sta.getIsAsciiMode(); + p_status->composing = _sta.getIsComposing(); + p_status->disabled = _sta.getIsDisabled(); + p_status->full_shape = _sta.getIsFullShape(); + p_status->schema_id = string_to_wstring(std::string(_sta.getSchemaId()), CP_UTF8); + p_status->schema_name = string_to_wstring(std::string(_sta.getSchemaName()), CP_UTF8); + } + // get context + if (reader.hasContext()) { + auto _ctx = reader.getContext(); + if (_ctx.hasCandidateInfo()) { + auto _cinfo = _ctx.getCandidateInfo(); + p_context->cinfo.currentPage = _cinfo.getCurrentPage(); + p_context->cinfo.highlighted = _cinfo.getHighlighted(); + p_context->cinfo.is_last_page = _cinfo.getIsLastPage(); + auto _labels = _cinfo.getLabels(); + auto _candies = _cinfo.getCandies(); + auto _comments = _cinfo.getComments(); + auto number_of_candidates = _candies.size(); + auto number_of_labels = _labels.size(); + auto number_of_comments = _comments.size(); + for (auto i = 0; i < number_of_candidates; i++) { + p_context->cinfo.candies.at(i).str = TO_WSTRING(std::string(_candies[i])); + } + for (auto i = 0; i < number_of_labels; i++) { + p_context->cinfo.labels.at(i).str = TO_WSTRING(std::string(_labels[i])); + } + for (auto i = 0; i < number_of_comments; i++) { + p_context->cinfo.comments.at(i).str = TO_WSTRING(std::string(_comments[i])); + } + } + } + // get UIStyle + if (reader.hasStyle()) { + auto _style = reader.getStyle(); + p_style->align_type = static_cast(_style.getAlgnType()); + p_style->antialias_mode = static_cast(_style.getAntialiasMode()); + p_style->preedit_type = static_cast(_style.getPreeditType()); + p_style->layout_type = static_cast(_style.getLayoutType()); + p_style->vertical_text_left_to_right = _style.getVerticalTextLeftToRight(); + p_style->vertical_text_with_wrap = _style.getVerticalTextWithWrap(); + p_style->paging_on_scroll = _style.getPagingOnScroll(); + p_style->font_face = TO_WSTRING(std::string(_style.getFontFace())); + p_style->label_font_face = TO_WSTRING(std::string(_style.getLabelFontFace())); + p_style->comment_font_face = TO_WSTRING(std::string(_style.getCommentFontFace())); + p_style->mouse_hover_ms = _style.getMouseHoverMs(); + p_style->font_point = _style.getFontPoint(); + p_style->label_font_point = _style.getLabelFontPoint(); + p_style->comment_font_point = _style.getCommentFontPoint(); + p_style->inline_preedit = _style.getInlinePreedit(); + p_style->display_tray_icon = _style.getDisplayTrayIcon(); + p_style->ascii_tip_follow_cursor = _style.getAsciiTipFollowCursor(); + p_style->current_zhung_icon = TO_WSTRING(std::string(_style.getCurrentZhungIcon())); + p_style->current_ascii_icon = TO_WSTRING(std::string(_style.getCurrentAsciiIcon())); + p_style->current_half_icon = TO_WSTRING(std::string(_style.getCurrentHalfIcon())); + p_style->current_full_icon = TO_WSTRING(std::string(_style.getCurrentFullIcon())); + p_style->enhanced_position = _style.getEnhancedPosition(); + p_style->label_text_format = TO_WSTRING(std::string(_style.getLabelTextFormat())); + p_style->mark_text = TO_WSTRING(std::string(_style.getMarkText())); + p_style->min_width = _style.getMinWidth(); + p_style->max_width = _style.getMaxWidth(); + p_style->min_height = _style.getMinHeight(); + p_style->max_height = _style.getMaxHeight(); + p_style->border = _style.getBorder(); + p_style->margin_x = _style.getMarginX(); + p_style->margin_y = _style.getMarginY(); + p_style->spacing = _style.getSpacing(); + p_style->candidate_spacing = _style.getCandidateSpacing(); + p_style->hilite_spacing = _style.getHiliteSpacing(); + p_style->hilite_padding_x = _style.getHilitePaddingX(); + p_style->hilite_padding_y = _style.getHilitePaddingY(); + p_style->round_corner = _style.getRoundCorner(); + p_style->round_corner_ex = _style.getRoundCornerEx(); + p_style->shadow_radius = _style.getShadowRadius(); + p_style->shadow_offset_x = _style.getShadowOffsetX(); + p_style->shadow_offset_y = _style.getShadowOffsetY(); + p_style->vertical_auto_reverse = _style.getVerticalAutoReverse(); + p_style->text_color = _style.getTextColor(); + p_style->candidate_text_color = _style.getCandidateTextColor(); + p_style->candidate_back_color = _style.getCandidateBackColor(); + p_style->candidate_shadow_color = _style.getCandidateShadowColor(); + p_style->candidate_border_color = _style.getCandidateBorderColor(); + p_style->label_text_color = _style.getLabelTextColor(); + p_style->comment_text_color = _style.getCommentTextColor(); + p_style->back_color = _style.getBackColor(); + p_style->shadow_color = _style.getShadowColor(); + p_style->border_color = _style.getBorderColor(); + p_style->hilited_text_color = _style.getHilitedTextColor(); + p_style->hilited_back_color = _style.getHilitedBackColor(); + p_style->hilited_shadow_color = _style.getHilitedShadowColor(); + p_style->hilited_candidate_text_color = _style.getHilitedCandidateTextColor(); + p_style->hilited_candidate_back_color = _style.getHilitedCandidateBackColor(); + p_style->hilited_candidate_shadow_color = _style.getHilitedCandidateShadowColor(); + p_style->hilited_candidate_border_color = _style.getHilitedCandidateBorderColor(); + p_style->hilited_label_text_color = _style.getHilitedLabelTextColor(); + p_style->hilited_comment_text_color = _style.getHilitedCommentTextColor(); + p_style->hilited_mark_color = _style.getHilitedMarkColor(); + p_style->prevpage_color = _style.getPrevpageColor(); + p_style->nextpage_color = _style.getNextpageColor(); + p_style->client_caps = _style.getClientCaps(); + } + // config + p_config->inline_preedit = reader.getInlinePreedit(); + return true; +} + void ResponseParser::Feed(const std::wstring& line) { // ignore blank lines and comments diff --git a/WeaselIPC/WeaselIPC.vcxproj b/WeaselIPC/WeaselIPC.vcxproj index d41c3f8b0..96837b899 100644 --- a/WeaselIPC/WeaselIPC.vcxproj +++ b/WeaselIPC/WeaselIPC.vcxproj @@ -277,6 +277,11 @@ + + + {1c497821-bd63-4f02-9094-32b185b62f23} + + diff --git a/WeaselIPCServer/WeaselServerImpl.cpp b/WeaselIPCServer/WeaselServerImpl.cpp index 3ac82d96c..b3de88dd7 100644 --- a/WeaselIPCServer/WeaselServerImpl.cpp +++ b/WeaselIPCServer/WeaselServerImpl.cpp @@ -187,7 +187,9 @@ DWORD ServerImpl::OnStartSession(WEASEL_IPC_COMMAND uMsg, DWORD wParam, DWORD lP return m_pRequestHandler->AddSession( reinterpret_cast(channel->ReceiveBuffer()), [this](std::wstring &msg) -> bool { + //[this](char* buffer, UINT length) -> bool { *channel << msg; + //channel->WriteBuffer(buffer, length); return true; } ); @@ -206,7 +208,9 @@ DWORD ServerImpl::OnKeyEvent(WEASEL_IPC_COMMAND uMsg, DWORD wParam, DWORD lParam return 0; auto eat = [this](std::wstring &msg) -> bool { + //auto eat = [this](char* buffer, UINT length) -> bool { *channel << msg; + //channel->WriteBuffer(buffer, length); return true; }; return m_pRequestHandler->ProcessKeyEvent(KeyEvent(wParam), lParam, eat); diff --git a/capnp.bat b/capnp.bat new file mode 100644 index 000000000..ff95b25fc --- /dev/null +++ b/capnp.bat @@ -0,0 +1,114 @@ +@echo off +setlocal + +set project_root=%CD% + +set clean=0 +set build=0 +set build_dir=build +set build_config=Release +set arch=Win32 +set build_x64=0 + +:parse_cmdline_options +if "%1" == "" goto end_parsing_cmdline_options +if "%1" == "clean" set clean=1 +if "%1" == "build" set build=1 +if "%1" == "debug" ( + set build_dir=debug + set build_config=Debug +) +if "%1" == "x64" ( + rmdir /s /q deps\capnproto\build + set install_dir=%project_root%\capnp\x64 + set ARCH=x64 + set build_x64=1 +) else ( + rmdir /s /q deps\capnproto\build + set install_dir=%project_root%\capnp\win32 + set ARCH=Win32 +) + +if "%1" == "release" ( + set build_dir=build + set build_config=Release +) +shift +goto parse_cmdline_options +:end_parsing_cmdline_options + +if %clean% == 0 ( +if %build% == 0 ( + set build=1 +)) + +if %clean% == 1 ( + rmdir /s /q deps\capnproto\build + goto exit +) + + +if defined WEASEL_ROOT ( +if exist %WEASEL_ROOT%\env.bat ( + call %WEASEL_ROOT%\env.bat +)) + +if defined CMAKE_GENERATOR ( + set deps_cmake_flags=%deps_cmake_flags% -G%CMAKE_GENERATOR% +) +if defined ARCH ( + set deps_cmake_flags=%deps_cmake_flags% -A%ARCH% +) +if defined PLATFORM_TOOLSET ( + set deps_cmake_flags=%deps_cmake_flags% -T%PLATFORM_TOOLSET% +) +set deps_cmake_flags=%deps_cmake_flags%^ + -DCMAKE_CONFIGURATION_TYPES:STRING="%build_config%"^ + -DCMAKE_CXX_FLAGS_RELEASE:STRING="/MT /O2 /Ob2 /DNDEBUG"^ + -DCMAKE_C_FLAGS_RELEASE:STRING="/MT /O2 /Ob2 /DNDEBUG"^ + -DCMAKE_CXX_FLAGS_DEBUG:STRING="/MTd /Od"^ + -DCMAKE_C_FLAGS_DEBUG:STRING="/MTd /Od"^ + -DCMAKE_INSTALL_PREFIX:PATH="%install_dir%" + +if %build% == 1 ( + echo building capnproto. + pushd deps\capnproto + cmake . -B%build_dir% %deps_cmake_flags%^ + -DBUILD_SHARED_LIBS:BOOL=OFF^ + -DBUILD_TESTING:BOOL=OFF + if errorlevel 1 goto error + cmake --build %build_dir% --config %build_config% --target INSTALL + if errorlevel 1 goto error + popd +) + + +echo. +echo done. +echo. +if %build_x64%==1 ( + xcopy /Y /I %install_dir%\lib\capnp.lib %project_root%\lib\capnp-x64.lib + xcopy /Y /I %install_dir%\lib\capnpc.lib %project_root%\lib\capnpc-x64.lib + xcopy /Y /I %install_dir%\lib\capnp-json.lib %project_root%\lib\capnp-json-x64.lib + xcopy /Y /I %install_dir%\lib\capnp-rpc.lib %project_root%\lib\capnp-rpc-x64.lib + xcopy /Y /I %install_dir%\lib\capnp-websocket.lib %project_root%\lib\capnp-websocket-x64.lib + xcopy /Y /I %install_dir%\lib\kj.lib %project_root%\lib\kj-x64.lib + xcopy /Y /I %install_dir%\lib\kj-async.lib %project_root%\lib\kj-async-x64.lib + xcopy /Y /I %install_dir%\lib\kj-http.lib %project_root%\lib\kj-http-x64.lib + xcopy /Y /I %install_dir%\lib\kj-test.lib %project_root%\lib\kj-test-x64.lib + xcopy /Y /E %install_dir%\include\* %project_root%\include\ +) else ( + xcopy /Y /I %install_dir%\lib\* %project_root%\lib\ + xcopy /Y /E %install_dir%\include\* %project_root%\include\ +) +goto exit + +:error +set exitcode=%errorlevel% +echo. +echo error building deps. +echo. + +:exit +set PATH=%OLD_PATH% +exit /b %exitcode% diff --git a/include/PipeChannel.h b/include/PipeChannel.h index e1f7263e8..46e59f133 100644 --- a/include/PipeChannel.h +++ b/include/PipeChannel.h @@ -98,6 +98,20 @@ namespace weasel { return *this; } + PipeChannel& WriteBuffer(char* buff, size_t data_sz) + { + has_body = true; + _Ensure(); + try { + _WritePipe(hpipe, data_sz, buff); + } catch (...) { + _Reconnect(); + _WritePipe(hpipe, data_sz, buff); + } + ClearBufferStream(); + return *this; + } + _TyRes Transact(Msg &msg) { _Ensure(); @@ -128,6 +142,8 @@ namespace weasel { // Use whole buffer to receive data in client return handler((LPWSTR)buffer.get(), (UINT)(buff_size * sizeof(char) / sizeof(wchar_t))); + // + //return handler(buffer.get(), (UINT)(buff_size * sizeof(char))); } diff --git a/include/ResponseParser.h b/include/ResponseParser.h index a8a934616..a26e2b305 100644 --- a/include/ResponseParser.h +++ b/include/ResponseParser.h @@ -26,6 +26,8 @@ namespace weasel // 重載函數調用運算符, 以扮做ResponseHandler bool operator() (LPWSTR buffer, UINT length); + bool operator() (char* buffer, UINT length); + // 處理一行回應文本 void Feed(const std::wstring& line); }; diff --git a/include/RimeWithWeasel.h b/include/RimeWithWeasel.h index cc75bc4fa..9f837484b 100644 --- a/include/RimeWithWeasel.h +++ b/include/RimeWithWeasel.h @@ -44,6 +44,7 @@ class RimeWithWeaselHandler : void _GetCandidateInfo(weasel::CandidateInfo &cinfo, RimeContext &ctx); void _GetStatus(weasel::Status &stat, UINT session_id, weasel::Context& ctx); void _GetContext(weasel::Context &ctx, UINT session_id); + void _prepare(UINT session_id); bool _IsSessionTSF(UINT session_id); void _UpdateInlinePreeditStatus(UINT session_id); diff --git a/include/WeaselIPC.h b/include/WeaselIPC.h index 3df3aca08..4148b4700 100644 --- a/include/WeaselIPC.h +++ b/include/WeaselIPC.h @@ -67,6 +67,7 @@ namespace weasel struct RequestHandler { using EatLine = std::function; + //using EatLine = std::function; RequestHandler() {} virtual ~RequestHandler() {} virtual void Initialize() {} @@ -88,6 +89,7 @@ namespace weasel // 處理server端回應之物件 typedef std::function ResponseHandler; + //typedef std::function ResponseHandler; // 事件處理函數 typedef std::function CommandHandler;