diff --git a/src/engine.c b/src/engine.c index dcfbe48..85b4baa 100644 --- a/src/engine.c +++ b/src/engine.c @@ -9,6 +9,13 @@ typedef struct _IBusM17NEngine IBusM17NEngine; typedef struct _IBusM17NEngineClass IBusM17NEngineClass; +enum IBusM17NFocusState { + NO_FOCUS, + GOT_FOCUS, + HAS_FOCUS, + LOST_FOCUS +}; + struct _IBusM17NEngine { IBusEngine parent; @@ -17,6 +24,8 @@ struct _IBusM17NEngine { IBusLookupTable *table; IBusProperty *status_prop; IBusPropList *prop_list; + enum IBusM17NFocusState focus_state; + gint cursor_pos; }; struct _IBusM17NEngineClass { @@ -42,7 +51,8 @@ static void ibus_m17n_engine_focus_out (IBusEngine *engine); static void ibus_m17n_engine_reset (IBusEngine *engine); static void ibus_m17n_engine_enable (IBusEngine *engine); static void ibus_m17n_engine_disable (IBusEngine *engine); -static void ibus_engine_set_cursor_location (IBusEngine *engine, +static void ibus_m17n_engine_set_cursor_location + (IBusEngine *engine, gint x, gint y, gint w, @@ -129,6 +139,8 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass) engine_class->cursor_down = ibus_m17n_engine_cursor_down; engine_class->property_activate = ibus_m17n_engine_property_activate; + + engine_class->set_cursor_location = ibus_m17n_engine_set_cursor_location; } static void @@ -152,6 +164,8 @@ ibus_m17n_engine_init (IBusM17NEngine *m17n) m17n->table = ibus_lookup_table_new (9, 0, TRUE, TRUE); g_object_ref_sink (m17n->table); m17n->context = NULL; + m17n->focus_state = NO_FOCUS; + m17n->cursor_pos = 0; } static GObject* @@ -254,12 +268,31 @@ ibus_m17n_engine_destroy (IBusM17NEngine *m17n) } static void +ibus_m17n_engine_update_preedit (IBusM17NEngine *m17n) +{ + IBusText *text; + gchar *buf; + + buf = ibus_m17n_mtext_to_utf8 (m17n->context->preedit); + if (buf) { + text = ibus_text_new_from_static_string (buf); + ibus_text_append_attribute (text, IBUS_ATTR_TYPE_FOREGROUND, 0x00ffffff, 0, -1); + ibus_text_append_attribute (text, IBUS_ATTR_TYPE_BACKGROUND, 0x00000000, 0, -1); + ibus_engine_update_preedit_text ((IBusEngine *) m17n, + text, + m17n->context->cursor_pos, + mtext_len (m17n->context->preedit) > 0); + } +} + +static void ibus_m17n_engine_commit_string (IBusM17NEngine *m17n, const gchar *string) { IBusText *text; text = ibus_text_new_from_static_string (string); ibus_engine_commit_text ((IBusEngine *)m17n, text); + ibus_m17n_engine_update_preedit (m17n); } MSymbol @@ -337,6 +370,10 @@ ibus_m17n_engine_process_key (IBusM17NEngine *m17n, MText *produced; gint retval; + /* XXX: mark as the IME just got focus to prevent + "input-focus-move" being sent as a result of key event. */ + m17n->focus_state = GOT_FOCUS; + retval = minput_filter (m17n->context, key, NULL); if (retval) { @@ -387,6 +424,7 @@ ibus_m17n_engine_focus_in (IBusEngine *engine) ibus_engine_register_properties (engine, m17n->prop_list); ibus_m17n_engine_process_key (m17n, msymbol ("input-focus-in")); + m17n->focus_state = GOT_FOCUS; parent_class->focus_in (engine); } @@ -397,6 +435,7 @@ ibus_m17n_engine_focus_out (IBusEngine *engine) IBusM17NEngine *m17n = (IBusM17NEngine *) engine; ibus_m17n_engine_process_key (m17n, msymbol ("input-focus-out")); + m17n->focus_state = LOST_FOCUS; parent_class->focus_out (engine); } @@ -424,6 +463,7 @@ ibus_m17n_engine_disable (IBusEngine *engine) IBusM17NEngine *m17n = (IBusM17NEngine *) engine; ibus_m17n_engine_focus_out (engine); + m17n->focus_state = NO_FOCUS; parent_class->disable (engine); } @@ -503,14 +543,15 @@ ibus_m17n_engine_update_lookup_table (IBusM17NEngine *m17n) if (mplist_key (group) == Mtext) { MText *mt; - gunichar *buf, *p; + gunichar *buf; + glong nchars, i; mt = (MText *) mplist_value (group); ibus_lookup_table_set_page_size (m17n->table, mtext_len (mt)); - buf = ibus_m17n_mtext_to_ucs4 (mt); - for (p = buf + 1; *p != 0; p++) { - ibus_lookup_table_append_candidate (m17n->table, ibus_text_new_from_unichar (*p)); + buf = ibus_m17n_mtext_to_ucs4 (mt, &nchars); + for (i = 0; i < nchars; i++) { + ibus_lookup_table_append_candidate (m17n->table, ibus_text_new_from_unichar (buf[i])); } g_free (buf); } @@ -546,6 +587,36 @@ ibus_m17n_engine_update_lookup_table (IBusM17NEngine *m17n) } static void +ibus_m17n_engine_set_cursor_location (IBusEngine *engine, + gint x, + gint y, + gint w, + gint h) +{ + IBusM17NEngine *m17n = (IBusM17NEngine *) engine; + + switch (m17n->focus_state) { + case GOT_FOCUS: + m17n->focus_state = HAS_FOCUS; + m17n->cursor_pos = x; + break; + case HAS_FOCUS: + if (m17n->cursor_pos != x) { + ibus_m17n_engine_process_key (m17n, msymbol ("input-focus-move")); + } + m17n->cursor_pos = x; + break; + case LOST_FOCUS: + m17n->focus_state = NO_FOCUS; + break; + default: + break; + } + + parent_class->set_cursor_location (engine, x, y, w, h); +} + +static void ibus_m17n_engine_callback (MInputContext *context, MSymbol command) { @@ -565,19 +636,7 @@ ibus_m17n_engine_callback (MInputContext *context, ibus_engine_hide_preedit_text ((IBusEngine *)m17n); } else if (command == Minput_preedit_draw) { - IBusText *text; - gchar *buf; - - buf = ibus_m17n_mtext_to_utf8 (m17n->context->preedit); - if (buf) { - text = ibus_text_new_from_static_string (buf); - ibus_text_append_attribute (text, IBUS_ATTR_TYPE_FOREGROUND, 0x00ffffff, 0, -1); - ibus_text_append_attribute (text, IBUS_ATTR_TYPE_BACKGROUND, 0x00000000, 0, -1); - ibus_engine_update_preedit_text ((IBusEngine *) m17n, - text, - m17n->context->cursor_pos, - mtext_len (m17n->context->preedit) > 0); - } + ibus_m17n_engine_update_preedit (m17n); } else if (command == Minput_preedit_done) { ibus_engine_hide_preedit_text ((IBusEngine *)m17n); diff --git a/src/m17nutil.c b/src/m17nutil.c index 257f68e..dc2626e 100644 --- a/src/m17nutil.c +++ b/src/m17nutil.c @@ -5,7 +5,6 @@ #define N_(text) text static MConverter *utf8_converter = NULL; -static MConverter *utf32_converter = NULL; static const gchar *keymap[] = { "m17n:as:phonetic", @@ -35,10 +34,6 @@ ibus_m17n_init (void) if (utf8_converter == NULL) { utf8_converter = mconv_buffer_converter (Mcoding_utf_8, NULL, 0); } - - if (utf32_converter == NULL) { - utf32_converter = mconv_buffer_converter (Mcoding_utf_32, NULL, 0); - } } gchar * @@ -64,25 +59,28 @@ ibus_m17n_mtext_to_utf8 (MText *text) } gunichar * -ibus_m17n_mtext_to_ucs4 (MText *text) +ibus_m17n_mtext_to_ucs4 (MText *text, glong *nchars) { - gint bufsize; - gunichar *buf; + glong bufsize; + gchar *buf; + gunichar *ucs; if (text == NULL) return NULL; - mconv_reset_converter (utf32_converter); - - bufsize = (mtext_len (text) + 2) * sizeof (gunichar); - buf = (gunichar *) g_malloc (bufsize); - - mconv_rebind_buffer (utf32_converter, (gchar *)buf, bufsize); - mconv_encode (utf32_converter, text); + mconv_reset_converter (utf8_converter); - buf [utf32_converter->nchars] = 0; + bufsize = (mtext_len (text) + 1) * 6; + buf = (gchar *) g_malloc (bufsize); - return buf; + mconv_rebind_buffer (utf8_converter, buf, bufsize); + if (mconv_encode (utf8_converter, text) < 0) { + g_free (buf); + return NULL; + } + ucs = g_utf8_to_ucs4_fast (buf, bufsize, nchars); + g_free (buf); + return ucs; } static IBusEngineDesc * diff --git a/src/m17nutil.h b/src/m17nutil.h index 82e7e59..707c5cc 100644 --- a/src/m17nutil.h +++ b/src/m17nutil.h @@ -9,5 +9,6 @@ void ibus_m17n_init (void); GList *ibus_m17n_list_engines (void); IBusComponent *ibus_m17n_get_component (void); gchar *ibus_m17n_mtext_to_utf8 (MText *text); -gunichar *ibus_m17n_mtext_to_ucs4 (MText *text); +gunichar *ibus_m17n_mtext_to_ucs4 (MText *text, + glong *nchars); #endif