void RimeWithWeaselHandler::_GetContext(weasel::Context & weasel_context, UINT session_id) { RIME_STRUCT(RimeContext, ctx); if (RimeGetContext(session_id, &ctx)) { if (ctx.composition.length > 0) { weasel_context.preedit.str = utf8towcs(ctx.composition.preedit); if (ctx.composition.sel_start < ctx.composition.sel_end) { weasel::TextAttribute attr; attr.type = weasel::HIGHLIGHTED; attr.range.start = utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start); attr.range.end = utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end); weasel_context.preedit.attributes.push_back(attr); } } if (ctx.menu.num_candidates) { weasel::CandidateInfo &cinfo(weasel_context.cinfo); _GetCandidateInfo(cinfo, ctx); } RimeFreeContext(&ctx); } }
static jboolean get_context(JNIEnv *env, jobject thiz, jint session_id) { RIME_STRUCT(RimeContext, context); Bool r = RimeGetContext(session_id, &context); if (r) { jclass jc = env->GetObjectClass(thiz); jfieldID fid; fid = env->GetFieldID(jc, "commit_text_preview", "Ljava/lang/String;"); env->SetObjectField(thiz, fid, newJstring(env, context.commit_text_preview)); fid = env->GetFieldID(jc, "menu_num_candidates", "I"); env->SetIntField(thiz, fid, context.menu.num_candidates); fid = env->GetFieldID(jc, "menu_page_size", "I"); env->SetIntField(thiz, fid, context.menu.page_size); fid = env->GetFieldID(jc, "menu_page_no", "I"); env->SetIntField(thiz, fid, context.menu.page_no); fid = env->GetFieldID(jc, "menu_highlighted_candidate_index", "I"); env->SetIntField(thiz, fid, context.menu.highlighted_candidate_index); fid = env->GetFieldID(jc, "menu_is_last_page", "Z"); env->SetBooleanField(thiz, fid, context.menu.is_last_page); fid = env->GetFieldID(jc, "menu_select_keys", "Ljava/lang/String;"); env->SetObjectField(thiz, fid, newJstring(env, context.menu.select_keys)); fid = env->GetFieldID(jc, "composition_length", "I"); env->SetIntField(thiz, fid, context.composition.length); fid = env->GetFieldID(jc, "composition_cursor_pos", "I"); env->SetIntField(thiz, fid, context.composition.cursor_pos); fid = env->GetFieldID(jc, "composition_sel_start", "I"); env->SetIntField(thiz, fid, context.composition.sel_start); fid = env->GetFieldID(jc, "composition_sel_end", "I"); env->SetIntField(thiz, fid, context.composition.sel_end); fid = env->GetFieldID(jc, "composition_preedit", "Ljava/lang/String;"); env->SetObjectField(thiz, fid, newJstring(env, context.composition.preedit)); int n = context.menu.num_candidates; fid = env->GetFieldID(jc, "candidates_text", "[Ljava/lang/String;"); jobjectArray texts = (jobjectArray) env->GetObjectField(thiz, fid); fid = env->GetFieldID(jc, "candidates_comment", "[Ljava/lang/String;"); jobjectArray comments = (jobjectArray) env->GetObjectField(thiz, fid); for (int i = 0; i < n; ++i) { env->SetObjectArrayElement(texts, i, newJstring(env, context.menu.candidates[i].text)); env->SetObjectArrayElement(comments, i, newJstring(env, context.menu.candidates[i].comment)); } RimeFreeContext(&context); } return r; }
bool RimeWithWeaselHandler::_Respond(UINT session_id, LPWSTR buffer) { std::set<std::string> actions; std::list<std::string> messages; // extract information RimeCommit commit = {0}; if (RimeGetCommit(session_id, &commit)) { actions.insert("commit"); messages.push_back(boost::str(boost::format("commit=%s\n") % commit.text)); RimeFreeCommit(&commit); } bool is_composing; RimeStatus status = {0}; RIME_STRUCT_INIT(RimeStatus, status); if (RimeGetStatus(session_id, &status)) { is_composing = status.is_composing; actions.insert("status"); messages.push_back(boost::str(boost::format("status.ascii_mode=%d\n") % status.is_ascii_mode)); messages.push_back(boost::str(boost::format("status.composing=%d\n") % status.is_composing)); messages.push_back(boost::str(boost::format("status.disabled=%d\n") % status.is_disabled)); RimeFreeStatus(&status); } RimeContext ctx = {0}; RIME_STRUCT_INIT(RimeContext, ctx); if (RimeGetContext(session_id, &ctx)) { if (is_composing) { actions.insert("ctx"); messages.push_back(boost::str(boost::format("ctx.preedit=%s\n") % ctx.composition.preedit)); if (ctx.composition.sel_start <= ctx.composition.sel_end) { messages.push_back(boost::str(boost::format("ctx.preedit.cursor=%d,%d\n") % utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start) % utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end))); } } RimeFreeContext(&ctx); } // configuration information actions.insert("config"); messages.push_back(boost::str(boost::format("config.inline_preedit=%d\n") % (int) m_ui->style().inline_preedit)); // summarize if (actions.empty()) { messages.insert(messages.begin(), std::string("action=noop\n")); } else { std::string actionList(boost::join(actions, ",")); messages.insert(messages.begin(), boost::str(boost::format("action=%s\n") % actionList)); } messages.push_back(std::string(".\n")); // printing to stream memset(buffer, 0, WEASEL_IPC_BUFFER_SIZE); wbufferstream bs(buffer, WEASEL_IPC_BUFFER_LENGTH); BOOST_FOREACH(const std::string &msg, messages) { bs << utf8towcs(msg.c_str()); if (!bs.good()) { // response text toooo long! return false; } }
void RimeWithWeaselHandler::_UpdateUI(UINT session_id) { weasel::Status weasel_status; weasel::Context weasel_context; if (session_id == 0) weasel_status.disabled = m_disabled; RimeStatus status = {0}; RIME_STRUCT_INIT(RimeStatus, status); if (RimeGetStatus(session_id, &status)) { weasel_status.schema_name = utf8towcs(status.schema_name); weasel_status.ascii_mode = status.is_ascii_mode; weasel_status.composing = status.is_composing; weasel_status.disabled = status.is_disabled; RimeFreeStatus(&status); } RimeContext ctx = {0}; RIME_STRUCT_INIT(RimeContext, ctx); if (RimeGetContext(session_id, &ctx)) { if (ctx.composition.length > 0) { weasel_context.preedit.str = utf8towcs(ctx.composition.preedit); if (ctx.composition.sel_start < ctx.composition.sel_end) { weasel::TextAttribute attr; attr.type = weasel::HIGHLIGHTED; attr.range.start = utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start); attr.range.end = utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end); weasel_context.preedit.attributes.push_back(attr); } } if (ctx.menu.num_candidates) { weasel::CandidateInfo &cinfo(weasel_context.cinfo); cinfo.candies.resize(ctx.menu.num_candidates); cinfo.comments.resize(ctx.menu.num_candidates); for (int i = 0; i < ctx.menu.num_candidates; ++i) { cinfo.candies[i].str = utf8towcs(ctx.menu.candidates[i].text); if (ctx.menu.candidates[i].comment) { cinfo.comments[i].str = utf8towcs(ctx.menu.candidates[i].comment); } } cinfo.highlighted = ctx.menu.highlighted_candidate_index; cinfo.currentPage = ctx.menu.page_no; cinfo.labels = ctx.menu.select_keys; } RimeFreeContext(&ctx); } if (!m_ui) return; if (RimeGetOption(session_id, "inline_preedit")) m_ui->style().client_caps |= weasel::INLINE_PREEDIT_CAPABLE; else m_ui->style().client_caps &= ~weasel::INLINE_PREEDIT_CAPABLE; if (weasel_status.composing) { m_ui->Update(weasel_context, weasel_status); m_ui->Show(); } else if (!_ShowMessage(weasel_context, weasel_status)) { m_ui->Hide(); m_ui->Update(weasel_context, weasel_status); } m_message_type.clear(); m_message_value.clear(); }
bool RimeWithWeaselHandler::_Respond(UINT session_id, EatLine eat) { std::set<std::string> actions; std::list<std::string> messages; // extract information RIME_STRUCT(RimeCommit, commit); if (RimeGetCommit(session_id, &commit)) { actions.insert("commit"); messages.push_back(std::string("commit=") + commit.text + '\n'); RimeFreeCommit(&commit); } bool is_composing = false; RIME_STRUCT(RimeStatus, status); if (RimeGetStatus(session_id, &status)) { is_composing = !!status.is_composing; actions.insert("status"); messages.push_back(std::string("status.ascii_mode=") + std::to_string(status.is_ascii_mode) + '\n'); messages.push_back(std::string("status.composing=") + std::to_string(status.is_composing) + '\n'); messages.push_back(std::string("status.disabled=") + std::to_string(status.is_disabled) + '\n'); RimeFreeStatus(&status); } RIME_STRUCT(RimeContext, ctx); if (RimeGetContext(session_id, &ctx)) { if (is_composing) { actions.insert("ctx"); switch (m_ui->style().preedit_type) { case weasel::UIStyle::PREVIEW: if (ctx.commit_text_preview != NULL) { std::string first = ctx.commit_text_preview; messages.push_back(std::string("ctx.preedit=") + first + '\n'); messages.push_back(std::string("ctx.preedit.cursor=") + std::to_string(utf8towcslen(first.c_str(), 0)) + ',' + std::to_string(utf8towcslen(first.c_str(), first.size())) + '\n'); break; } // no preview, fall back to composition case weasel::UIStyle::COMPOSITION: messages.push_back(std::string("ctx.preedit=") + ctx.composition.preedit + '\n'); if (ctx.composition.sel_start <= ctx.composition.sel_end) { messages.push_back(std::string("ctx.preedit.cursor=") + std::to_string(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_start)) + ',' + std::to_string(utf8towcslen(ctx.composition.preedit, ctx.composition.sel_end)) + '\n'); } break; } } if (ctx.menu.num_candidates) { weasel::CandidateInfo cinfo; std::wstringstream ss; boost::archive::text_woarchive oa(ss); _GetCandidateInfo(cinfo, ctx); oa << cinfo; messages.push_back(std::string("ctx.cand=") + wcstoutf8(ss.str().c_str()) + '\n'); } RimeFreeContext(&ctx); } // configuration information actions.insert("config"); messages.push_back(std::string("config.inline_preedit=") + std::to_string((int)m_ui->style().inline_preedit) + '\n'); // style bool has_synced = RimeGetOption(session_id, "__synced"); if (!has_synced) { std::wstringstream ss; boost::archive::text_woarchive oa(ss); oa << m_ui->style(); actions.insert("style"); messages.push_back(std::string("style=") + wcstoutf8(ss.str().c_str()) + '\n'); RimeSetOption(session_id, "__synced", true); } // summarize if (actions.empty()) { messages.insert(messages.begin(), std::string("action=noop\n")); } else { std::string actionList(join(actions, ",")); messages.insert(messages.begin(), std::string("action=") + actionList + '\n'); } messages.push_back(std::string(".\n")); return std::all_of(messages.begin(), messages.end(), [&eat](std::string &msg) { return eat(std::wstring(utf8towcs(msg.c_str()))); }); }