1 /* vim:set et sts=4: */
16 typedef struct _IBusHangulEngine IBusHangulEngine;
17 typedef struct _IBusHangulEngineClass IBusHangulEngineClass;
19 struct _IBusHangulEngine {
23 HangulInputContext *context;
27 HanjaList* hanja_list;
29 IBusLookupTable *table;
31 IBusProperty *prop_hanja_mode;
32 IBusPropList *prop_list;
35 struct _IBusHangulEngineClass {
36 IBusEngineClass parent;
44 /* functions prototype */
45 static void ibus_hangul_engine_class_init
46 (IBusHangulEngineClass *klass);
47 static void ibus_hangul_engine_init (IBusHangulEngine *hangul);
49 ibus_hangul_engine_constructor
51 guint n_construct_params,
52 GObjectConstructParam *construct_params);
53 static void ibus_hangul_engine_destroy (IBusHangulEngine *hangul);
55 ibus_hangul_engine_process_key_event
60 static void ibus_hangul_engine_focus_in (IBusEngine *engine);
61 static void ibus_hangul_engine_focus_out (IBusEngine *engine);
62 static void ibus_hangul_engine_reset (IBusEngine *engine);
63 static void ibus_hangul_engine_enable (IBusEngine *engine);
64 static void ibus_hangul_engine_disable (IBusEngine *engine);
66 static void ibus_engine_set_cursor_location (IBusEngine *engine,
71 static void ibus_hangul_engine_set_capabilities
75 static void ibus_hangul_engine_page_up (IBusEngine *engine);
76 static void ibus_hangul_engine_page_down (IBusEngine *engine);
77 static void ibus_hangul_engine_cursor_up (IBusEngine *engine);
78 static void ibus_hangul_engine_cursor_down (IBusEngine *engine);
79 static void ibus_hangul_engine_property_activate
81 const gchar *prop_name,
84 static void ibus_hangul_engine_property_show
86 const gchar *prop_name);
87 static void ibus_hangul_engine_property_hide
89 const gchar *prop_name);
92 static void ibus_hangul_engine_candidate_clicked
98 static void ibus_hangul_engine_flush (IBusHangulEngine *hangul);
99 static void ibus_hangul_engine_update_preedit_text
100 (IBusHangulEngine *hangul);
102 static void ibus_hangul_engine_update_lookup_table
103 (IBusHangulEngine *hangul);
104 static void ibus_config_value_changed (IBusConfig *config,
105 const gchar *section,
110 static void lookup_table_set_visible (IBusLookupTable *table,
112 static gboolean lookup_table_is_visible
113 (IBusLookupTable *table);
115 static void key_event_list_set (GArray *list,
117 static gboolean key_event_list_match (GArray *list,
121 static IBusEngineClass *parent_class = NULL;
122 static HanjaTable *hanja_table = NULL;
123 static HanjaTable *symbol_table = NULL;
124 static IBusConfig *config = NULL;
125 static GString *hangul_keyboard = NULL;
126 static GArray *hanja_keys = NULL;
127 static int lookup_table_orientation = 0;
130 ibus_hangul_engine_get_type (void)
132 static GType type = 0;
134 static const GTypeInfo type_info = {
135 sizeof (IBusHangulEngineClass),
136 (GBaseInitFunc) NULL,
137 (GBaseFinalizeFunc) NULL,
138 (GClassInitFunc) ibus_hangul_engine_class_init,
141 sizeof (IBusHangulEngine),
143 (GInstanceInitFunc) ibus_hangul_engine_init,
147 type = g_type_register_static (IBUS_TYPE_ENGINE,
157 ibus_hangul_init (IBusBus *bus)
160 GValue value = { 0, };
162 hanja_table = hanja_table_load (NULL);
164 symbol_table = hanja_table_load (IBUSHANGUL_DATADIR "/data/symbol.txt");
166 config = ibus_bus_get_config (bus);
168 g_object_ref_sink (config);
170 hangul_keyboard = g_string_new_len ("2", 8);
171 res = ibus_config_get_value (config, "engine/Hangul",
172 "HangulKeyboard", &value);
174 const gchar* str = g_value_get_string (&value);
175 g_string_assign (hangul_keyboard, str);
176 g_value_unset(&value);
179 hanja_keys = g_array_sized_new(FALSE, TRUE, sizeof(struct KeyEvent), 4);
180 res = ibus_config_get_value (config, "engine/Hangul",
181 "HanjaKeys", &value);
183 const gchar* str = g_value_get_string (&value);
184 key_event_list_set(hanja_keys, str);
185 g_value_unset(&value);
189 ev.keyval = IBUS_Hangul_Hanja;
191 g_array_append_val(hanja_keys, ev);
195 g_array_append_val(hanja_keys, ev);
200 ibus_hangul_exit (void)
202 hanja_table_delete (hanja_table);
205 hanja_table_delete (symbol_table);
208 g_object_unref (config);
211 g_string_free (hangul_keyboard, TRUE);
212 hangul_keyboard = NULL;
216 ibus_hangul_engine_class_init (IBusHangulEngineClass *klass)
218 GObjectClass *object_class = G_OBJECT_CLASS (klass);
219 IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
220 IBusEngineClass *engine_class = IBUS_ENGINE_CLASS (klass);
222 parent_class = (IBusEngineClass *) g_type_class_peek_parent (klass);
224 object_class->constructor = ibus_hangul_engine_constructor;
225 ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_hangul_engine_destroy;
227 engine_class->process_key_event = ibus_hangul_engine_process_key_event;
229 engine_class->reset = ibus_hangul_engine_reset;
230 engine_class->enable = ibus_hangul_engine_enable;
231 engine_class->disable = ibus_hangul_engine_disable;
233 engine_class->focus_in = ibus_hangul_engine_focus_in;
234 engine_class->focus_out = ibus_hangul_engine_focus_out;
236 engine_class->page_up = ibus_hangul_engine_page_up;
237 engine_class->page_down = ibus_hangul_engine_page_down;
239 engine_class->cursor_up = ibus_hangul_engine_cursor_up;
240 engine_class->cursor_down = ibus_hangul_engine_cursor_down;
242 engine_class->property_activate = ibus_hangul_engine_property_activate;
244 engine_class->candidate_clicked = ibus_hangul_engine_candidate_clicked;
248 ibus_hangul_engine_init (IBusHangulEngine *hangul)
254 hangul->context = hangul_ic_new (hangul_keyboard->str);
255 hangul->preedit = ustring_new();
256 hangul->hanja_list = NULL;
257 hangul->hangul_mode = TRUE;
258 hangul->hanja_mode = FALSE;
260 hangul->prop_list = ibus_prop_list_new ();
261 g_object_ref_sink (hangul->prop_list);
263 label = ibus_text_new_from_string (_("Hanja lock"));
264 tooltip = ibus_text_new_from_string (_("Enable/Disable Hanja mode"));
265 prop = ibus_property_new ("hanja_mode",
270 TRUE, TRUE, PROP_STATE_UNCHECKED, NULL);
271 g_object_ref_sink (prop);
272 ibus_prop_list_append (hangul->prop_list, prop);
273 hangul->prop_hanja_mode = prop;
275 label = ibus_text_new_from_string (_("Setup"));
276 tooltip = ibus_text_new_from_string (_("Configure hangul engine"));
277 prop = ibus_property_new ("setup",
282 TRUE, TRUE, PROP_STATE_UNCHECKED, NULL);
283 ibus_prop_list_append (hangul->prop_list, prop);
285 hangul->table = ibus_lookup_table_new (9, 0, TRUE, FALSE);
286 g_object_ref_sink (hangul->table);
288 g_signal_connect (config, "value-changed",
289 G_CALLBACK(ibus_config_value_changed), hangul);
293 ibus_hangul_engine_constructor (GType type,
294 guint n_construct_params,
295 GObjectConstructParam *construct_params)
297 IBusHangulEngine *hangul;
299 hangul = (IBusHangulEngine *) G_OBJECT_CLASS (parent_class)->constructor (type,
303 return (GObject *)hangul;
308 ibus_hangul_engine_destroy (IBusHangulEngine *hangul)
310 if (hangul->prop_hanja_mode) {
311 g_object_unref (hangul->prop_hanja_mode);
312 hangul->prop_hanja_mode = NULL;
315 if (hangul->prop_list) {
316 g_object_unref (hangul->prop_list);
317 hangul->prop_list = NULL;
321 g_object_unref (hangul->table);
322 hangul->table = NULL;
325 if (hangul->context) {
326 hangul_ic_delete (hangul->context);
327 hangul->context = NULL;
330 IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *)hangul);
334 ibus_hangul_engine_update_preedit_text (IBusHangulEngine *hangul)
336 const ucschar *hic_preedit;
341 // ibus-hangul's preedit string is made up of ibus context's
342 // internal preedit string and libhangul's preedit string.
343 // libhangul only supports one syllable preedit string.
344 // In order to make longer preedit string, ibus-hangul maintains
345 // internal preedit string.
346 hic_preedit = hangul_ic_get_preedit_string (hangul->context);
348 preedit = ustring_dup (hangul->preedit);
349 preedit_len = ustring_length(preedit);
350 ustring_append_ucs4 (preedit, hic_preedit, -1);
352 if (ustring_length(preedit) > 0) {
353 text = ibus_text_new_from_ucs4 ((gunichar*)preedit->data);
354 // ibus-hangul's internal preedit string
355 ibus_text_append_attribute (text, IBUS_ATTR_TYPE_UNDERLINE,
356 IBUS_ATTR_UNDERLINE_SINGLE, 0, preedit_len);
357 // Preedit string from libhangul context.
358 // This is currently composing syllable.
359 ibus_text_append_attribute (text, IBUS_ATTR_TYPE_FOREGROUND,
360 0x00ffffff, preedit_len, -1);
361 ibus_text_append_attribute (text, IBUS_ATTR_TYPE_BACKGROUND,
362 0x00000000, preedit_len, -1);
363 ibus_engine_update_preedit_text_with_mode ((IBusEngine *)hangul,
365 ibus_text_get_length (text),
367 IBUS_ENGINE_PREEDIT_COMMIT);
369 text = ibus_text_new_from_static_string ("");
370 ibus_engine_update_preedit_text ((IBusEngine *)hangul, text, 0, FALSE);
373 ustring_delete(preedit);
377 ibus_hangul_engine_update_lookup_table_ui (IBusHangulEngine *hangul)
384 cursor_pos = ibus_lookup_table_get_cursor_pos (hangul->table);
385 comment = hanja_list_get_nth_comment (hangul->hanja_list, cursor_pos);
387 text = ibus_text_new_from_string (comment);
388 ibus_engine_update_auxiliary_text ((IBusEngine *)hangul, text, TRUE);
390 // update lookup table
391 ibus_engine_update_lookup_table ((IBusEngine *)hangul, hangul->table, TRUE);
395 ibus_hangul_engine_commit_current_candidate (IBusHangulEngine *hangul)
406 cursor_pos = ibus_lookup_table_get_cursor_pos (hangul->table);
407 key = hanja_list_get_nth_key (hangul->hanja_list, cursor_pos);
408 value = hanja_list_get_nth_value (hangul->hanja_list, cursor_pos);
410 key_len = g_utf8_strlen(key, -1);
411 preedit_len = ustring_length(hangul->preedit);
413 len = MIN(key_len, preedit_len);
414 ustring_erase (hangul->preedit, 0, len);
415 if (key_len > preedit_len)
416 hangul_ic_reset (hangul->context);
418 ibus_hangul_engine_update_preedit_text (hangul);
420 text = ibus_text_new_from_string (value);
421 ibus_engine_commit_text ((IBusEngine *)hangul, text);
425 ibus_hangul_engine_update_hanja_list (IBusHangulEngine *hangul)
428 const ucschar* hic_preedit;
431 if (hangul->hanja_list != NULL) {
432 hanja_list_delete (hangul->hanja_list);
433 hangul->hanja_list = NULL;
436 hic_preedit = hangul_ic_get_preedit_string (hangul->context);
438 preedit = ustring_dup (hangul->preedit);
439 ustring_append_ucs4 (preedit, hic_preedit, -1);
440 if (ustring_length(preedit) > 0) {
441 utf8 = ustring_to_utf8 (preedit, -1);
443 if (symbol_table != NULL)
444 hangul->hanja_list = hanja_table_match_prefix (symbol_table, utf8);
445 if (hangul->hanja_list == NULL)
446 hangul->hanja_list = hanja_table_match_prefix (hanja_table, utf8);
451 ustring_delete (preedit);
456 ibus_hangul_engine_apply_hanja_list (IBusHangulEngine *hangul)
458 HanjaList* list = hangul->hanja_list;
461 n = hanja_list_get_size (list);
463 ibus_lookup_table_clear (hangul->table);
464 for (i = 0; i < n; i++) {
465 const char* value = hanja_list_get_nth_value (list, i);
466 IBusText* text = ibus_text_new_from_string (value);
467 ibus_lookup_table_append_candidate (hangul->table, text);
470 ibus_lookup_table_set_cursor_pos (hangul->table, 0);
471 ibus_hangul_engine_update_lookup_table_ui (hangul);
472 lookup_table_set_visible (hangul->table, TRUE);
477 ibus_hangul_engine_hide_lookup_table (IBusHangulEngine *hangul)
480 is_visible = lookup_table_is_visible (hangul->table);
482 // Sending hide lookup table message when the lookup table
483 // is not visible results wrong behavior. So I have to check
484 // whether the table is visible or not before to hide.
486 ibus_engine_hide_lookup_table ((IBusEngine *)hangul);
487 ibus_engine_hide_auxiliary_text ((IBusEngine *)hangul);
488 lookup_table_set_visible (hangul->table, FALSE);
491 if (hangul->hanja_list != NULL) {
492 hanja_list_delete (hangul->hanja_list);
493 hangul->hanja_list = NULL;
498 ibus_hangul_engine_update_lookup_table (IBusHangulEngine *hangul)
500 ibus_hangul_engine_update_hanja_list (hangul);
502 if (hangul->hanja_list != NULL) {
503 ibus_hangul_engine_apply_hanja_list (hangul);
505 ibus_hangul_engine_hide_lookup_table (hangul);
510 ibus_hangul_engine_process_candidate_key_event (IBusHangulEngine *hangul,
514 if (keyval == IBUS_Escape) {
515 ibus_hangul_engine_hide_lookup_table (hangul);
517 } else if (keyval == IBUS_Return) {
518 ibus_hangul_engine_commit_current_candidate (hangul);
520 if (hangul->hanja_mode) {
521 ibus_hangul_engine_update_lookup_table (hangul);
523 ibus_hangul_engine_hide_lookup_table (hangul);
526 } else if (keyval >= IBUS_1 && keyval <= IBUS_9) {
531 page_size = ibus_lookup_table_get_page_size (hangul->table);
532 cursor_pos = ibus_lookup_table_get_cursor_pos (hangul->table);
533 page_no = cursor_pos / page_size;
535 cursor_pos = page_no * page_size + (keyval - IBUS_1);
536 ibus_lookup_table_set_cursor_pos (hangul->table, cursor_pos);
538 ibus_hangul_engine_commit_current_candidate (hangul);
540 if (hangul->hanja_mode) {
541 ibus_hangul_engine_update_lookup_table (hangul);
543 ibus_hangul_engine_hide_lookup_table (hangul);
546 } else if (keyval == IBUS_Page_Up) {
547 ibus_lookup_table_page_up (hangul->table);
548 ibus_hangul_engine_update_lookup_table_ui (hangul);
550 } else if (keyval == IBUS_Page_Down) {
551 ibus_lookup_table_page_down (hangul->table);
552 ibus_hangul_engine_update_lookup_table_ui (hangul);
555 if (lookup_table_orientation == 0) {
557 if (keyval == IBUS_Left) {
558 ibus_lookup_table_cursor_up (hangul->table);
559 ibus_hangul_engine_update_lookup_table_ui (hangul);
561 } else if (keyval == IBUS_Right) {
562 ibus_lookup_table_cursor_down (hangul->table);
563 ibus_hangul_engine_update_lookup_table_ui (hangul);
565 } else if (keyval == IBUS_Up) {
566 ibus_lookup_table_page_up (hangul->table);
567 ibus_hangul_engine_update_lookup_table_ui (hangul);
569 } else if (keyval == IBUS_Down) {
570 ibus_lookup_table_page_down (hangul->table);
571 ibus_hangul_engine_update_lookup_table_ui (hangul);
576 if (keyval == IBUS_Left) {
577 ibus_lookup_table_page_up (hangul->table);
578 ibus_hangul_engine_update_lookup_table_ui (hangul);
580 } else if (keyval == IBUS_Right) {
581 ibus_lookup_table_page_down (hangul->table);
582 ibus_hangul_engine_update_lookup_table_ui (hangul);
584 } else if (keyval == IBUS_Up) {
585 ibus_lookup_table_cursor_up (hangul->table);
586 ibus_hangul_engine_update_lookup_table_ui (hangul);
588 } else if (keyval == IBUS_Down) {
589 ibus_lookup_table_cursor_down (hangul->table);
590 ibus_hangul_engine_update_lookup_table_ui (hangul);
596 if (!hangul->hanja_mode) {
597 if (lookup_table_orientation == 0) {
599 if (keyval == IBUS_h) {
600 ibus_lookup_table_cursor_up (hangul->table);
601 ibus_hangul_engine_update_lookup_table_ui (hangul);
603 } else if (keyval == IBUS_l) {
604 ibus_lookup_table_cursor_down (hangul->table);
605 ibus_hangul_engine_update_lookup_table_ui (hangul);
607 } else if (keyval == IBUS_k) {
608 ibus_lookup_table_page_up (hangul->table);
609 ibus_hangul_engine_update_lookup_table_ui (hangul);
611 } else if (keyval == IBUS_j) {
612 ibus_lookup_table_page_down (hangul->table);
613 ibus_hangul_engine_update_lookup_table_ui (hangul);
618 if (keyval == IBUS_h) {
619 ibus_lookup_table_page_up (hangul->table);
620 ibus_hangul_engine_update_lookup_table_ui (hangul);
622 } else if (keyval == IBUS_l) {
623 ibus_lookup_table_page_down (hangul->table);
624 ibus_hangul_engine_update_lookup_table_ui (hangul);
626 } else if (keyval == IBUS_k) {
627 ibus_lookup_table_cursor_up (hangul->table);
628 ibus_hangul_engine_update_lookup_table_ui (hangul);
630 } else if (keyval == IBUS_j) {
631 ibus_lookup_table_cursor_down (hangul->table);
632 ibus_hangul_engine_update_lookup_table_ui (hangul);
642 ibus_hangul_engine_process_key_event (IBusEngine *engine,
647 IBusHangulEngine *hangul = (IBusHangulEngine *) engine;
652 if (modifiers & IBUS_RELEASE_MASK)
655 // if we don't ignore shift keys, shift key will make flush the preedit
656 // string. So you cannot input shift+key.
657 // Let's think about these examples:
660 if (keyval == IBUS_Shift_L || keyval == IBUS_Shift_R)
663 if (key_event_list_match(hanja_keys, keyval, modifiers)) {
664 if (hangul->hanja_list == NULL) {
665 ibus_hangul_engine_update_lookup_table (hangul);
667 ibus_hangul_engine_hide_lookup_table (hangul);
672 if (modifiers & (IBUS_CONTROL_MASK | IBUS_MOD1_MASK))
675 if (hangul->hanja_list != NULL) {
676 retval = ibus_hangul_engine_process_candidate_key_event (hangul,
678 if (hangul->hanja_mode) {
686 if (keyval == IBUS_BackSpace) {
687 retval = hangul_ic_backspace (hangul->context);
690 if (modifiers & IBUS_LOCK_MASK) {
691 if (keyval >= 'A' && keyval <= 'z') {
693 keyval = tolower(keyval);
695 keyval = toupper(keyval);
698 retval = hangul_ic_process (hangul->context, keyval);
701 str = hangul_ic_get_commit_string (hangul->context);
702 if (hangul->hanja_mode) {
703 const ucschar* hic_preedit;
705 hic_preedit = hangul_ic_get_preedit_string (hangul->context);
706 if (hic_preedit != NULL && hic_preedit[0] != 0) {
707 ustring_append_ucs4 (hangul->preedit, str, -1);
710 const ucschar* preedit;
712 ustring_append_ucs4 (hangul->preedit, str, -1);
713 if (ustring_length (hangul->preedit) > 0) {
714 preedit = ustring_begin (hangul->preedit);
715 text = ibus_text_new_from_ucs4 ((gunichar*)preedit);
716 ibus_engine_commit_text (engine, text);
718 ustring_clear (hangul->preedit);
721 if (str != NULL && str[0] != 0) {
722 IBusText *text = ibus_text_new_from_ucs4 (str);
723 ibus_engine_commit_text (engine, text);
727 ibus_hangul_engine_update_preedit_text (hangul);
729 if (hangul->hanja_mode) {
730 ibus_hangul_engine_update_lookup_table (hangul);
734 ibus_hangul_engine_flush (hangul);
740 ibus_hangul_engine_flush (IBusHangulEngine *hangul)
745 ibus_hangul_engine_hide_lookup_table (hangul);
747 str = hangul_ic_flush (hangul->context);
749 ustring_append_ucs4 (hangul->preedit, str, -1);
751 if (ustring_length (hangul->preedit) == 0)
754 str = ustring_begin (hangul->preedit);
755 text = ibus_text_new_from_ucs4 (str);
757 ibus_engine_hide_preedit_text ((IBusEngine *) hangul);
758 // Use ibus_engine_update_preedit_text_with_mode instead.
759 //ibus_engine_commit_text ((IBusEngine *) hangul, text);
761 ustring_clear(hangul->preedit);
765 ibus_hangul_engine_focus_in (IBusEngine *engine)
767 IBusHangulEngine *hangul = (IBusHangulEngine *) engine;
769 if (hangul->hanja_mode) {
770 hangul->prop_hanja_mode->state = PROP_STATE_CHECKED;
772 hangul->prop_hanja_mode->state = PROP_STATE_UNCHECKED;
775 ibus_engine_register_properties (engine, hangul->prop_list);
777 if (hangul->hanja_list != NULL) {
778 ibus_hangul_engine_update_lookup_table_ui (hangul);
781 parent_class->focus_in (engine);
785 ibus_hangul_engine_focus_out (IBusEngine *engine)
787 IBusHangulEngine *hangul = (IBusHangulEngine *) engine;
789 if (hangul->hanja_list == NULL) {
790 ibus_hangul_engine_flush (hangul);
792 ibus_engine_hide_lookup_table (engine);
793 ibus_engine_hide_auxiliary_text (engine);
796 parent_class->focus_out ((IBusEngine *) hangul);
800 ibus_hangul_engine_reset (IBusEngine *engine)
802 IBusHangulEngine *hangul = (IBusHangulEngine *) engine;
804 ibus_hangul_engine_flush (hangul);
805 if (hangul->hanja_list != NULL) {
806 ibus_hangul_engine_hide_lookup_table (hangul);
808 parent_class->reset (engine);
812 ibus_hangul_engine_enable (IBusEngine *engine)
814 parent_class->enable (engine);
818 ibus_hangul_engine_disable (IBusEngine *engine)
820 ibus_hangul_engine_focus_out (engine);
821 parent_class->disable (engine);
825 ibus_hangul_engine_page_up (IBusEngine *engine)
827 parent_class->page_up (engine);
831 ibus_hangul_engine_page_down (IBusEngine *engine)
833 parent_class->page_down (engine);
837 ibus_hangul_engine_cursor_up (IBusEngine *engine)
839 IBusHangulEngine *hangul = (IBusHangulEngine *) engine;
841 if (hangul->hanja_list != NULL) {
842 ibus_lookup_table_cursor_up (hangul->table);
843 ibus_hangul_engine_update_lookup_table_ui (hangul);
846 parent_class->cursor_up (engine);
850 ibus_hangul_engine_cursor_down (IBusEngine *engine)
852 IBusHangulEngine *hangul = (IBusHangulEngine *) engine;
854 if (hangul->hanja_list != NULL) {
855 ibus_lookup_table_cursor_down (hangul->table);
856 ibus_hangul_engine_update_lookup_table_ui (hangul);
859 parent_class->cursor_down (engine);
863 ibus_hangul_engine_property_activate (IBusEngine *engine,
864 const gchar *prop_name,
867 if (strcmp(prop_name, "setup") == 0) {
868 GError *error = NULL;
869 gchar *argv[2] = { NULL, };
871 const char* libexecdir;
873 libexecdir = g_getenv("LIBEXECDIR");
874 if (libexecdir == NULL)
875 libexecdir = LIBEXECDIR;
877 path = g_build_filename(libexecdir, "ibus-setup-hangul", NULL);
880 g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, NULL, &error);
883 } else if (strcmp(prop_name, "hanja_mode") == 0) {
884 IBusHangulEngine *hangul = (IBusHangulEngine *) engine;
886 hangul->hanja_mode = !hangul->hanja_mode;
887 if (hangul->hanja_mode) {
888 hangul->prop_hanja_mode->state = PROP_STATE_CHECKED;
890 hangul->prop_hanja_mode->state = PROP_STATE_UNCHECKED;
893 ibus_engine_update_property (engine, hangul->prop_hanja_mode);
894 ibus_hangul_engine_flush (hangul);
899 ibus_config_value_changed (IBusConfig *config,
900 const gchar *section,
905 IBusHangulEngine *hangul = (IBusHangulEngine *) user_data;
907 if (strcmp(section, "engine/Hangul") == 0) {
908 if (strcmp(name, "HangulKeyboard") == 0) {
909 const gchar *str = g_value_get_string (value);
910 g_string_assign (hangul_keyboard, str);
911 hangul_ic_select_keyboard (hangul->context, hangul_keyboard->str);
912 } else if (strcmp(name, "HanjaKeys") == 0) {
913 const gchar* str = g_value_get_string (value);
914 key_event_list_set(hanja_keys, str);
916 } else if (strcmp(section, "panel") == 0) {
917 if (strcmp(name, "lookup_table_orientation") == 0) {
918 lookup_table_orientation = g_value_get_int (value);
924 lookup_table_set_visible (IBusLookupTable *table, gboolean flag)
926 g_object_set_data (G_OBJECT(table), "visible", GUINT_TO_POINTER(flag));
930 lookup_table_is_visible (IBusLookupTable *table)
932 gpointer res = g_object_get_data (G_OBJECT(table), "visible");
933 return GPOINTER_TO_UINT(res);
937 key_event_list_set (GArray* list, const char* str)
939 gchar** items = g_strsplit(str, ",", 0);
941 g_array_set_size(list, 0);
945 for (i = 0; items[i] != NULL; ++i) {
949 res = ibus_key_event_from_string(items[i], &keyval, &modifiers);
951 struct KeyEvent ev = { keyval, modifiers };
952 g_array_append_val(list, ev);
960 key_event_list_match(GArray* list, guint keyval, guint modifiers)
965 /* ignore capslock and numlock */
966 mask = IBUS_SHIFT_MASK |
974 for (i = 0; i < list->len; ++i) {
975 struct KeyEvent* ev = &g_array_index(list, struct KeyEvent, i);
976 if (ev->keyval == keyval && ev->modifiers == modifiers) {
985 ibus_hangul_engine_candidate_clicked (IBusEngine *engine,
990 IBusHangulEngine *hangul = (IBusHangulEngine *) engine;
994 if (hangul->table == NULL)
997 ibus_lookup_table_set_cursor_pos (hangul->table, index);
998 ibus_hangul_engine_commit_current_candidate (hangul);
1000 if (hangul->hanja_mode) {
1001 ibus_hangul_engine_update_lookup_table (hangul);
1003 ibus_hangul_engine_hide_lookup_table (hangul);