From b6251d1c46ef1bea3b69754753820807c4ffaa28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=85=E6=88=8E=E6=B0=8F?= Date: Thu, 16 May 2024 16:27:44 +0800 Subject: [PATCH] feat(api): provide a flavor of api using stdbool API type: RimeApi_stdbool API entry function: rime_get_api_stdbool --- CMakeLists.txt | 2 +- src/rime_api.cc | 775 ++++++----------------------------------- src/rime_api.h | 541 +++++++++------------------- src/rime_api_impl.h | 671 +++++++++++++++++++++++++++++++++++ src/rime_api_stdbool.h | 23 ++ src/rime_api_struct.h | 257 ++++++++++++++ 6 files changed, 1226 insertions(+), 1043 deletions(-) create mode 100644 src/rime_api_impl.h create mode 100644 src/rime_api_stdbool.h create mode 100644 src/rime_api_struct.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 53f9d5374c..9edb60b538 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ endif(WIN32) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "${PROJECT_SOURCE_DIR}") -if (ENABLE_ASAN) +if(ENABLE_ASAN) set(asan_cflags "-fsanitize=address -fno-omit-frame-pointer") set(asan_lflags "-fsanitize=address -lasan") set(CMAKE_C_FLAGS "${asan_cflags} ${CMAKE_C_FLAGS}") diff --git a/src/rime_api.cc b/src/rime_api.cc index dd26886309..e4aa7a91e3 100644 --- a/src/rime_api.cc +++ b/src/rime_api.cc @@ -29,7 +29,7 @@ using namespace std::placeholders; #define PROVIDED(p, member) \ ((p) && RIME_STRUCT_HAS_MEMBER(*(p), (p)->member) && (p)->member) -RIME_API void RimeSetupLogging(const char* app_name) { +RIME_API_DEPRECATED void RimeSetupLogging(const char* app_name) { SetupLogging(app_name); } @@ -49,7 +49,7 @@ static void rime_declare_module_dependencies() { } #endif -RIME_API void RimeSetup(RimeTraits* traits) { +RIME_API_DEPRECATED void RimeSetup(RimeTraits* traits) { rime_declare_module_dependencies(); SetupDeployer(traits); @@ -63,8 +63,9 @@ RIME_API void RimeSetup(RimeTraits* traits) { } } -RIME_API void RimeSetNotificationHandler(RimeNotificationHandler handler, - void* context_object) { +RIME_API_DEPRECATED void RimeSetNotificationHandler( + RimeNotificationHandler handler, + void* context_object) { if (handler) { Service::instance().SetNotificationHandler( std::bind(handler, context_object, _1, _2, _3)); @@ -73,25 +74,25 @@ RIME_API void RimeSetNotificationHandler(RimeNotificationHandler handler, } } -RIME_API void RimeInitialize(RimeTraits* traits) { +RIME_API_DEPRECATED void RimeInitialize(RimeTraits* traits) { SetupDeployer(traits); LoadModules(PROVIDED(traits, modules) ? traits->modules : kDefaultModules); Service::instance().StartService(); } -RIME_API void RimeFinalize() { +RIME_API_DEPRECATED void RimeFinalize() { RimeJoinMaintenanceThread(); Service::instance().StopService(); Registry::instance().Clear(); ModuleManager::instance().UnloadModules(); } -RIME_API Bool RimeStartMaintenance(Bool full_check) { +static bool start_maintenance(bool full_check) { LoadModules(kDeployerModules); Deployer& deployer(Service::instance().deployer()); deployer.RunTask("clean_old_log_files"); if (!deployer.RunTask("installation_update")) { - return False; + return false; } if (!full_check) { TaskInitializer args{ @@ -101,7 +102,7 @@ RIME_API Bool RimeStartMaintenance(Bool full_check) { }, }; if (!deployer.RunTask("detect_modifications", args)) { - return False; + return false; } LOG(INFO) << "changes detected; starting maintenance."; } @@ -109,103 +110,36 @@ RIME_API Bool RimeStartMaintenance(Bool full_check) { deployer.ScheduleTask("user_dict_upgrade"); deployer.ScheduleTask("cleanup_trash"); deployer.StartMaintenance(); - return True; -} - -RIME_API Bool RimeStartMaintenanceOnWorkspaceChange() { - return RimeStartMaintenance(False); + return true; } -RIME_API Bool RimeIsMaintenancing() { - Deployer& deployer(Service::instance().deployer()); - return Bool(deployer.IsMaintenanceMode()); -} - -RIME_API void RimeJoinMaintenanceThread() { +RIME_API_DEPRECATED void RimeJoinMaintenanceThread() { Deployer& deployer(Service::instance().deployer()); deployer.JoinMaintenanceThread(); } // deployment -RIME_API void RimeDeployerInitialize(RimeTraits* traits) { +RIME_API_DEPRECATED void RimeDeployerInitialize(RimeTraits* traits) { SetupDeployer(traits); LoadModules(PROVIDED(traits, modules) ? traits->modules : kDeployerModules); } -RIME_API Bool RimePrebuildAllSchemas() { - Deployer& deployer(Service::instance().deployer()); - return Bool(deployer.RunTask("prebuild_all_schemas")); -} - -RIME_API Bool RimeDeployWorkspace() { - Deployer& deployer(Service::instance().deployer()); - return Bool(deployer.RunTask("installation_update") && - deployer.RunTask("workspace_update") && - deployer.RunTask("user_dict_upgrade") && - deployer.RunTask("cleanup_trash")); -} - -RIME_API Bool RimeDeploySchema(const char* schema_file) { - Deployer& deployer(Service::instance().deployer()); - return Bool(deployer.RunTask("schema_update", path(schema_file))); -} - -RIME_API Bool RimeDeployConfigFile(const char* file_name, - const char* version_key) { - Deployer& deployer(Service::instance().deployer()); - TaskInitializer args(make_pair(file_name, version_key)); - return Bool(deployer.RunTask("config_file_update", args)); -} - -RIME_API Bool RimeSyncUserData() { - RimeCleanupAllSessions(); - Deployer& deployer(Service::instance().deployer()); - deployer.ScheduleTask("installation_update"); - deployer.ScheduleTask("backup_config_files"); - deployer.ScheduleTask("user_dict_sync"); - return Bool(deployer.StartMaintenance()); -} - // session management -RIME_API RimeSessionId RimeCreateSession() { +RIME_API_DEPRECATED RimeSessionId RimeCreateSession() { return Service::instance().CreateSession(); } -RIME_API Bool RimeFindSession(RimeSessionId session_id) { - return Bool(session_id && Service::instance().GetSession(session_id)); -} - -RIME_API Bool RimeDestroySession(RimeSessionId session_id) { - return Bool(Service::instance().DestroySession(session_id)); -} - -RIME_API void RimeCleanupStaleSessions() { +RIME_API_DEPRECATED void RimeCleanupStaleSessions() { Service::instance().CleanupStaleSessions(); } -RIME_API void RimeCleanupAllSessions() { +RIME_API_DEPRECATED void RimeCleanupAllSessions() { Service::instance().CleanupAllSessions(); } -// input - -RIME_API Bool RimeProcessKey(RimeSessionId session_id, int keycode, int mask) { - an session(Service::instance().GetSession(session_id)); - if (!session) - return False; - return Bool(session->ProcessKey(KeyEvent(keycode, mask))); -} - -RIME_API Bool RimeCommitComposition(RimeSessionId session_id) { - an session(Service::instance().GetSession(session_id)); - if (!session) - return False; - return Bool(session->CommitComposition()); -} - -RIME_API void RimeClearComposition(RimeSessionId session_id) { +RIME_API_DEPRECATED void RimeClearComposition(RimeSessionId session_id) { an session(Service::instance().GetSession(session_id)); if (!session) return; @@ -227,13 +161,13 @@ static void rime_candidate_copy(RimeCandidate* dest, const an& src) { dest->reserved = nullptr; } -RIME_API Bool RimeGetContext(RimeSessionId session_id, RimeContext* context) { +static bool get_context(RimeSessionId session_id, RimeContext* context) { if (!context || context->data_size <= 0) - return False; + return false; RIME_STRUCT_CLEAR(*context); an session(Service::instance().GetSession(session_id)); if (!session) - return False; + return false; Context* ctx = session->context(); if (!ctx) return False; @@ -295,12 +229,12 @@ RIME_API Bool RimeGetContext(RimeSessionId session_id, RimeContext* context) { } } } - return True; + return true; } -RIME_API Bool RimeFreeContext(RimeContext* context) { +static bool free_context(RimeContext* context) { if (!context || context->data_size <= 0) - return False; + return false; delete[] context->composition.preedit; for (int i = 0; i < context->menu.num_candidates; ++i) { delete[] context->menu.candidates[i].text; @@ -319,45 +253,45 @@ RIME_API Bool RimeFreeContext(RimeContext* context) { delete[] context->commit_text_preview; } RIME_STRUCT_CLEAR(*context); - return True; + return true; } -RIME_API Bool RimeGetCommit(RimeSessionId session_id, RimeCommit* commit) { +static bool get_commit(RimeSessionId session_id, RimeCommit* commit) { if (!commit) - return False; + return false; RIME_STRUCT_CLEAR(*commit); an session(Service::instance().GetSession(session_id)); if (!session) - return False; + return false; const string& commit_text(session->commit_text()); if (!commit_text.empty()) { commit->text = new char[commit_text.length() + 1]; std::strcpy(commit->text, commit_text.c_str()); session->ResetCommitText(); - return True; + return true; } - return False; + return false; } -RIME_API Bool RimeFreeCommit(RimeCommit* commit) { +static bool free_commit(RimeCommit* commit) { if (!commit) - return False; + return false; delete[] commit->text; RIME_STRUCT_CLEAR(*commit); - return True; + return true; } -RIME_API Bool RimeGetStatus(RimeSessionId session_id, RimeStatus* status) { +static bool get_status(RimeSessionId session_id, RimeStatus* status) { if (!status || status->data_size <= 0) - return False; + return false; RIME_STRUCT_CLEAR(*status); an session(Service::instance().GetSession(session_id)); if (!session) - return False; + return false; Schema* schema = session->schema(); Context* ctx = session->context(); if (!schema || !ctx) - return False; + return false; status->schema_id = new char[schema->schema_id().length() + 1]; std::strcpy(status->schema_id, schema->schema_id().c_str()); status->schema_name = new char[schema->schema_name().length() + 1]; @@ -369,59 +303,55 @@ RIME_API Bool RimeGetStatus(RimeSessionId session_id, RimeStatus* status) { status->is_simplified = Bool(ctx->get_option("simplification")); status->is_traditional = Bool(ctx->get_option("traditional")); status->is_ascii_punct = Bool(ctx->get_option("ascii_punct")); - return True; + return true; } -RIME_API Bool RimeFreeStatus(RimeStatus* status) { +static bool free_status(RimeStatus* status) { if (!status || status->data_size <= 0) - return False; + return false; delete[] status->schema_id; delete[] status->schema_name; RIME_STRUCT_CLEAR(*status); - return True; + return true; } -// Accessing candidate list +// accessing candidate list -RIME_API Bool RimeCandidateListFromIndex(RimeSessionId session_id, - RimeCandidateListIterator* iterator, - int index) { +static bool candidate_list_from_index(RimeSessionId session_id, + RimeCandidateListIterator* iterator, + int index) { if (!iterator) - return False; + return false; an session(Service::instance().GetSession(session_id)); if (!session) - return False; + return false; Context* ctx = session->context(); if (!ctx || !ctx->HasMenu()) - return False; + return false; memset(iterator, 0, sizeof(RimeCandidateListIterator)); iterator->ptr = ctx->composition().back().menu.get(); iterator->index = index - 1; - return True; -} - -RIME_API Bool RimeCandidateListBegin(RimeSessionId session_id, - RimeCandidateListIterator* iterator) { - return RimeCandidateListFromIndex(session_id, iterator, 0); + return true; } -RIME_API Bool RimeCandidateListNext(RimeCandidateListIterator* iterator) { +static bool candidate_list_next(RimeCandidateListIterator* iterator) { if (!iterator) - return False; + return false; Menu* menu = reinterpret_cast(iterator->ptr); if (!menu) - return False; + return false; ++iterator->index; if (auto cand = menu->GetCandidateAt((size_t)iterator->index)) { delete[] iterator->candidate.text; delete[] iterator->candidate.comment; rime_candidate_copy(&iterator->candidate, cand); - return True; + return true; } - return False; + return false; } -RIME_API void RimeCandidateListEnd(RimeCandidateListIterator* iterator) { +RIME_API_DEPRECATED void RimeCandidateListEnd( + RimeCandidateListIterator* iterator) { if (!iterator) return; delete[] iterator->candidate.text; @@ -429,33 +359,9 @@ RIME_API void RimeCandidateListEnd(RimeCandidateListIterator* iterator) { memset(iterator, 0, sizeof(RimeCandidateListIterator)); } -// runtime options - -RIME_API void RimeSetOption(RimeSessionId session_id, - const char* option, - Bool value) { - an session(Service::instance().GetSession(session_id)); - if (!session) - return; - Context* ctx = session->context(); - if (!ctx) - return; - ctx->set_option(option, !!value); -} - -RIME_API Bool RimeGetOption(RimeSessionId session_id, const char* option) { - an session(Service::instance().GetSession(session_id)); - if (!session) - return False; - Context* ctx = session->context(); - if (!ctx) - return False; - return Bool(ctx->get_option(option)); -} - -RIME_API void RimeSetProperty(RimeSessionId session_id, - const char* prop, - const char* value) { +RIME_API_DEPRECATED void RimeSetProperty(RimeSessionId session_id, + const char* prop, + const char* value) { an session(Service::instance().GetSession(session_id)); if (!session) return; @@ -465,35 +371,18 @@ RIME_API void RimeSetProperty(RimeSessionId session_id, ctx->set_property(prop, value); } -RIME_API Bool RimeGetProperty(RimeSessionId session_id, - const char* prop, - char* value, - size_t buffer_size) { - an session(Service::instance().GetSession(session_id)); - if (!session) - return False; - Context* ctx = session->context(); - if (!ctx) - return False; - string str_value(ctx->get_property(prop)); - if (str_value.empty()) - return False; - strncpy(value, str_value.c_str(), buffer_size); - return True; -} - -RIME_API Bool RimeGetSchemaList(RimeSchemaList* output) { +static bool get_schema_list(RimeSchemaList* output) { if (!output) - return False; + return false; output->size = 0; output->list = NULL; Schema default_schema; Config* config = default_schema.config(); if (!config) - return False; + return false; an schema_list = config->GetList("schema_list"); if (!schema_list || schema_list->size() == 0) - return False; + return false; output->list = new RimeSchemaListItem[schema_list->size()]; for (size_t i = 0; i < schema_list->size(); ++i) { an item = As(schema_list->GetAt(i)); @@ -515,12 +404,12 @@ RIME_API Bool RimeGetSchemaList(RimeSchemaList* output) { if (output->size == 0) { delete[] output->list; output->list = NULL; - return False; + return false; } - return True; + return true; } -RIME_API void RimeFreeSchemaList(RimeSchemaList* schema_list) { +RIME_API_DEPRECATED void RimeFreeSchemaList(RimeSchemaList* schema_list) { if (!schema_list) return; if (schema_list->list) { @@ -534,118 +423,25 @@ RIME_API void RimeFreeSchemaList(RimeSchemaList* schema_list) { schema_list->list = NULL; } -RIME_API Bool RimeGetCurrentSchema(RimeSessionId session_id, - char* schema_id, - size_t buffer_size) { - an session(Service::instance().GetSession(session_id)); - if (!session) - return False; - Schema* schema = session->schema(); - if (!schema) - return False; - strncpy(schema_id, schema->schema_id().c_str(), buffer_size); - return True; -} - -RIME_API Bool RimeSelectSchema(RimeSessionId session_id, - const char* schema_id) { - if (!schema_id) - return False; - an session(Service::instance().GetSession(session_id)); - if (!session) - return False; - session->ApplySchema(new Schema(schema_id)); - return True; -} - // config -static Bool open_config_in_component(const char* config_component, +static bool open_config_in_component(const char* config_component, const char* config_id, RimeConfig* config) { if (!config_id || !config) - return False; + return false; Config::Component* cc = Config::Require(config_component); if (!cc) - return False; + return false; Config* c = cc->Create(config_id); if (!c) - return False; + return false; config->ptr = (void*)c; - return True; -} - -RIME_API Bool RimeSchemaOpen(const char* schema_id, RimeConfig* config) { - return open_config_in_component("schema", schema_id, config); + return true; } -RIME_API Bool RimeConfigOpen(const char* config_id, RimeConfig* config) { - return open_config_in_component("config", config_id, config); -} - -RIME_API Bool RimeUserConfigOpen(const char* config_id, RimeConfig* config) { - return open_config_in_component("user_config", config_id, config); -} - -RIME_API Bool RimeConfigClose(RimeConfig* config) { - if (!config || !config->ptr) - return False; - Config* c = reinterpret_cast(config->ptr); - delete c; - config->ptr = NULL; - return True; -} - -RIME_API Bool RimeConfigGetBool(RimeConfig* config, - const char* key, - Bool* value) { - if (!config || !key || !value) - return False; - Config* c = reinterpret_cast(config->ptr); - bool bool_value = false; - if (c->GetBool(key, &bool_value)) { - *value = Bool(bool_value); - return True; - } - return False; -} - -RIME_API Bool RimeConfigGetInt(RimeConfig* config, - const char* key, - int* value) { - if (!config || !key || !value) - return False; - Config* c = reinterpret_cast(config->ptr); - return Bool(c->GetInt(key, value)); -} - -RIME_API Bool RimeConfigGetDouble(RimeConfig* config, - const char* key, - double* value) { - if (!config || !key || !value) - return False; - Config* c = reinterpret_cast(config->ptr); - return Bool(c->GetDouble(key, value)); -} - -RIME_API Bool RimeConfigGetString(RimeConfig* config, - const char* key, - char* value, - size_t buffer_size) { - if (!config || !key || !value) - return False; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - string str_value; - if (c->GetString(key, &str_value)) { - std::strncpy(value, str_value.c_str(), buffer_size); - return True; - } - return False; -} - -RIME_API const char* RimeConfigGetCString(RimeConfig* config, const char* key) { +RIME_API_DEPRECATED const char* RimeConfigGetCString(RimeConfig* config, + const char* key) { if (!config || !key) return NULL; Config* c = reinterpret_cast(config->ptr); @@ -657,16 +453,6 @@ RIME_API const char* RimeConfigGetCString(RimeConfig* config, const char* key) { return NULL; } -RIME_API Bool RimeConfigUpdateSignature(RimeConfig* config, - const char* signer) { - if (!config || !signer) - return False; - Config* c = reinterpret_cast(config->ptr); - Deployer& deployer(Service::instance().deployer()); - Signature sig(signer); - return Bool(sig.Sign(c, &deployer)); -} - template struct RimeConfigIteratorImpl { typename T::Iterator iter; @@ -684,85 +470,45 @@ struct RimeConfigIteratorImpl { } }; -RIME_API Bool RimeConfigBeginList(RimeConfigIterator* iterator, - RimeConfig* config, - const char* key) { - if (!iterator || !config || !key) - return False; - iterator->list = NULL; - iterator->map = NULL; - iterator->index = -1; - iterator->key = NULL; - iterator->path = NULL; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - an list = c->GetList(key); - if (!list) - return False; - iterator->list = new RimeConfigIteratorImpl(*list, key); - return True; -} - -RIME_API Bool RimeConfigBeginMap(RimeConfigIterator* iterator, - RimeConfig* config, - const char* key) { - if (!iterator || !config || !key) - return False; - iterator->list = NULL; - iterator->map = NULL; - iterator->index = -1; - iterator->key = NULL; - iterator->path = NULL; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - an m = c->GetMap(key); - if (!m) - return False; - iterator->map = new RimeConfigIteratorImpl(*m, key); - return True; -} - -RIME_API Bool RimeConfigNext(RimeConfigIterator* iterator) { +static bool config_next(RimeConfigIterator* iterator) { if (!iterator->list && !iterator->map) - return False; + return false; if (iterator->list) { RimeConfigIteratorImpl* p = reinterpret_cast*>(iterator->list); if (!p) - return False; + return false; if (++iterator->index > 0) ++p->iter; if (p->iter == p->end) - return False; + return false; std::ostringstream key; key << "@" << iterator->index; p->key = key.str(); p->path = p->prefix + p->key; iterator->key = p->key.c_str(); iterator->path = p->path.c_str(); - return True; + return true; } if (iterator->map) { RimeConfigIteratorImpl* p = reinterpret_cast*>(iterator->map); if (!p) - return False; + return false; if (++iterator->index > 0) ++p->iter; if (p->iter == p->end) - return False; + return false; p->key = p->iter->first; p->path = p->prefix + p->key; iterator->key = p->key.c_str(); iterator->path = p->path.c_str(); - return True; + return true; } - return False; + return false; } -RIME_API void RimeConfigEnd(RimeConfigIterator* iterator) { +RIME_API_DEPRECATED void RimeConfigEnd(RimeConfigIterator* iterator) { if (!iterator) return; if (iterator->list) @@ -773,82 +519,51 @@ RIME_API void RimeConfigEnd(RimeConfigIterator* iterator) { memset(iterator, 0, sizeof(RimeConfigIterator)); } -RIME_API Bool RimeSimulateKeySequence(RimeSessionId session_id, - const char* key_sequence) { - LOG(INFO) << "simulate key sequence: " << key_sequence; - an session(Service::instance().GetSession(session_id)); - if (!session) - return False; - KeySequence keys; - if (!keys.Parse(key_sequence)) { - LOG(ERROR) << "error parsing input: '" << key_sequence << "'"; - return False; - } - for (const KeyEvent& key : keys) { - session->ProcessKey(key); - } - return True; -} - -RIME_API Bool RimeRegisterModule(RimeModule* module) { - if (!module || !module->module_name) - return False; - ModuleManager::instance().Register(module->module_name, module); - return True; -} - -RIME_API RimeModule* RimeFindModule(const char* module_name) { +RIME_API_DEPRECATED RimeModule* RimeFindModule(const char* module_name) { return ModuleManager::instance().Find(module_name); } -RIME_API Bool RimeRunTask(const char* task_name) { - if (!task_name) - return False; - Deployer& deployer(Service::instance().deployer()); - return Bool(deployer.RunTask(task_name)); -} - -RIME_API const char* RimeGetSharedDataDir() { +RIME_API_DEPRECATED const char* RimeGetSharedDataDir() { Deployer& deployer(Service::instance().deployer()); static string string_path; string_path = deployer.shared_data_dir.string(); return string_path.c_str(); } -RIME_API const char* RimeGetUserDataDir() { +RIME_API_DEPRECATED const char* RimeGetUserDataDir() { Deployer& deployer(Service::instance().deployer()); static string string_path; string_path = deployer.user_data_dir.string(); return string_path.c_str(); } -RIME_API const char* RimeGetPrebuiltDataDir() { +RIME_API_DEPRECATED const char* RimeGetPrebuiltDataDir() { Deployer& deployer(Service::instance().deployer()); static string string_path; string_path = deployer.prebuilt_data_dir.string(); return string_path.c_str(); } -RIME_API const char* RimeGetStagingDir() { +RIME_API_DEPRECATED const char* RimeGetStagingDir() { Deployer& deployer(Service::instance().deployer()); static string string_path; string_path = deployer.staging_dir.string(); return string_path.c_str(); } -RIME_API const char* RimeGetSyncDir() { +RIME_API_DEPRECATED const char* RimeGetSyncDir() { Deployer& deployer(Service::instance().deployer()); static string string_path; string_path = deployer.sync_dir.string(); return string_path.c_str(); } -RIME_API const char* RimeGetUserId() { +RIME_API_DEPRECATED const char* RimeGetUserId() { Deployer& deployer(Service::instance().deployer()); return deployer.user_id.c_str(); } -RIME_API void RimeGetUserDataSyncDir(char* dir, size_t buffer_size) { +RIME_API_DEPRECATED void RimeGetUserDataSyncDir(char* dir, size_t buffer_size) { Deployer& deployer(Service::instance().deployer()); string string_path = deployer.user_data_sync_dir().string(); strncpy(dir, string_path.c_str(), buffer_size); @@ -880,128 +595,8 @@ void RimeGetSyncDirSecure(char* dir, size_t buffer_size) { strncpy(dir, string_path.c_str(), buffer_size); } -RIME_API Bool RimeConfigInit(RimeConfig* config) { - if (!config || config->ptr) - return False; - config->ptr = (void*)new Config; - return True; -} - -RIME_API Bool RimeConfigLoadString(RimeConfig* config, const char* yaml) { - if (!config || !yaml) { - return False; - } - if (!config->ptr) { - RimeConfigInit(config); - } - Config* c = reinterpret_cast(config->ptr); - std::istringstream iss(yaml); - return Bool(c->LoadFromStream(iss)); -} - -RIME_API Bool RimeConfigGetItem(RimeConfig* config, - const char* key, - RimeConfig* value) { - if (!config || !key || !value) - return False; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - if (!value->ptr) { - RimeConfigInit(value); - } - Config* v = reinterpret_cast(value->ptr); - *v = c->GetItem(key); - return True; -} - -RIME_API Bool RimeConfigSetItem(RimeConfig* config, - const char* key, - RimeConfig* value) { - if (!config || !key) - return False; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - an item; - if (value) { - if (Config* v = reinterpret_cast(value->ptr)) { - item = v->GetItem(""); - } - } - return Bool(c->SetItem(key, item)); -} - -RIME_API Bool RimeConfigSetBool(RimeConfig* config, - const char* key, - Bool value) { - if (!config || !key) - return False; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - return c->SetBool(key, value != False); -} - -RIME_API Bool RimeConfigSetInt(RimeConfig* config, const char* key, int value) { - if (!config || !key) - return False; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - return Bool(c->SetInt(key, value)); -} - -RIME_API Bool RimeConfigSetDouble(RimeConfig* config, - const char* key, - double value) { - if (!config || !key) - return False; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - return Bool(c->SetDouble(key, value)); -} - -RIME_API Bool RimeConfigSetString(RimeConfig* config, - const char* key, - const char* value) { - if (!config || !key || !value) - return False; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - return Bool(c->SetString(key, value)); -} - -RIME_API Bool RimeConfigClear(RimeConfig* config, const char* key) { - if (!config || !key) - return False; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - return Bool(c->SetItem(key, nullptr)); -} - -RIME_API Bool RimeConfigCreateList(RimeConfig* config, const char* key) { - if (!config || !key) - return False; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - return Bool(c->SetItem(key, New())); -} - -RIME_API Bool RimeConfigCreateMap(RimeConfig* config, const char* key) { - if (!config || !key) - return False; - Config* c = reinterpret_cast(config->ptr); - if (!c) - return False; - return Bool(c->SetItem(key, New())); -} - -RIME_API size_t RimeConfigListSize(RimeConfig* config, const char* key) { +RIME_API_DEPRECATED size_t RimeConfigListSize(RimeConfig* config, + const char* key) { if (!config || !key) return 0; Config* c = reinterpret_cast(config->ptr); @@ -1038,10 +633,10 @@ static bool do_with_candidate(RimeSessionId session_id, bool (Context::*verb)(size_t index)) { an session(Service::instance().GetSession(session_id)); if (!session) - return False; + return false; Context* ctx = session->context(); if (!ctx) - return False; + return false; return (ctx->*verb)(index); } @@ -1051,31 +646,31 @@ static bool do_with_candidate_on_current_page( bool (Context::*verb)(size_t index)) { an session(Service::instance().GetSession(session_id)); if (!session) - return False; + return false; Context* ctx = session->context(); if (!ctx || !ctx->HasMenu()) - return False; + return false; Schema* schema = session->schema(); if (!schema) - return False; + return false; size_t page_size = (size_t)schema->page_size(); if (index >= page_size) - return False; + return false; const auto& seg(ctx->composition().back()); size_t page_start = seg.selected_index / page_size * page_size; return (ctx->*verb)(page_start + index); } -Bool RimeChangePage(RimeSessionId session_id, Bool backward) { +static bool change_page(RimeSessionId session_id, bool backward) { an session(Service::instance().GetSession(session_id)); if (!session) - return False; + return false; Context* ctx = session->context(); if (!ctx || !ctx->HasMenu()) - return False; + return false; Schema* schema = session->schema(); if (!schema) - return False; + return false; size_t page_size = (size_t)schema->page_size(); auto& seg(ctx->composition().back()); size_t current_index = seg.selected_index; @@ -1089,39 +684,10 @@ Bool RimeChangePage(RimeSessionId session_id, Bool backward) { return ctx->Highlight(index); } -Bool RimeHighlightCandidate(RimeSessionId session_id, size_t index) { - return do_with_candidate(session_id, index, &Context::Highlight); -} - -Bool RimeHighlightCandidateOnCurrentPage(RimeSessionId session_id, - size_t index) { - return do_with_candidate_on_current_page(session_id, index, - &Context::Highlight); -} - -RIME_API Bool RimeSelectCandidate(RimeSessionId session_id, size_t index) { - return do_with_candidate(session_id, index, &Context::Select); -} - -RIME_API Bool RimeSelectCandidateOnCurrentPage(RimeSessionId session_id, - size_t index) { - return do_with_candidate_on_current_page(session_id, index, &Context::Select); -} - const char* RimeGetVersion() { return RIME_VERSION; } -RIME_API Bool RimeDeleteCandidate(RimeSessionId session_id, size_t index) { - return do_with_candidate(session_id, index, &Context::DeleteCandidate); -} - -RIME_API Bool RimeDeleteCandidateOnCurrentPage(RimeSessionId session_id, - size_t index) { - return do_with_candidate_on_current_page(session_id, index, - &Context::DeleteCandidate); -} - void RimeSetCaretPos(RimeSessionId session_id, size_t caret_pos) { an session(Service::instance().GetSession(session_id)); if (!session) @@ -1132,10 +698,10 @@ void RimeSetCaretPos(RimeSessionId session_id, size_t caret_pos) { return ctx->set_caret_pos(caret_pos); } -RimeStringSlice RimeGetStateLabelAbbreviated(RimeSessionId session_id, - const char* option_name, - Bool state, - Bool abbreviated) { +static RimeStringSlice get_state_label_abbreviated(RimeSessionId session_id, + const char* option_name, + bool state, + bool abbreviated) { an session(Service::instance().GetSession(session_id)); if (!session) return {nullptr, 0}; @@ -1147,127 +713,10 @@ RimeStringSlice RimeGetStateLabelAbbreviated(RimeSessionId session_id, return {label.str, label.length}; } -const char* RimeGetStateLabel(RimeSessionId session_id, - const char* option_name, - Bool state) { - return RimeGetStateLabelAbbreviated(session_id, option_name, state, False) - .str; -} - -RIME_API Bool RimeSetInput(RimeSessionId session_id, const char* input) { - an session(Service::instance().GetSession(session_id)); - if (!session) - return False; - Context* ctx = session->context(); - if (!ctx) - return False; - ctx->set_input(input); - return True; -} +#include "rime_api_impl.h" -RIME_API RimeApi* rime_get_api() { - static RimeApi s_api = {0}; - if (!s_api.data_size) { - RIME_STRUCT_INIT(RimeApi, s_api); - s_api.setup = &RimeSetup; - s_api.set_notification_handler = &RimeSetNotificationHandler; - s_api.initialize = &RimeInitialize; - s_api.finalize = &RimeFinalize; - s_api.start_maintenance = &RimeStartMaintenance; - s_api.is_maintenance_mode = &RimeIsMaintenancing; - s_api.join_maintenance_thread = &RimeJoinMaintenanceThread; - s_api.deployer_initialize = &RimeDeployerInitialize; - s_api.prebuild = &RimePrebuildAllSchemas; - s_api.deploy = &RimeDeployWorkspace; - s_api.deploy_schema = &RimeDeploySchema; - s_api.deploy_config_file = &RimeDeployConfigFile; - s_api.sync_user_data = &RimeSyncUserData; - s_api.create_session = &RimeCreateSession; - s_api.find_session = &RimeFindSession; - s_api.destroy_session = &RimeDestroySession; - s_api.cleanup_stale_sessions = &RimeCleanupStaleSessions; - s_api.cleanup_all_sessions = &RimeCleanupAllSessions; - s_api.process_key = &RimeProcessKey; - s_api.commit_composition = &RimeCommitComposition; - s_api.clear_composition = &RimeClearComposition; - s_api.get_commit = &RimeGetCommit; - s_api.free_commit = &RimeFreeCommit; - s_api.get_context = &RimeGetContext; - s_api.free_context = &RimeFreeContext; - s_api.get_status = &RimeGetStatus; - s_api.free_status = &RimeFreeStatus; - s_api.set_option = &RimeSetOption; - s_api.get_option = &RimeGetOption; - s_api.set_property = &RimeSetProperty; - s_api.get_property = &RimeGetProperty; - s_api.get_schema_list = &RimeGetSchemaList; - s_api.free_schema_list = &RimeFreeSchemaList; - s_api.get_current_schema = &RimeGetCurrentSchema; - s_api.select_schema = &RimeSelectSchema; - s_api.schema_open = &RimeSchemaOpen; - s_api.config_open = &RimeConfigOpen; - s_api.user_config_open = &RimeUserConfigOpen; - s_api.config_close = &RimeConfigClose; - s_api.config_get_bool = &RimeConfigGetBool; - s_api.config_get_int = &RimeConfigGetInt; - s_api.config_get_double = &RimeConfigGetDouble; - s_api.config_get_string = &RimeConfigGetString; - s_api.config_get_cstring = &RimeConfigGetCString; - s_api.config_update_signature = &RimeConfigUpdateSignature; - s_api.config_begin_map = &RimeConfigBeginMap; - s_api.config_next = &RimeConfigNext; - s_api.config_end = &RimeConfigEnd; - s_api.simulate_key_sequence = &RimeSimulateKeySequence; - s_api.register_module = &RimeRegisterModule; - s_api.find_module = &RimeFindModule; - s_api.run_task = &RimeRunTask; - s_api.get_shared_data_dir = &RimeGetSharedDataDir; - s_api.get_user_data_dir = &RimeGetUserDataDir; - s_api.get_sync_dir = &RimeGetSyncDir; - s_api.get_user_id = &RimeGetUserId; - s_api.get_user_data_sync_dir = &RimeGetUserDataSyncDir; - s_api.config_init = &RimeConfigInit; - s_api.config_load_string = &RimeConfigLoadString; - s_api.config_set_bool = &RimeConfigSetBool; - s_api.config_set_int = &RimeConfigSetInt; - s_api.config_set_double = &RimeConfigSetDouble; - s_api.config_set_string = &RimeConfigSetString; - s_api.config_get_item = &RimeConfigGetItem; - s_api.config_set_item = &RimeConfigSetItem; - s_api.config_clear = &RimeConfigClear; - s_api.config_create_list = &RimeConfigCreateList; - s_api.config_create_map = &RimeConfigCreateMap; - s_api.config_list_size = &RimeConfigListSize; - s_api.config_begin_list = &RimeConfigBeginList; - s_api.get_input = &RimeGetInput; - s_api.get_caret_pos = &RimeGetCaretPos; - s_api.select_candidate = &RimeSelectCandidate; - s_api.get_version = &RimeGetVersion; - s_api.set_caret_pos = &RimeSetCaretPos; - s_api.select_candidate_on_current_page = &RimeSelectCandidateOnCurrentPage; - s_api.candidate_list_begin = &RimeCandidateListBegin; - s_api.candidate_list_next = &RimeCandidateListNext; - s_api.candidate_list_end = &RimeCandidateListEnd; - s_api.candidate_list_from_index = &RimeCandidateListFromIndex; - s_api.get_prebuilt_data_dir = &RimeGetPrebuiltDataDir; - s_api.get_staging_dir = &RimeGetStagingDir; - s_api.commit_proto = nullptr; - s_api.context_proto = nullptr; - s_api.status_proto = nullptr; - s_api.get_state_label = &RimeGetStateLabel; - s_api.delete_candidate = &RimeDeleteCandidate; - s_api.delete_candidate_on_current_page = &RimeDeleteCandidateOnCurrentPage; - s_api.get_state_label_abbreviated = &RimeGetStateLabelAbbreviated; - s_api.set_input = &RimeSetInput; - s_api.get_shared_data_dir_s = &RimeGetSharedDataDirSecure; - s_api.get_user_data_dir_s = &RimeGetUserDataDirSecure; - s_api.get_prebuilt_data_dir_s = &RimeGetPrebuiltDataDirSecure; - s_api.get_staging_dir_s = &RimeGetStagingDirSecure; - s_api.get_sync_dir_s = &RimeGetSyncDirSecure; - s_api.highlight_candidate = &RimeHighlightCandidate; - s_api.highlight_candidate_on_current_page = - &RimeHighlightCandidateOnCurrentPage; - s_api.change_page = &RimeChangePage; - } - return &s_api; -} +#undef RIME_API_FLAVORED +#undef RIME_API_DEPRECATED +#undef Bool +#include "rime_api_stdbool.h" +#include "rime_api_impl.h" diff --git a/src/rime_api.h b/src/rime_api.h index 44b2ea3f6b..7b8d152415 100644 --- a/src/rime_api.h +++ b/src/rime_api.h @@ -30,17 +30,28 @@ extern "C" { #define RIME_API #endif /* _WIN32 */ -typedef uintptr_t RimeSessionId; +#ifndef RIME_API_DEPRECATED +#define RIME_API_DEPRECATED RIME_API +#endif + +#ifndef RIME_API_FLAVORED +#define RIME_API_FLAVORED(name) name +#endif -typedef int Bool; +#ifndef Bool +#define Bool int +#endif #ifndef False #define False 0 #endif + #ifndef True #define True 1 #endif +typedef uintptr_t RimeSessionId; + //! Define the max number of candidates /*! * \deprecated There is no limit to the number of candidates in RimeMenu @@ -210,7 +221,7 @@ typedef struct rime_string_slice_t { /*! * Call this function before accessing any other API. */ -RIME_API void RimeSetup(RimeTraits* traits); +RIME_API_DEPRECATED void RimeSetup(RimeTraits* traits); /*! * Pass a C-string constant in the format "rime.x" @@ -218,7 +229,7 @@ RIME_API void RimeSetup(RimeTraits* traits); * Add prefix "rime." to ensure old log files are automatically cleaned. * \deprecated Use RimeSetup() instead. */ -RIME_API void RimeSetupLogging(const char* app_name); +RIME_API_DEPRECATED void RimeSetupLogging(const char* app_name); //! Receive notifications /*! @@ -236,158 +247,186 @@ RIME_API void RimeSetupLogging(const char* app_name); * every time an event occurs in librime, until RimeFinalize() is called. * when handler is NULL, notification is disabled. */ -RIME_API void RimeSetNotificationHandler(RimeNotificationHandler handler, - void* context_object); +RIME_API_DEPRECATED void RimeSetNotificationHandler( + RimeNotificationHandler handler, + void* context_object); // Entry and exit -RIME_API void RimeInitialize(RimeTraits* traits); -RIME_API void RimeFinalize(void); +RIME_API_DEPRECATED void RimeInitialize(RimeTraits* traits); +RIME_API_DEPRECATED void RimeFinalize(void); -RIME_API Bool RimeStartMaintenance(Bool full_check); +RIME_API_DEPRECATED Bool RimeStartMaintenance(Bool full_check); //! \deprecated Use RimeStartMaintenance(full_check = False) instead. -RIME_API Bool RimeStartMaintenanceOnWorkspaceChange(void); -RIME_API Bool RimeIsMaintenancing(void); -RIME_API void RimeJoinMaintenanceThread(void); +RIME_API_DEPRECATED Bool RimeStartMaintenanceOnWorkspaceChange(void); +RIME_API_DEPRECATED Bool RimeIsMaintenancing(void); +RIME_API_DEPRECATED void RimeJoinMaintenanceThread(void); // Deployment -RIME_API void RimeDeployerInitialize(RimeTraits* traits); -RIME_API Bool RimePrebuildAllSchemas(void); -RIME_API Bool RimeDeployWorkspace(void); -RIME_API Bool RimeDeploySchema(const char* schema_file); -RIME_API Bool RimeDeployConfigFile(const char* file_name, - const char* version_key); +RIME_API_DEPRECATED void RimeDeployerInitialize(RimeTraits* traits); +RIME_API_DEPRECATED Bool RimePrebuildAllSchemas(void); +RIME_API_DEPRECATED Bool RimeDeployWorkspace(void); +RIME_API_DEPRECATED Bool RimeDeploySchema(const char* schema_file); +RIME_API_DEPRECATED Bool RimeDeployConfigFile(const char* file_name, + const char* version_key); -RIME_API Bool RimeSyncUserData(void); +RIME_API_DEPRECATED Bool RimeSyncUserData(void); // Session management -RIME_API RimeSessionId RimeCreateSession(void); -RIME_API Bool RimeFindSession(RimeSessionId session_id); -RIME_API Bool RimeDestroySession(RimeSessionId session_id); -RIME_API void RimeCleanupStaleSessions(void); -RIME_API void RimeCleanupAllSessions(void); +RIME_API_DEPRECATED RimeSessionId RimeCreateSession(void); +RIME_API_DEPRECATED Bool RimeFindSession(RimeSessionId session_id); +RIME_API_DEPRECATED Bool RimeDestroySession(RimeSessionId session_id); +RIME_API_DEPRECATED void RimeCleanupStaleSessions(void); +RIME_API_DEPRECATED void RimeCleanupAllSessions(void); // Input -RIME_API Bool RimeProcessKey(RimeSessionId session_id, int keycode, int mask); +RIME_API_DEPRECATED Bool RimeProcessKey(RimeSessionId session_id, + int keycode, + int mask); /*! * return True if there is unread commit text */ -RIME_API Bool RimeCommitComposition(RimeSessionId session_id); -RIME_API void RimeClearComposition(RimeSessionId session_id); +RIME_API_DEPRECATED Bool RimeCommitComposition(RimeSessionId session_id); +RIME_API_DEPRECATED void RimeClearComposition(RimeSessionId session_id); // Output -RIME_API Bool RimeGetCommit(RimeSessionId session_id, RimeCommit* commit); -RIME_API Bool RimeFreeCommit(RimeCommit* commit); -RIME_API Bool RimeGetContext(RimeSessionId session_id, RimeContext* context); -RIME_API Bool RimeFreeContext(RimeContext* context); -RIME_API Bool RimeGetStatus(RimeSessionId session_id, RimeStatus* status); -RIME_API Bool RimeFreeStatus(RimeStatus* status); +RIME_API_DEPRECATED Bool RimeGetCommit(RimeSessionId session_id, + RimeCommit* commit); +RIME_API_DEPRECATED Bool RimeFreeCommit(RimeCommit* commit); +RIME_API_DEPRECATED Bool RimeGetContext(RimeSessionId session_id, + RimeContext* context); +RIME_API_DEPRECATED Bool RimeFreeContext(RimeContext* context); +RIME_API_DEPRECATED Bool RimeGetStatus(RimeSessionId session_id, + RimeStatus* status); +RIME_API_DEPRECATED Bool RimeFreeStatus(RimeStatus* status); // Accessing candidate list -RIME_API Bool RimeCandidateListBegin(RimeSessionId session_id, - RimeCandidateListIterator* iterator); -RIME_API Bool RimeCandidateListNext(RimeCandidateListIterator* iterator); -RIME_API void RimeCandidateListEnd(RimeCandidateListIterator* iterator); -RIME_API Bool RimeCandidateListFromIndex(RimeSessionId session_id, - RimeCandidateListIterator* iterator, - int index); -RIME_API Bool RimeSelectCandidate(RimeSessionId session_id, size_t index); -RIME_API Bool RimeSelectCandidateOnCurrentPage(RimeSessionId session_id, - size_t index); -RIME_API Bool RimeDeleteCandidate(RimeSessionId session_id, size_t index); -RIME_API Bool RimeDeleteCandidateOnCurrentPage(RimeSessionId session_id, - size_t index); +RIME_API_DEPRECATED Bool +RimeCandidateListBegin(RimeSessionId session_id, + RimeCandidateListIterator* iterator); +RIME_API_DEPRECATED Bool +RimeCandidateListNext(RimeCandidateListIterator* iterator); +RIME_API_DEPRECATED void RimeCandidateListEnd( + RimeCandidateListIterator* iterator); +RIME_API_DEPRECATED Bool +RimeCandidateListFromIndex(RimeSessionId session_id, + RimeCandidateListIterator* iterator, + int index); +RIME_API_DEPRECATED Bool RimeSelectCandidate(RimeSessionId session_id, + size_t index); +RIME_API_DEPRECATED Bool +RimeSelectCandidateOnCurrentPage(RimeSessionId session_id, size_t index); +RIME_API_DEPRECATED Bool RimeDeleteCandidate(RimeSessionId session_id, + size_t index); +RIME_API_DEPRECATED Bool +RimeDeleteCandidateOnCurrentPage(RimeSessionId session_id, size_t index); // Runtime options -RIME_API void RimeSetOption(RimeSessionId session_id, - const char* option, - Bool value); -RIME_API Bool RimeGetOption(RimeSessionId session_id, const char* option); - -RIME_API void RimeSetProperty(RimeSessionId session_id, - const char* prop, - const char* value); -RIME_API Bool RimeGetProperty(RimeSessionId session_id, - const char* prop, - char* value, - size_t buffer_size); - -RIME_API Bool RimeGetSchemaList(RimeSchemaList* schema_list); -RIME_API void RimeFreeSchemaList(RimeSchemaList* schema_list); -RIME_API Bool RimeGetCurrentSchema(RimeSessionId session_id, - char* schema_id, - size_t buffer_size); -RIME_API Bool RimeSelectSchema(RimeSessionId session_id, const char* schema_id); +RIME_API_DEPRECATED void RimeSetOption(RimeSessionId session_id, + const char* option, + Bool value); +RIME_API_DEPRECATED Bool RimeGetOption(RimeSessionId session_id, + const char* option); + +RIME_API_DEPRECATED void RimeSetProperty(RimeSessionId session_id, + const char* prop, + const char* value); +RIME_API_DEPRECATED Bool RimeGetProperty(RimeSessionId session_id, + const char* prop, + char* value, + size_t buffer_size); + +RIME_API_DEPRECATED Bool RimeGetSchemaList(RimeSchemaList* schema_list); +RIME_API_DEPRECATED void RimeFreeSchemaList(RimeSchemaList* schema_list); +RIME_API_DEPRECATED Bool RimeGetCurrentSchema(RimeSessionId session_id, + char* schema_id, + size_t buffer_size); +RIME_API_DEPRECATED Bool RimeSelectSchema(RimeSessionId session_id, + const char* schema_id); // Configuration // .schema.yaml -RIME_API Bool RimeSchemaOpen(const char* schema_id, RimeConfig* config); +RIME_API_DEPRECATED Bool RimeSchemaOpen(const char* schema_id, + RimeConfig* config); // .yaml -RIME_API Bool RimeConfigOpen(const char* config_id, RimeConfig* config); +RIME_API_DEPRECATED Bool RimeConfigOpen(const char* config_id, + RimeConfig* config); // access config files in user data directory, eg. user.yaml and // installation.yaml -RIME_API Bool RimeUserConfigOpen(const char* config_id, RimeConfig* config); -RIME_API Bool RimeConfigClose(RimeConfig* config); -RIME_API Bool RimeConfigInit(RimeConfig* config); -RIME_API Bool RimeConfigLoadString(RimeConfig* config, const char* yaml); +RIME_API_DEPRECATED Bool RimeUserConfigOpen(const char* config_id, + RimeConfig* config); +RIME_API_DEPRECATED Bool RimeConfigClose(RimeConfig* config); +RIME_API_DEPRECATED Bool RimeConfigInit(RimeConfig* config); +RIME_API_DEPRECATED Bool RimeConfigLoadString(RimeConfig* config, + const char* yaml); // Access config values -RIME_API Bool RimeConfigGetBool(RimeConfig* config, - const char* key, - Bool* value); -RIME_API Bool RimeConfigGetInt(RimeConfig* config, const char* key, int* value); -RIME_API Bool RimeConfigGetDouble(RimeConfig* config, - const char* key, - double* value); -RIME_API Bool RimeConfigGetString(RimeConfig* config, - const char* key, - char* value, - size_t buffer_size); -RIME_API const char* RimeConfigGetCString(RimeConfig* config, const char* key); -RIME_API Bool RimeConfigSetBool(RimeConfig* config, - const char* key, - Bool value); -RIME_API Bool RimeConfigSetInt(RimeConfig* config, const char* key, int value); -RIME_API Bool RimeConfigSetDouble(RimeConfig* config, - const char* key, - double value); -RIME_API Bool RimeConfigSetString(RimeConfig* config, - const char* key, - const char* value); +RIME_API_DEPRECATED Bool RimeConfigGetBool(RimeConfig* config, + const char* key, + Bool* value); +RIME_API_DEPRECATED Bool RimeConfigGetInt(RimeConfig* config, + const char* key, + int* value); +RIME_API_DEPRECATED Bool RimeConfigGetDouble(RimeConfig* config, + const char* key, + double* value); +RIME_API_DEPRECATED Bool RimeConfigGetString(RimeConfig* config, + const char* key, + char* value, + size_t buffer_size); +RIME_API_DEPRECATED const char* RimeConfigGetCString(RimeConfig* config, + const char* key); +RIME_API_DEPRECATED Bool RimeConfigSetBool(RimeConfig* config, + const char* key, + Bool value); +RIME_API_DEPRECATED Bool RimeConfigSetInt(RimeConfig* config, + const char* key, + int value); +RIME_API_DEPRECATED Bool RimeConfigSetDouble(RimeConfig* config, + const char* key, + double value); +RIME_API_DEPRECATED Bool RimeConfigSetString(RimeConfig* config, + const char* key, + const char* value); // Manipulate complex structures -RIME_API Bool RimeConfigGetItem(RimeConfig* config, - const char* key, - RimeConfig* value); -RIME_API Bool RimeConfigSetItem(RimeConfig* config, - const char* key, - RimeConfig* value); -RIME_API Bool RimeConfigClear(RimeConfig* config, const char* key); -RIME_API Bool RimeConfigCreateList(RimeConfig* config, const char* key); -RIME_API Bool RimeConfigCreateMap(RimeConfig* config, const char* key); -RIME_API size_t RimeConfigListSize(RimeConfig* config, const char* key); -RIME_API Bool RimeConfigBeginList(RimeConfigIterator* iterator, - RimeConfig* config, - const char* key); -RIME_API Bool RimeConfigBeginMap(RimeConfigIterator* iterator, - RimeConfig* config, - const char* key); -RIME_API Bool RimeConfigNext(RimeConfigIterator* iterator); -RIME_API void RimeConfigEnd(RimeConfigIterator* iterator); +RIME_API_DEPRECATED Bool RimeConfigGetItem(RimeConfig* config, + const char* key, + RimeConfig* value); +RIME_API_DEPRECATED Bool RimeConfigSetItem(RimeConfig* config, + const char* key, + RimeConfig* value); +RIME_API_DEPRECATED Bool RimeConfigClear(RimeConfig* config, const char* key); +RIME_API_DEPRECATED Bool RimeConfigCreateList(RimeConfig* config, + const char* key); +RIME_API_DEPRECATED Bool RimeConfigCreateMap(RimeConfig* config, + const char* key); +RIME_API_DEPRECATED size_t RimeConfigListSize(RimeConfig* config, + const char* key); +RIME_API_DEPRECATED Bool RimeConfigBeginList(RimeConfigIterator* iterator, + RimeConfig* config, + const char* key); +RIME_API_DEPRECATED Bool RimeConfigBeginMap(RimeConfigIterator* iterator, + RimeConfig* config, + const char* key); +RIME_API_DEPRECATED Bool RimeConfigNext(RimeConfigIterator* iterator); +RIME_API_DEPRECATED void RimeConfigEnd(RimeConfigIterator* iterator); // Utilities -RIME_API Bool RimeConfigUpdateSignature(RimeConfig* config, const char* signer); +RIME_API_DEPRECATED Bool RimeConfigUpdateSignature(RimeConfig* config, + const char* signer); // Testing -RIME_API Bool RimeSimulateKeySequence(RimeSessionId session_id, - const char* key_sequence); +RIME_API_DEPRECATED Bool RimeSimulateKeySequence(RimeSessionId session_id, + const char* key_sequence); -RIME_API Bool RimeSetInput(RimeSessionId session_id, const char* input); +RIME_API_DEPRECATED Bool RimeSetInput(RimeSessionId session_id, + const char* input); // Module /*! @@ -407,278 +446,22 @@ typedef struct rime_module_t { RimeCustomApi* (*get_api)(void); } RimeModule; -RIME_API Bool RimeRegisterModule(RimeModule* module); -RIME_API RimeModule* RimeFindModule(const char* module_name); +RIME_API_DEPRECATED Bool RimeRegisterModule(RimeModule* module); +RIME_API_DEPRECATED RimeModule* RimeFindModule(const char* module_name); //! Run a registered task -RIME_API Bool RimeRunTask(const char* task_name); +RIME_API_DEPRECATED Bool RimeRunTask(const char* task_name); //! \deprecated use RimeApi::get_shared_data_dir_s instead. -RIME_API const char* RimeGetSharedDataDir(void); +RIME_API_DEPRECATED const char* RimeGetSharedDataDir(void); //! \deprecated use RimeApi::get_user_data_dir_s instead. -RIME_API const char* RimeGetUserDataDir(void); +RIME_API_DEPRECATED const char* RimeGetUserDataDir(void); //! \deprecated use RimeApi::get_sync_dir_s instead. -RIME_API const char* RimeGetSyncDir(void); - -RIME_API const char* RimeGetUserId(void); - -/*! The API structure - * RimeApi is for rime v1.0+ - */ -typedef struct rime_api_t { - int data_size; - - /*! setup - * Call this function before accessing any other API functions. - */ - void (*setup)(RimeTraits* traits); - - /*! Set up the notification callbacks - * Receive notifications - * - on loading schema: - * + message_type="schema", message_value="luna_pinyin/Luna Pinyin" - * - on changing mode: - * + message_type="option", message_value="ascii_mode" - * + message_type="option", message_value="!ascii_mode" - * - on deployment: - * + session_id = 0, message_type="deploy", message_value="start" - * + session_id = 0, message_type="deploy", message_value="success" - * + session_id = 0, message_type="deploy", message_value="failure" - * - * handler will be called with context_object as the first parameter - * every time an event occurs in librime, until RimeFinalize() is called. - * when handler is NULL, notification is disabled. - */ - void (*set_notification_handler)(RimeNotificationHandler handler, - void* context_object); - - // entry and exit - - void (*initialize)(RimeTraits* traits); - void (*finalize)(void); - - Bool (*start_maintenance)(Bool full_check); - Bool (*is_maintenance_mode)(void); - void (*join_maintenance_thread)(void); - - // deployment - - void (*deployer_initialize)(RimeTraits* traits); - Bool (*prebuild)(void); - Bool (*deploy)(void); - Bool (*deploy_schema)(const char* schema_file); - Bool (*deploy_config_file)(const char* file_name, const char* version_key); - - Bool (*sync_user_data)(void); - - // session management +RIME_API_DEPRECATED const char* RimeGetSyncDir(void); - RimeSessionId (*create_session)(void); - Bool (*find_session)(RimeSessionId session_id); - Bool (*destroy_session)(RimeSessionId session_id); - void (*cleanup_stale_sessions)(void); - void (*cleanup_all_sessions)(void); +RIME_API_DEPRECATED const char* RimeGetUserId(void); - // input - - Bool (*process_key)(RimeSessionId session_id, int keycode, int mask); - // return True if there is unread commit text - Bool (*commit_composition)(RimeSessionId session_id); - void (*clear_composition)(RimeSessionId session_id); - - // output - - Bool (*get_commit)(RimeSessionId session_id, RimeCommit* commit); - Bool (*free_commit)(RimeCommit* commit); - Bool (*get_context)(RimeSessionId session_id, RimeContext* context); - Bool (*free_context)(RimeContext* ctx); - Bool (*get_status)(RimeSessionId session_id, RimeStatus* status); - Bool (*free_status)(RimeStatus* status); - - // runtime options - - void (*set_option)(RimeSessionId session_id, const char* option, Bool value); - Bool (*get_option)(RimeSessionId session_id, const char* option); - - void (*set_property)(RimeSessionId session_id, - const char* prop, - const char* value); - Bool (*get_property)(RimeSessionId session_id, - const char* prop, - char* value, - size_t buffer_size); - - Bool (*get_schema_list)(RimeSchemaList* schema_list); - void (*free_schema_list)(RimeSchemaList* schema_list); - - Bool (*get_current_schema)(RimeSessionId session_id, - char* schema_id, - size_t buffer_size); - Bool (*select_schema)(RimeSessionId session_id, const char* schema_id); - - // configuration - - Bool (*schema_open)(const char* schema_id, RimeConfig* config); - Bool (*config_open)(const char* config_id, RimeConfig* config); - Bool (*config_close)(RimeConfig* config); - Bool (*config_get_bool)(RimeConfig* config, const char* key, Bool* value); - Bool (*config_get_int)(RimeConfig* config, const char* key, int* value); - Bool (*config_get_double)(RimeConfig* config, const char* key, double* value); - Bool (*config_get_string)(RimeConfig* config, - const char* key, - char* value, - size_t buffer_size); - const char* (*config_get_cstring)(RimeConfig* config, const char* key); - Bool (*config_update_signature)(RimeConfig* config, const char* signer); - Bool (*config_begin_map)(RimeConfigIterator* iterator, - RimeConfig* config, - const char* key); - Bool (*config_next)(RimeConfigIterator* iterator); - void (*config_end)(RimeConfigIterator* iterator); - - // testing - - Bool (*simulate_key_sequence)(RimeSessionId session_id, - const char* key_sequence); - - // module - - Bool (*register_module)(RimeModule* module); - RimeModule* (*find_module)(const char* module_name); - - Bool (*run_task)(const char* task_name); - - //! \deprecated use get_shared_data_dir_s instead. - const char* (*get_shared_data_dir)(void); - //! \deprecated use get_user_data_dir_s instead. - const char* (*get_user_data_dir)(void); - //! \deprecated use get_sync_dir_s instead. - const char* (*get_sync_dir)(void); - - const char* (*get_user_id)(void); - void (*get_user_data_sync_dir)(char* dir, size_t buffer_size); - - //! initialize an empty config object - /*! - * should call config_close() to free the object - */ - Bool (*config_init)(RimeConfig* config); - //! deserialize config from a yaml string - Bool (*config_load_string)(RimeConfig* config, const char* yaml); - - // configuration: setters - Bool (*config_set_bool)(RimeConfig* config, const char* key, Bool value); - Bool (*config_set_int)(RimeConfig* config, const char* key, int value); - Bool (*config_set_double)(RimeConfig* config, const char* key, double value); - Bool (*config_set_string)(RimeConfig* config, - const char* key, - const char* value); - - // configuration: manipulating complex structures - Bool (*config_get_item)(RimeConfig* config, - const char* key, - RimeConfig* value); - Bool (*config_set_item)(RimeConfig* config, - const char* key, - RimeConfig* value); - Bool (*config_clear)(RimeConfig* config, const char* key); - Bool (*config_create_list)(RimeConfig* config, const char* key); - Bool (*config_create_map)(RimeConfig* config, const char* key); - size_t (*config_list_size)(RimeConfig* config, const char* key); - Bool (*config_begin_list)(RimeConfigIterator* iterator, - RimeConfig* config, - const char* key); - - //! get raw input - /*! - * NULL is returned if session does not exist. - * the returned pointer to input string will become invalid upon editing. - */ - const char* (*get_input)(RimeSessionId session_id); - - //! caret position in terms of raw input - size_t (*get_caret_pos)(RimeSessionId session_id); - - //! select a candidate at the given index in candidate list. - Bool (*select_candidate)(RimeSessionId session_id, size_t index); - - //! get the version of librime - const char* (*get_version)(void); - - //! set caret position in terms of raw input - void (*set_caret_pos)(RimeSessionId session_id, size_t caret_pos); - - //! select a candidate from current page. - Bool (*select_candidate_on_current_page)(RimeSessionId session_id, - size_t index); - - //! access candidate list. - Bool (*candidate_list_begin)(RimeSessionId session_id, - RimeCandidateListIterator* iterator); - Bool (*candidate_list_next)(RimeCandidateListIterator* iterator); - void (*candidate_list_end)(RimeCandidateListIterator* iterator); - - //! access config files in user data directory, eg. user.yaml and - //! installation.yaml - Bool (*user_config_open)(const char* config_id, RimeConfig* config); - - Bool (*candidate_list_from_index)(RimeSessionId session_id, - RimeCandidateListIterator* iterator, - int index); - - //! prebuilt data directory. - //! \deprecated use get_prebuilt_data_dir_s instead. - const char* (*get_prebuilt_data_dir)(void); - //! staging directory, stores data files deployed to a Rime client. - //! \deprecated use get_staging_dir_s instead. - const char* (*get_staging_dir)(void); - - //! \deprecated for capnproto API, use "proto" module from librime-proto - //! plugin. - void (*commit_proto)(RimeSessionId session_id, - RIME_PROTO_BUILDER* commit_builder); - void (*context_proto)(RimeSessionId session_id, - RIME_PROTO_BUILDER* context_builder); - void (*status_proto)(RimeSessionId session_id, - RIME_PROTO_BUILDER* status_builder); - - const char* (*get_state_label)(RimeSessionId session_id, - const char* option_name, - Bool state); - - //! delete a candidate at the given index in candidate list. - Bool (*delete_candidate)(RimeSessionId session_id, size_t index); - //! delete a candidate from current page. - Bool (*delete_candidate_on_current_page)(RimeSessionId session_id, - size_t index); - - RimeStringSlice (*get_state_label_abbreviated)(RimeSessionId session_id, - const char* option_name, - Bool state, - Bool abbreviated); - - Bool (*set_input)(RimeSessionId session_id, const char* input); - - void (*get_shared_data_dir_s)(char* dir, size_t buffer_size); - void (*get_user_data_dir_s)(char* dir, size_t buffer_size); - void (*get_prebuilt_data_dir_s)(char* dir, size_t buffer_size); - void (*get_staging_dir_s)(char* dir, size_t buffer_size); - void (*get_sync_dir_s)(char* dir, size_t buffer_size); - - //! highlight a selection without committing - Bool (*highlight_candidate)(RimeSessionId session_id, size_t index); - //! highlight a selection without committing - Bool (*highlight_candidate_on_current_page)(RimeSessionId session_id, - size_t index); - - Bool (*change_page)(RimeSessionId session_id, Bool backward); -} RimeApi; - -//! API entry -/*! - * Acquire the version controlled RimeApi structure. - */ -RIME_API RimeApi* rime_get_api(void); +#include "rime_api_struct.h" //! Clients should test if an api function is available in the current version //! before calling it. diff --git a/src/rime_api_impl.h b/src/rime_api_impl.h new file mode 100644 index 0000000000..859adfbf0b --- /dev/null +++ b/src/rime_api_impl.h @@ -0,0 +1,671 @@ + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeStartMaintenance)(Bool full_check) { + return (Bool)start_maintenance(full_check); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeStartMaintenanceOnWorkspaceChange)() { + return RimeStartMaintenance(False); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimeIsMaintenancing)() { + Deployer& deployer(Service::instance().deployer()); + return Bool(deployer.IsMaintenanceMode()); +} + +// deployment + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimePrebuildAllSchemas)() { + Deployer& deployer(Service::instance().deployer()); + return Bool(deployer.RunTask("prebuild_all_schemas")); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimeDeployWorkspace)() { + Deployer& deployer(Service::instance().deployer()); + return Bool(deployer.RunTask("installation_update") && + deployer.RunTask("workspace_update") && + deployer.RunTask("user_dict_upgrade") && + deployer.RunTask("cleanup_trash")); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeDeploySchema)(const char* schema_file) { + Deployer& deployer(Service::instance().deployer()); + return Bool(deployer.RunTask("schema_update", path(schema_file))); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeDeployConfigFile)(const char* file_name, const char* version_key) { + Deployer& deployer(Service::instance().deployer()); + TaskInitializer args(make_pair(file_name, version_key)); + return Bool(deployer.RunTask("config_file_update", args)); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimeSyncUserData)() { + RimeCleanupAllSessions(); + Deployer& deployer(Service::instance().deployer()); + deployer.ScheduleTask("installation_update"); + deployer.ScheduleTask("backup_config_files"); + deployer.ScheduleTask("user_dict_sync"); + return Bool(deployer.StartMaintenance()); +} + +// session management + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeFindSession)(RimeSessionId session_id) { + return Bool(session_id && Service::instance().GetSession(session_id)); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeDestroySession)(RimeSessionId session_id) { + return Bool(Service::instance().DestroySession(session_id)); +} + +// input + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeProcessKey)(RimeSessionId session_id, int keycode, int mask) { + an session(Service::instance().GetSession(session_id)); + if (!session) + return False; + return Bool(session->ProcessKey(KeyEvent(keycode, mask))); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeCommitComposition)(RimeSessionId session_id) { + an session(Service::instance().GetSession(session_id)); + if (!session) + return False; + return Bool(session->CommitComposition()); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeGetContext)(RimeSessionId session_id, RimeContext* context) { + return (Bool)get_context(session_id, context); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeFreeContext)(RimeContext* context) { + return (Bool)free_context(context); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeGetCommit)(RimeSessionId session_id, RimeCommit* commit) { + return (Bool)get_commit(session_id, commit); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimeFreeCommit)(RimeCommit* commit) { + return (Bool)free_commit(commit); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeGetStatus)(RimeSessionId session_id, RimeStatus* status) { + return (Bool)get_status(session_id, status); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimeFreeStatus)(RimeStatus* status) { + return (Bool)free_status(status); +} + +// accessing candidate list + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimeCandidateListFromIndex)( + RimeSessionId session_id, + RimeCandidateListIterator* iterator, + int index) { + return (Bool)candidate_list_from_index(session_id, iterator, index); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeCandidateListBegin)(RimeSessionId session_id, + RimeCandidateListIterator* iterator) { + return (Bool)candidate_list_from_index(session_id, iterator, 0); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeCandidateListNext)(RimeCandidateListIterator* iterator) { + return (Bool)candidate_list_next(iterator); +} + +// runtime options + +RIME_API_DEPRECATED void RIME_API_FLAVORED( + RimeSetOption)(RimeSessionId session_id, const char* option, Bool value) { + an session(Service::instance().GetSession(session_id)); + if (!session) + return; + Context* ctx = session->context(); + if (!ctx) + return; + ctx->set_option(option, !!value); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeGetOption)(RimeSessionId session_id, const char* option) { + an session(Service::instance().GetSession(session_id)); + if (!session) + return False; + Context* ctx = session->context(); + if (!ctx) + return False; + return Bool(ctx->get_option(option)); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeGetProperty)(RimeSessionId session_id, + const char* prop, + char* value, + size_t buffer_size) { + an session(Service::instance().GetSession(session_id)); + if (!session) + return False; + Context* ctx = session->context(); + if (!ctx) + return False; + string str_value(ctx->get_property(prop)); + if (str_value.empty()) + return False; + strncpy(value, str_value.c_str(), buffer_size); + return True; +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeGetSchemaList)(RimeSchemaList* output) { + return (Bool)get_schema_list(output); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeGetCurrentSchema)(RimeSessionId session_id, + char* schema_id, + size_t buffer_size) { + an session(Service::instance().GetSession(session_id)); + if (!session) + return False; + Schema* schema = session->schema(); + if (!schema) + return False; + strncpy(schema_id, schema->schema_id().c_str(), buffer_size); + return True; +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeSelectSchema)(RimeSessionId session_id, const char* schema_id) { + if (!schema_id) + return False; + an session(Service::instance().GetSession(session_id)); + if (!session) + return False; + session->ApplySchema(new Schema(schema_id)); + return True; +} + +// config + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeSchemaOpen)(const char* schema_id, RimeConfig* config) { + return (Bool)open_config_in_component("schema", schema_id, config); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeConfigOpen)(const char* config_id, RimeConfig* config) { + return (Bool)open_config_in_component("config", config_id, config); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeUserConfigOpen)(const char* config_id, RimeConfig* config) { + return (Bool)open_config_in_component("user_config", config_id, config); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeConfigClose)(RimeConfig* config) { + if (!config || !config->ptr) + return False; + Config* c = reinterpret_cast(config->ptr); + delete c; + config->ptr = NULL; + return True; +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeConfigGetBool)(RimeConfig* config, const char* key, Bool* value) { + if (!config || !key || !value) + return False; + Config* c = reinterpret_cast(config->ptr); + bool bool_value = false; + if (c->GetBool(key, &bool_value)) { + *value = Bool(bool_value); + return True; + } + return False; +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimeConfigGetInt)(RimeConfig* config, + const char* key, + int* value) { + if (!config || !key || !value) + return False; + Config* c = reinterpret_cast(config->ptr); + return Bool(c->GetInt(key, value)); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeConfigGetDouble)(RimeConfig* config, const char* key, double* value) { + if (!config || !key || !value) + return False; + Config* c = reinterpret_cast(config->ptr); + return Bool(c->GetDouble(key, value)); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeConfigGetString)(RimeConfig* config, + const char* key, + char* value, + size_t buffer_size) { + if (!config || !key || !value) + return False; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + string str_value; + if (c->GetString(key, &str_value)) { + std::strncpy(value, str_value.c_str(), buffer_size); + return True; + } + return False; +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeConfigUpdateSignature)(RimeConfig* config, const char* signer) { + if (!config || !signer) + return False; + Config* c = reinterpret_cast(config->ptr); + Deployer& deployer(Service::instance().deployer()); + Signature sig(signer); + return Bool(sig.Sign(c, &deployer)); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeConfigBeginList)(RimeConfigIterator* iterator, + RimeConfig* config, + const char* key) { + if (!iterator || !config || !key) + return False; + iterator->list = NULL; + iterator->map = NULL; + iterator->index = -1; + iterator->key = NULL; + iterator->path = NULL; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + an list = c->GetList(key); + if (!list) + return False; + iterator->list = new RimeConfigIteratorImpl(*list, key); + return True; +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeConfigBeginMap)(RimeConfigIterator* iterator, + RimeConfig* config, + const char* key) { + if (!iterator || !config || !key) + return False; + iterator->list = NULL; + iterator->map = NULL; + iterator->index = -1; + iterator->key = NULL; + iterator->path = NULL; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + an m = c->GetMap(key); + if (!m) + return False; + iterator->map = new RimeConfigIteratorImpl(*m, key); + return True; +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeConfigNext)(RimeConfigIterator* iterator) { + return (Bool)config_next(iterator); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeSimulateKeySequence)(RimeSessionId session_id, + const char* key_sequence) { + LOG(INFO) << "simulate key sequence: " << key_sequence; + an session(Service::instance().GetSession(session_id)); + if (!session) + return False; + KeySequence keys; + if (!keys.Parse(key_sequence)) { + LOG(ERROR) << "error parsing input: '" << key_sequence << "'"; + return False; + } + for (const KeyEvent& key : keys) { + session->ProcessKey(key); + } + return True; +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeRegisterModule)(RimeModule* module) { + if (!module || !module->module_name) + return False; + ModuleManager::instance().Register(module->module_name, module); + return True; +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimeRunTask)(const char* task_name) { + if (!task_name) + return False; + Deployer& deployer(Service::instance().deployer()); + return Bool(deployer.RunTask(task_name)); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimeConfigInit)(RimeConfig* config) { + if (!config || config->ptr) + return False; + config->ptr = (void*)new Config; + return True; +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeConfigLoadString)(RimeConfig* config, const char* yaml) { + if (!config || !yaml) { + return False; + } + if (!config->ptr) { + RimeConfigInit(config); + } + Config* c = reinterpret_cast(config->ptr); + std::istringstream iss(yaml); + return Bool(c->LoadFromStream(iss)); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeConfigGetItem)(RimeConfig* config, const char* key, RimeConfig* value) { + if (!config || !key || !value) + return False; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + if (!value->ptr) { + RimeConfigInit(value); + } + Config* v = reinterpret_cast(value->ptr); + *v = c->GetItem(key); + return True; +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeConfigSetItem)(RimeConfig* config, const char* key, RimeConfig* value) { + if (!config || !key) + return False; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + an item; + if (value) { + if (Config* v = reinterpret_cast(value->ptr)) { + item = v->GetItem(""); + } + } + return Bool(c->SetItem(key, item)); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeConfigSetBool)(RimeConfig* config, const char* key, Bool value) { + if (!config || !key) + return False; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + return c->SetBool(key, value != False); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimeConfigSetInt)(RimeConfig* config, + const char* key, + int value) { + if (!config || !key) + return False; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + return Bool(c->SetInt(key, value)); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeConfigSetDouble)(RimeConfig* config, const char* key, double value) { + if (!config || !key) + return False; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + return Bool(c->SetDouble(key, value)); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeConfigSetString)(RimeConfig* config, + const char* key, + const char* value) { + if (!config || !key || !value) + return False; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + return Bool(c->SetString(key, value)); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED(RimeConfigClear)(RimeConfig* config, + const char* key) { + if (!config || !key) + return False; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + return Bool(c->SetItem(key, nullptr)); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeConfigCreateList)(RimeConfig* config, const char* key) { + if (!config || !key) + return False; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + return Bool(c->SetItem(key, New())); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeConfigCreateMap)(RimeConfig* config, const char* key) { + if (!config || !key) + return False; + Config* c = reinterpret_cast(config->ptr); + if (!c) + return False; + return Bool(c->SetItem(key, New())); +} + +Bool RIME_API_FLAVORED(RimeChangePage)(RimeSessionId session_id, + Bool backward) { + return (Bool)change_page(session_id, bool(backward)); +} + +Bool RIME_API_FLAVORED(RimeHighlightCandidate)(RimeSessionId session_id, + size_t index) { + return (Bool)do_with_candidate(session_id, index, &Context::Highlight); +} + +Bool RIME_API_FLAVORED(RimeHighlightCandidateOnCurrentPage)( + RimeSessionId session_id, + size_t index) { + return (Bool)do_with_candidate_on_current_page(session_id, index, + &Context::Highlight); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeSelectCandidate)(RimeSessionId session_id, size_t index) { + return (Bool)do_with_candidate(session_id, index, &Context::Select); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeSelectCandidateOnCurrentPage)(RimeSessionId session_id, size_t index) { + return (Bool)do_with_candidate_on_current_page(session_id, index, + &Context::Select); +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeDeleteCandidate)(RimeSessionId session_id, size_t index) { + return (Bool)do_with_candidate(session_id, index, &Context::DeleteCandidate); +} + +RIME_API_DEPRECATED Bool RIME_API_FLAVORED( + RimeDeleteCandidateOnCurrentPage)(RimeSessionId session_id, size_t index) { + return (Bool)do_with_candidate_on_current_page(session_id, index, + &Context::DeleteCandidate); +} + +RimeStringSlice RIME_API_FLAVORED(RimeGetStateLabelAbbreviated)( + RimeSessionId session_id, + const char* option_name, + Bool state, + Bool abbreviated) { + return get_state_label_abbreviated(session_id, option_name, bool(state), + bool(abbreviated)); +} + +const char* RIME_API_FLAVORED(RimeGetStateLabel)(RimeSessionId session_id, + const char* option_name, + Bool state) { + return get_state_label_abbreviated(session_id, option_name, bool(state), + false) + .str; +} + +RIME_API_DEPRECATED Bool +RIME_API_FLAVORED(RimeSetInput)(RimeSessionId session_id, const char* input) { + an session(Service::instance().GetSession(session_id)); + if (!session) + return False; + Context* ctx = session->context(); + if (!ctx) + return False; + ctx->set_input(input); + return True; +} + +RIME_API RIME_API_FLAVORED(RimeApi) * RIME_API_FLAVORED(rime_get_api)() { + static RIME_API_FLAVORED(RimeApi) s_api = {0}; + if (!s_api.data_size) { + RIME_STRUCT_INIT(RIME_API_FLAVORED(RimeApi), s_api); + s_api.setup = &RimeSetup; + s_api.set_notification_handler = &RimeSetNotificationHandler; + s_api.initialize = &RimeInitialize; + s_api.finalize = &RimeFinalize; + s_api.start_maintenance = &RIME_API_FLAVORED(RimeStartMaintenance); + s_api.is_maintenance_mode = &RIME_API_FLAVORED(RimeIsMaintenancing); + s_api.join_maintenance_thread = &RimeJoinMaintenanceThread; + s_api.deployer_initialize = &RimeDeployerInitialize; + s_api.prebuild = &RIME_API_FLAVORED(RimePrebuildAllSchemas); + s_api.deploy = &RIME_API_FLAVORED(RimeDeployWorkspace); + s_api.deploy_schema = &RIME_API_FLAVORED(RimeDeploySchema); + s_api.deploy_config_file = &RIME_API_FLAVORED(RimeDeployConfigFile); + s_api.sync_user_data = &RIME_API_FLAVORED(RimeSyncUserData); + s_api.create_session = &RimeCreateSession; + s_api.find_session = &RIME_API_FLAVORED(RimeFindSession); + s_api.destroy_session = &RIME_API_FLAVORED(RimeDestroySession); + s_api.cleanup_stale_sessions = &RimeCleanupStaleSessions; + s_api.cleanup_all_sessions = &RimeCleanupAllSessions; + s_api.process_key = &RIME_API_FLAVORED(RimeProcessKey); + s_api.commit_composition = &RIME_API_FLAVORED(RimeCommitComposition); + s_api.clear_composition = &RimeClearComposition; + s_api.get_commit = &RIME_API_FLAVORED(RimeGetCommit); + s_api.free_commit = &RIME_API_FLAVORED(RimeFreeCommit); + s_api.get_context = &RIME_API_FLAVORED(RimeGetContext); + s_api.free_context = &RIME_API_FLAVORED(RimeFreeContext); + s_api.get_status = &RIME_API_FLAVORED(RimeGetStatus); + s_api.free_status = &RIME_API_FLAVORED(RimeFreeStatus); + s_api.set_option = &RIME_API_FLAVORED(RimeSetOption); + s_api.get_option = &RIME_API_FLAVORED(RimeGetOption); + s_api.set_property = &RimeSetProperty; + s_api.get_property = &RIME_API_FLAVORED(RimeGetProperty); + s_api.get_schema_list = &RIME_API_FLAVORED(RimeGetSchemaList); + s_api.free_schema_list = &RimeFreeSchemaList; + s_api.get_current_schema = &RIME_API_FLAVORED(RimeGetCurrentSchema); + s_api.select_schema = &RIME_API_FLAVORED(RimeSelectSchema); + s_api.schema_open = &RIME_API_FLAVORED(RimeSchemaOpen); + s_api.config_open = &RIME_API_FLAVORED(RimeConfigOpen); + s_api.user_config_open = &RIME_API_FLAVORED(RimeUserConfigOpen); + s_api.config_close = &RIME_API_FLAVORED(RimeConfigClose); + s_api.config_get_bool = &RIME_API_FLAVORED(RimeConfigGetBool); + s_api.config_get_int = &RIME_API_FLAVORED(RimeConfigGetInt); + s_api.config_get_double = &RIME_API_FLAVORED(RimeConfigGetDouble); + s_api.config_get_string = &RIME_API_FLAVORED(RimeConfigGetString); + s_api.config_get_cstring = &RimeConfigGetCString; + s_api.config_update_signature = + &RIME_API_FLAVORED(RimeConfigUpdateSignature); + s_api.config_begin_map = &RIME_API_FLAVORED(RimeConfigBeginMap); + s_api.config_next = &RIME_API_FLAVORED(RimeConfigNext); + s_api.config_end = &RimeConfigEnd; + s_api.simulate_key_sequence = &RIME_API_FLAVORED(RimeSimulateKeySequence); + s_api.register_module = &RIME_API_FLAVORED(RimeRegisterModule); + s_api.find_module = &RimeFindModule; + s_api.run_task = &RIME_API_FLAVORED(RimeRunTask); + s_api.get_shared_data_dir = &RimeGetSharedDataDir; + s_api.get_user_data_dir = &RimeGetUserDataDir; + s_api.get_sync_dir = &RimeGetSyncDir; + s_api.get_user_id = &RimeGetUserId; + s_api.get_user_data_sync_dir = &RimeGetUserDataSyncDir; + s_api.config_init = &RIME_API_FLAVORED(RimeConfigInit); + s_api.config_load_string = &RIME_API_FLAVORED(RimeConfigLoadString); + s_api.config_set_bool = &RIME_API_FLAVORED(RimeConfigSetBool); + s_api.config_set_int = &RIME_API_FLAVORED(RimeConfigSetInt); + s_api.config_set_double = &RIME_API_FLAVORED(RimeConfigSetDouble); + s_api.config_set_string = &RIME_API_FLAVORED(RimeConfigSetString); + s_api.config_get_item = &RIME_API_FLAVORED(RimeConfigGetItem); + s_api.config_set_item = &RIME_API_FLAVORED(RimeConfigSetItem); + s_api.config_clear = &RIME_API_FLAVORED(RimeConfigClear); + s_api.config_create_list = &RIME_API_FLAVORED(RimeConfigCreateList); + s_api.config_create_map = &RIME_API_FLAVORED(RimeConfigCreateMap); + s_api.config_list_size = &RimeConfigListSize; + s_api.config_begin_list = &RIME_API_FLAVORED(RimeConfigBeginList); + s_api.get_input = &RimeGetInput; + s_api.get_caret_pos = &RimeGetCaretPos; + s_api.select_candidate = &RIME_API_FLAVORED(RimeSelectCandidate); + s_api.get_version = &RimeGetVersion; + s_api.set_caret_pos = &RimeSetCaretPos; + s_api.select_candidate_on_current_page = + &RIME_API_FLAVORED(RimeSelectCandidateOnCurrentPage); + s_api.candidate_list_begin = &RIME_API_FLAVORED(RimeCandidateListBegin); + s_api.candidate_list_next = &RIME_API_FLAVORED(RimeCandidateListNext); + s_api.candidate_list_end = &RimeCandidateListEnd; + s_api.candidate_list_from_index = + &RIME_API_FLAVORED(RimeCandidateListFromIndex); + s_api.get_prebuilt_data_dir = &RimeGetPrebuiltDataDir; + s_api.get_staging_dir = &RimeGetStagingDir; + s_api.commit_proto = nullptr; + s_api.context_proto = nullptr; + s_api.status_proto = nullptr; + s_api.get_state_label = &RIME_API_FLAVORED(RimeGetStateLabel); + s_api.delete_candidate = &RIME_API_FLAVORED(RimeDeleteCandidate); + s_api.delete_candidate_on_current_page = + &RIME_API_FLAVORED(RimeDeleteCandidateOnCurrentPage); + s_api.get_state_label_abbreviated = + &RIME_API_FLAVORED(RimeGetStateLabelAbbreviated); + s_api.set_input = &RIME_API_FLAVORED(RimeSetInput); + s_api.get_shared_data_dir_s = &RimeGetSharedDataDirSecure; + s_api.get_user_data_dir_s = &RimeGetUserDataDirSecure; + s_api.get_prebuilt_data_dir_s = &RimeGetPrebuiltDataDirSecure; + s_api.get_staging_dir_s = &RimeGetStagingDirSecure; + s_api.get_sync_dir_s = &RimeGetSyncDirSecure; + s_api.highlight_candidate = &RIME_API_FLAVORED(RimeHighlightCandidate); + s_api.highlight_candidate_on_current_page = + &RIME_API_FLAVORED(RimeHighlightCandidateOnCurrentPage); + s_api.change_page = &RIME_API_FLAVORED(RimeChangePage); + } + return &s_api; +} diff --git a/src/rime_api_stdbool.h b/src/rime_api_stdbool.h new file mode 100644 index 0000000000..644ab9e304 --- /dev/null +++ b/src/rime_api_stdbool.h @@ -0,0 +1,23 @@ +#ifndef RIME_API_STDBOOL_H_ +#define RIME_API_STDBOOL_H_ + +#include + +#define RIME_API_FLAVORED(name) name##_stdbool + +// do not export librime 0.9 API in this build variant +#define RIME_API_DEPRECATED + +typedef bool Bool; + +#ifndef False +#define False false +#endif + +#ifndef True +#define True true +#endif + +#include "rime_api_struct.h" + +#endif // RIME_API_STDBOOL_H_ diff --git a/src/rime_api_struct.h b/src/rime_api_struct.h new file mode 100644 index 0000000000..b2fdeaf77d --- /dev/null +++ b/src/rime_api_struct.h @@ -0,0 +1,257 @@ +/*! The API structure + * RimeApi is for rime v1.0+ + */ +typedef struct RIME_API_FLAVORED(rime_api_t) { + int data_size; + + /*! setup + * Call this function before accessing any other API functions. + */ + void (*setup)(RimeTraits* traits); + + /*! Set up the notification callbacks + * Receive notifications + * - on loading schema: + * + message_type="schema", message_value="luna_pinyin/Luna Pinyin" + * - on changing mode: + * + message_type="option", message_value="ascii_mode" + * + message_type="option", message_value="!ascii_mode" + * - on deployment: + * + session_id = 0, message_type="deploy", message_value="start" + * + session_id = 0, message_type="deploy", message_value="success" + * + session_id = 0, message_type="deploy", message_value="failure" + * + * handler will be called with context_object as the first parameter + * every time an event occurs in librime, until RimeFinalize() is called. + * when handler is NULL, notification is disabled. + */ + void (*set_notification_handler)(RimeNotificationHandler handler, + void* context_object); + + // entry and exit + + void (*initialize)(RimeTraits* traits); + void (*finalize)(void); + + Bool (*start_maintenance)(Bool full_check); + Bool (*is_maintenance_mode)(void); + void (*join_maintenance_thread)(void); + + // deployment + + void (*deployer_initialize)(RimeTraits* traits); + Bool (*prebuild)(void); + Bool (*deploy)(void); + Bool (*deploy_schema)(const char* schema_file); + Bool (*deploy_config_file)(const char* file_name, const char* version_key); + + Bool (*sync_user_data)(void); + + // session management + + RimeSessionId (*create_session)(void); + Bool (*find_session)(RimeSessionId session_id); + Bool (*destroy_session)(RimeSessionId session_id); + void (*cleanup_stale_sessions)(void); + void (*cleanup_all_sessions)(void); + + // input + + Bool (*process_key)(RimeSessionId session_id, int keycode, int mask); + // return True if there is unread commit text + Bool (*commit_composition)(RimeSessionId session_id); + void (*clear_composition)(RimeSessionId session_id); + + // output + + Bool (*get_commit)(RimeSessionId session_id, RimeCommit* commit); + Bool (*free_commit)(RimeCommit* commit); + Bool (*get_context)(RimeSessionId session_id, RimeContext* context); + Bool (*free_context)(RimeContext* ctx); + Bool (*get_status)(RimeSessionId session_id, RimeStatus* status); + Bool (*free_status)(RimeStatus* status); + + // runtime options + + void (*set_option)(RimeSessionId session_id, const char* option, Bool value); + Bool (*get_option)(RimeSessionId session_id, const char* option); + + void (*set_property)(RimeSessionId session_id, + const char* prop, + const char* value); + Bool (*get_property)(RimeSessionId session_id, + const char* prop, + char* value, + size_t buffer_size); + + Bool (*get_schema_list)(RimeSchemaList* schema_list); + void (*free_schema_list)(RimeSchemaList* schema_list); + + Bool (*get_current_schema)(RimeSessionId session_id, + char* schema_id, + size_t buffer_size); + Bool (*select_schema)(RimeSessionId session_id, const char* schema_id); + + // configuration + + Bool (*schema_open)(const char* schema_id, RimeConfig* config); + Bool (*config_open)(const char* config_id, RimeConfig* config); + Bool (*config_close)(RimeConfig* config); + Bool (*config_get_bool)(RimeConfig* config, const char* key, Bool* value); + Bool (*config_get_int)(RimeConfig* config, const char* key, int* value); + Bool (*config_get_double)(RimeConfig* config, const char* key, double* value); + Bool (*config_get_string)(RimeConfig* config, + const char* key, + char* value, + size_t buffer_size); + const char* (*config_get_cstring)(RimeConfig* config, const char* key); + Bool (*config_update_signature)(RimeConfig* config, const char* signer); + Bool (*config_begin_map)(RimeConfigIterator* iterator, + RimeConfig* config, + const char* key); + Bool (*config_next)(RimeConfigIterator* iterator); + void (*config_end)(RimeConfigIterator* iterator); + + // testing + + Bool (*simulate_key_sequence)(RimeSessionId session_id, + const char* key_sequence); + + // module + + Bool (*register_module)(RimeModule* module); + RimeModule* (*find_module)(const char* module_name); + + Bool (*run_task)(const char* task_name); + + //! \deprecated use get_shared_data_dir_s instead. + const char* (*get_shared_data_dir)(void); + //! \deprecated use get_user_data_dir_s instead. + const char* (*get_user_data_dir)(void); + //! \deprecated use get_sync_dir_s instead. + const char* (*get_sync_dir)(void); + + const char* (*get_user_id)(void); + void (*get_user_data_sync_dir)(char* dir, size_t buffer_size); + + //! initialize an empty config object + /*! + * should call config_close() to free the object + */ + Bool (*config_init)(RimeConfig* config); + //! deserialize config from a yaml string + Bool (*config_load_string)(RimeConfig* config, const char* yaml); + + // configuration: setters + Bool (*config_set_bool)(RimeConfig* config, const char* key, Bool value); + Bool (*config_set_int)(RimeConfig* config, const char* key, int value); + Bool (*config_set_double)(RimeConfig* config, const char* key, double value); + Bool (*config_set_string)(RimeConfig* config, + const char* key, + const char* value); + + // configuration: manipulating complex structures + Bool (*config_get_item)(RimeConfig* config, + const char* key, + RimeConfig* value); + Bool (*config_set_item)(RimeConfig* config, + const char* key, + RimeConfig* value); + Bool (*config_clear)(RimeConfig* config, const char* key); + Bool (*config_create_list)(RimeConfig* config, const char* key); + Bool (*config_create_map)(RimeConfig* config, const char* key); + size_t (*config_list_size)(RimeConfig* config, const char* key); + Bool (*config_begin_list)(RimeConfigIterator* iterator, + RimeConfig* config, + const char* key); + + //! get raw input + /*! + * NULL is returned if session does not exist. + * the returned pointer to input string will become invalid upon editing. + */ + const char* (*get_input)(RimeSessionId session_id); + + //! caret position in terms of raw input + size_t (*get_caret_pos)(RimeSessionId session_id); + + //! select a candidate at the given index in candidate list. + Bool (*select_candidate)(RimeSessionId session_id, size_t index); + + //! get the version of librime + const char* (*get_version)(void); + + //! set caret position in terms of raw input + void (*set_caret_pos)(RimeSessionId session_id, size_t caret_pos); + + //! select a candidate from current page. + Bool (*select_candidate_on_current_page)(RimeSessionId session_id, + size_t index); + + //! access candidate list. + Bool (*candidate_list_begin)(RimeSessionId session_id, + RimeCandidateListIterator* iterator); + Bool (*candidate_list_next)(RimeCandidateListIterator* iterator); + void (*candidate_list_end)(RimeCandidateListIterator* iterator); + + //! access config files in user data directory, eg. user.yaml and + //! installation.yaml + Bool (*user_config_open)(const char* config_id, RimeConfig* config); + + Bool (*candidate_list_from_index)(RimeSessionId session_id, + RimeCandidateListIterator* iterator, + int index); + + //! prebuilt data directory. + //! \deprecated use get_prebuilt_data_dir_s instead. + const char* (*get_prebuilt_data_dir)(void); + //! staging directory, stores data files deployed to a Rime client. + //! \deprecated use get_staging_dir_s instead. + const char* (*get_staging_dir)(void); + + //! \deprecated for capnproto API, use "proto" module from librime-proto + //! plugin. + void (*commit_proto)(RimeSessionId session_id, + RIME_PROTO_BUILDER* commit_builder); + void (*context_proto)(RimeSessionId session_id, + RIME_PROTO_BUILDER* context_builder); + void (*status_proto)(RimeSessionId session_id, + RIME_PROTO_BUILDER* status_builder); + + const char* (*get_state_label)(RimeSessionId session_id, + const char* option_name, + Bool state); + + //! delete a candidate at the given index in candidate list. + Bool (*delete_candidate)(RimeSessionId session_id, size_t index); + //! delete a candidate from current page. + Bool (*delete_candidate_on_current_page)(RimeSessionId session_id, + size_t index); + + RimeStringSlice (*get_state_label_abbreviated)(RimeSessionId session_id, + const char* option_name, + Bool state, + Bool abbreviated); + + Bool (*set_input)(RimeSessionId session_id, const char* input); + + void (*get_shared_data_dir_s)(char* dir, size_t buffer_size); + void (*get_user_data_dir_s)(char* dir, size_t buffer_size); + void (*get_prebuilt_data_dir_s)(char* dir, size_t buffer_size); + void (*get_staging_dir_s)(char* dir, size_t buffer_size); + void (*get_sync_dir_s)(char* dir, size_t buffer_size); + + //! highlight a selection without committing + Bool (*highlight_candidate)(RimeSessionId session_id, size_t index); + //! highlight a selection without committing + Bool (*highlight_candidate_on_current_page)(RimeSessionId session_id, + size_t index); + + Bool (*change_page)(RimeSessionId session_id, Bool backward); +} RIME_API_FLAVORED(RimeApi); + +//! API entry +/*! + * Acquire the version controlled RimeApi structure. + */ +RIME_API RIME_API_FLAVORED(RimeApi) * RIME_API_FLAVORED(rime_get_api)(void);