static void preedit_done_callback(XIC xic EINA_UNUSED, XPointer client_data, XPointer call_data EINA_UNUSED) { EINA_LOG_DBG("in"); Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data; Ecore_IMF_Context_Data *imf_context_data; imf_context_data = ecore_imf_context_data_get(ctx); EINA_SAFETY_ON_NULL_RETURN(imf_context_data); if (imf_context_data->preedit_length) { imf_context_data->preedit_length = 0; free(imf_context_data->preedit_chars); imf_context_data->preedit_chars = NULL; ecore_imf_context_preedit_changed_event_add(ctx); ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); } if (imf_context_data->finalizing == EINA_FALSE) { ecore_imf_context_preedit_end_event_add(ctx); ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); } }
static int preedit_start_callback(XIC xic EINA_UNUSED, XPointer client_data, XPointer call_data EINA_UNUSED) { EINA_LOG_DBG("in"); Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data; Ecore_IMF_Context_Data *imf_context_data; imf_context_data = ecore_imf_context_data_get(ctx); if (!imf_context_data) return -1; if (imf_context_data->finalizing == EINA_FALSE) { ecore_imf_context_preedit_start_event_add(ctx); ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); } return -1; }
static int _ecore_imf_xim_preedit_start_call(XIC xic EINA_UNUSED, XPointer client_data, XPointer call_data EINA_UNUSED) { Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)client_data; Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx); DBG("ctx=%p, imf_context_data=%p", ctx, imf_context_data); EINA_SAFETY_ON_NULL_RETURN_VAL(imf_context_data, -1); if (imf_context_data->finalizing == EINA_FALSE) { ecore_imf_context_preedit_start_event_add(ctx); ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); } return -1; }
static Eina_Bool _ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx, Ecore_IMF_Event_Type type, Ecore_IMF_Event *event) { EINA_LOG_DBG("%s in", __FUNCTION__); #ifdef ENABLE_XIM Ecore_IMF_Context_Data *imf_context_data; XIC ic; Ecore_X_Display *dsp; Ecore_X_Window win; int val; char compose_buffer[256]; KeySym sym; char *compose = NULL; char *tmp = NULL; Eina_Bool result = EINA_FALSE; imf_context_data = ecore_imf_context_data_get(ctx); if (!imf_context_data) return EINA_FALSE; ic = imf_context_data->ic; if (!ic) ic = get_ic(ctx); if (type == ECORE_IMF_EVENT_KEY_DOWN) { XKeyPressedEvent xev; Ecore_IMF_Event_Key_Down *ev = (Ecore_IMF_Event_Key_Down *)event; EINA_LOG_DBG("ECORE_IMF_EVENT_KEY_DOWN"); dsp = ecore_x_display_get(); win = imf_context_data->win; xev.type = KeyPress; xev.serial = 0; /* hope it doesn't matter */ xev.send_event = 0; xev.display = dsp; xev.window = win; xev.root = ecore_x_window_root_get(win); xev.subwindow = win; xev.time = ev->timestamp; xev.x = xev.x_root = 0; xev.y = xev.y_root = 0; xev.state = 0; xev.state |= _ecore_x_event_reverse_modifiers(ev->modifiers); xev.state |= _ecore_x_event_reverse_locks(ev->locks); xev.keycode = _keycode_get(dsp, ev->keyname); xev.same_screen = True; if (ic) { Status mbstatus; #ifdef X_HAVE_UTF8_STRING val = Xutf8LookupString(ic, &xev, compose_buffer, sizeof(compose_buffer) - 1, &sym, &mbstatus); #else /* ifdef X_HAVE_UTF8_STRING */ val = XmbLookupString(ic, &xev, compose_buffer, sizeof(compose_buffer) - 1, &sym, &mbstatus); #endif /* ifdef X_HAVE_UTF8_STRING */ if (mbstatus == XBufferOverflow) { tmp = malloc(sizeof (char) * (val + 1)); if (!tmp) return EINA_FALSE; compose = tmp; #ifdef X_HAVE_UTF8_STRING val = Xutf8LookupString(ic, &xev, tmp, val, &sym, &mbstatus); #else /* ifdef X_HAVE_UTF8_STRING */ val = XmbLookupString(ic, &xev, tmp, val, &sym, &mbstatus); #endif /* ifdef X_HAVE_UTF8_STRING */ if (val > 0) { tmp[val] = '\0'; #ifndef X_HAVE_UTF8_STRING compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", tmp); free(tmp); tmp = compose; #endif /* ifndef X_HAVE_UTF8_STRING */ } else compose = NULL; } else if (val > 0) { compose_buffer[val] = '\0'; #ifdef X_HAVE_UTF8_STRING compose = strdup(compose_buffer); #else /* ifdef X_HAVE_UTF8_STRING */ compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer); #endif /* ifdef X_HAVE_UTF8_STRING */ } } else { compose = strdup(ev->compose); } if (compose) { Eina_Unicode *unicode; int len; unicode = eina_unicode_utf8_to_unicode(compose, &len); if (!unicode) abort(); if (unicode[0] >= 0x20 && unicode[0] != 0x7f) { ecore_imf_context_commit_event_add(ctx, compose); ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, compose); result = EINA_TRUE; } free(compose); free(unicode); } } return result; #else (void)ctx; (void)type; (void)event; return EINA_FALSE; #endif }
static void _ecore_imf_context_xim_reset(Ecore_IMF_Context *ctx) { EINA_LOG_DBG("%s in", __FUNCTION__); #ifdef ENABLE_XIM XIC ic; Ecore_IMF_Context_Data *imf_context_data; char *result; /* restore conversion state after resetting ic later */ XIMPreeditState preedit_state = XIMPreeditUnKnown; XVaNestedList preedit_attr; Eina_Bool have_preedit_state = EINA_FALSE; imf_context_data = ecore_imf_context_data_get(ctx); EINA_SAFETY_ON_NULL_RETURN(imf_context_data); ic = imf_context_data->ic; if (!ic) return; if (imf_context_data->preedit_length == 0) return; preedit_attr = XVaCreateNestedList(0, XNPreeditState, &preedit_state, NULL); if (!XGetICValues(ic, XNPreeditAttributes, preedit_attr, NULL)) have_preedit_state = EINA_TRUE; XFree(preedit_attr); result = XmbResetIC(ic); preedit_attr = XVaCreateNestedList(0, XNPreeditState, preedit_state, NULL); if (have_preedit_state) XSetICValues(ic, XNPreeditAttributes, preedit_attr, NULL); XFree(preedit_attr); if (imf_context_data->feedbacks) { free(imf_context_data->feedbacks); imf_context_data->feedbacks = NULL; } if (imf_context_data->preedit_length) { imf_context_data->preedit_length = 0; free(imf_context_data->preedit_chars); imf_context_data->preedit_chars = NULL; ecore_imf_context_preedit_changed_event_add(ctx); ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); } if (result) { char *result_utf8 = strdup(result); if (result_utf8) { ecore_imf_context_commit_event_add(ctx, result_utf8); ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, result_utf8); free(result_utf8); } } XFree(result); #else (void)ctx; #endif }