void RimeWithWeaselHandler::_ReadClientInfo(UINT session_id, LPWSTR buffer) { std::string app_name; std::string client_type; // parse request text wbufferstream bs(buffer, WEASEL_IPC_BUFFER_LENGTH); std::wstring line; while (bs.good()) { std::getline(bs, line); if (!bs.good()) break; // file ends if (line == L".") break; const std::wstring kClientAppKey = L"session.client_app="; if (starts_with(line, kClientAppKey)) { std::wstring lwr = line; to_lower(lwr); app_name = wcstoutf8(lwr.substr(kClientAppKey.length()).c_str()); } const std::wstring kClientTypeKey = L"session.client_type="; if (starts_with(line, kClientTypeKey)) { client_type = wcstoutf8(line.substr(kClientTypeKey.length()).c_str()); } } // set app specific options if (!app_name.empty()) { RimeSetProperty(session_id, "client_app", app_name.c_str()); if (m_app_options.find(app_name) != m_app_options.end()) { AppOptions& options(m_app_options[app_name]); std::for_each(options.begin(), options.end(), [session_id](std::pair<const std::string, bool> &pair) { DLOG(INFO) << "set app option: " << pair.first << " = " << pair.second; RimeSetOption(session_id, pair.first.c_str(), Bool(pair.second)); }); } } // ime | tsf RimeSetProperty(session_id, "client_type", client_type.c_str()); // inline preedit bool inline_preedit = m_ui->style().inline_preedit && (client_type == "tsf"); RimeSetOption(session_id, "inline_preedit", Bool(inline_preedit)); // show soft cursor on weasel panel but not inline RimeSetOption(session_id, "soft_cursor", Bool(!inline_preedit)); }
void RimeWithWeaselHandler::_GetStatus(weasel::Status & stat, UINT session_id) { RIME_STRUCT(RimeStatus, status); if (RimeGetStatus(session_id, &status)) { std::string schema_id = status.schema_id; if (schema_id != m_last_schema_id) { m_last_schema_id = schema_id; RimeSetOption(session_id, "__synced", false); // Sync new schema options with front end _LoadSchemaSpecificSettings(schema_id); } stat.schema_name = utf8towcs(status.schema_name); stat.ascii_mode = !!status.is_ascii_mode; stat.composing = !!status.is_composing; stat.disabled = !!status.is_disabled; RimeFreeStatus(&status); } }
// session management static jint create_session(JNIEnv *env, jobject thiz) { RimeSessionId session_id = RimeCreateSession(); RimeSetOption(session_id, "soft_cursor", True); return session_id; }
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()))); }); }
void RimeWithWeaselHandler::SetOption(UINT session_id, const std::string & opt, bool val) { RimeSetOption(session_id, opt.c_str(), val); }