void InputContext::review_im(const char *engine) { char *locale, *prev_engine; const char *client_locale, *engine_locales; const char *encoding; prev_engine = mEngineName; mEngineName = strdup(engine); encoding = mXic->get_encoding(); client_locale = mXic->get_lang_region(); engine_locales = compose_localenames_from_im_lang(get_im_lang_from_engine(engine)); if (!strcmp(encoding, "UTF-8")) { if (is_locale_included(engine_locales, client_locale)) locale = strdup(client_locale); else locale = get_prefered_locale(engine_locales); locale = (char *)realloc(locale, strlen(locale) + strlen(".UTF-8") + 1); strcat(locale, ".UTF-8"); setlocale(LC_CTYPE, locale); free(mLocaleName); mLocaleName = locale; } else { if (!is_locale_included(engine_locales, client_locale)) { clear(); uim_switch_im(mUc, prev_engine); free(mEngineName); mEngineName = strdup(prev_engine); } } free(prev_engine); }
void InputContext::changeContext(const char *engine) { const char *encoding, *im_lang; if (!strcmp(mEngineName, engine)) return; encoding = mXic->get_encoding(); im_lang = get_im_lang_from_engine(engine); // Don't change im unless encoding matches for clients with legacy locales. if (strcmp(encoding, "UTF-8")) { const char *client_locale = mXic->get_lang_region(); const char *engine_locales = compose_localenames_from_im_lang(im_lang); if (!is_locale_included(engine_locales, client_locale)) return; } clear(); uim_release_context(mUc); createUimContext(engine); // mUc, mEngineName, and locale will be set here. if (mConvdisp) { mConvdisp->set_im_lang(get_im_lang_from_engine(mEngineName)); mConvdisp->set_locale_name(mLocaleName); } }
static const char * get_valid_locales(const char *locales) { char *valid_locales = NULL; char *validated; char *locale; char *tmp, *tmpp; int len = 0; tmp = tmpp = strdup(locales); char *orig_locale = strdup(setlocale(LC_CTYPE, NULL)); // locales is separated with ':' while ((locale = strsep(&tmpp, ":")) != NULL) { if (setlocale(LC_CTYPE, locale) != NULL) { if (asprintf(&validated, "%s:", locale) == -1) { free(validated); continue; } len += static_cast<int>(strlen(validated)); if (valid_locales) { valid_locales = (char *)realloc(valid_locales, len + 1); strcat(valid_locales, validated); } else valid_locales = strdup(validated); free(validated); } else { // retry with supplemental encodings int i; for (i = 0; locale_map[i].localename; i++) { if (is_locale_included(locale_map[i].localename, locale)) break; } if (locale_map[i].supplemental_encoding) { char *encs, *encsp, *encoding; encs = encsp = strdup(locale_map[i].supplemental_encoding); while ((encoding = strsep(&encsp, ":")) != NULL) { char *test_locale = strdup(locale); test_locale = (char *)realloc(test_locale, strlen(test_locale) + strlen(encoding) + 2); strcat(test_locale, "."); strcat(test_locale, encoding); if (setlocale(LC_CTYPE, test_locale) != NULL) { if (asprintf(&validated, "%s:", locale) == -1) { free(validated); continue; } len += static_cast<int>(strlen(validated)); if (valid_locales) { valid_locales = (char *)realloc(valid_locales, len + 1); strcat(valid_locales, validated); } else valid_locales = strdup(validated); free(validated); free(test_locale); break; } else free(test_locale); } free(encs); } } } if (valid_locales) valid_locales[len - 1] = '\0'; // remove trailing ':' else valid_locales = strdup(""); // There is no valid locale or im-lang is // "". These im will be used with // en_US.UTF-8. setlocale(LC_CTYPE, orig_locale); free(orig_locale); free(tmp); return valid_locales; }
void InputContext::createUimContext(const char *engine) { char *locale; const char *client_locale, *engine_locales; const char *encoding; const char *real_im; encoding = mXic->get_encoding(); client_locale = mXic->get_lang_region(); engine_locales = compose_localenames_from_im_lang(get_im_lang_from_engine(engine)); if (!strcmp(encoding, "UTF-8")) { real_im = engine; if (is_locale_included(engine_locales, client_locale)) locale = strdup(client_locale); else { locale = get_prefered_locale(engine_locales); } } else { // Use default engine for corresponding encoding of the client // unless encoding matches with selected engine. if (!is_locale_included(engine_locales, client_locale)) { const char *test_im = uim_get_default_im_name(client_locale); const char *test_im_lang = get_im_lang_from_engine(test_im); const char *test_im_locales = compose_localenames_from_im_lang(test_im_lang); if (is_locale_included(test_im_locales, client_locale)) real_im = test_im; else real_im = uim_get_im_name_for_locale(client_locale); } else real_im = engine; locale = strdup(client_locale); } locale = (char *)realloc(locale, strlen(locale) + strlen(encoding) + 2); strcat(locale, "."); strcat(locale, encoding); setlocale(LC_CTYPE, locale); free(mLocaleName); mLocaleName = locale; if (mEngineName != real_im) { free(mEngineName); mEngineName = strdup(real_im); } uim_context uc = uim_create_context((void *) this, "UTF-8", NULL, real_im, NULL, InputContext::commit_cb); if (uc) { uim_set_preedit_cb(uc, InputContext::clear_cb, InputContext::pushback_cb, InputContext::update_cb); uim_set_candidate_selector_cb(uc, InputContext::candidate_activate_cb, InputContext::candidate_select_cb, InputContext::candidate_shift_page_cb, InputContext::candidate_deactivate_cb); uim_set_prop_list_update_cb(uc, InputContext::update_prop_list_cb); #if 0 uim_set_prop_label_update_cb(uc, InputContext::update_prop_label_cb); #endif uim_set_configuration_changed_cb(uc, InputContext::configuration_changed_cb); uim_set_im_switch_request_cb(uc, InputContext::switch_app_global_im_cb, InputContext::switch_system_global_im_cb); #if UIM_XIM_USE_DELAY uim_set_delay_candidate_selector_cb(uc, InputContext::candidate_activate_with_delay_cb); #endif if (mFocusedContext == this) uim_prop_list_update(uc); } mUc = uc; }