/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ #include #include "ibus.h" static IBusBus *bus; #define BEFORE_ENGINE "xkb:us::eng" #define AFTER_ENGINE "xkb:jp::jpn" static const gchar *engine_names[] = { BEFORE_ENGINE, AFTER_ENGINE }; static const gchar *engine_names2[] = { AFTER_ENGINE, BEFORE_ENGINE }; static void change_global_engine (gboolean reverse) { gint i; for (i = 0; i < G_N_ELEMENTS (engine_names); i++) { const gchar *engine_name = engine_names[i]; if (reverse) engine_name = engine_names2[i]; ibus_bus_set_global_engine (bus, engine_name); IBusEngineDesc *engine_desc = ibus_bus_get_global_engine (bus); g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, engine_name); g_object_unref (G_OBJECT (engine_desc)); } } static void change_context_engine (IBusInputContext *context) { gint i; for (i = 0; i < G_N_ELEMENTS (engine_names); i++) { ibus_input_context_set_engine (context, engine_names[i]); IBusEngineDesc *engine_desc = ibus_input_context_get_engine (context); g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, engine_names[i]); } } typedef struct { gint count; guint timeout_id; guint idle_id; gboolean reverse; } GlobalEngineChangedData; static void global_engine_changed_cb (IBusBus *bus, gchar *name, gpointer user_data) { GlobalEngineChangedData *data = (GlobalEngineChangedData *) user_data; if (data->count++ == 0) ibus_quit (); } static gboolean timeout_cb (gpointer user_data) { GlobalEngineChangedData *data = (GlobalEngineChangedData *) user_data; if (data->count == 0) ibus_quit (); data->timeout_id = 0; return FALSE; } static gboolean change_global_engine_cb (gpointer user_data) { GlobalEngineChangedData *data = (GlobalEngineChangedData *) user_data; change_global_engine (data->reverse); data->idle_id = 0; return FALSE; } static void test_global_engine (void) { GLogLevelFlags flags; IBusEngineDesc *desc; GlobalEngineChangedData data; guint handler_id; if (!ibus_bus_get_use_global_engine (bus)) return; /* "No global engine." warning is not critical message. */ flags = g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); desc = ibus_bus_get_global_engine (bus); g_log_set_always_fatal (flags); if (desc && !g_strcmp0 (BEFORE_ENGINE, ibus_engine_desc_get_name (desc))) { data.reverse = TRUE; } else { data.reverse = FALSE; } data.count = 0; handler_id = g_signal_connect (bus, "global-engine-changed", G_CALLBACK (global_engine_changed_cb), &data); data.timeout_id = g_timeout_add_seconds (1, timeout_cb, &data); data.idle_id = g_idle_add ((GSourceFunc) change_global_engine_cb, &data); ibus_main (); g_assert_cmpint (data.count, ==, G_N_ELEMENTS (engine_names)); if (data.idle_id > 0) g_source_remove (data.idle_id); if (data.timeout_id > 0) g_source_remove (data.timeout_id); g_signal_handler_disconnect (bus, handler_id); } static void test_context_engine (void) { IBusEngineDesc *engine_desc; IBusInputContext *context; if (ibus_bus_get_use_global_engine (bus)) return; context = ibus_bus_create_input_context (bus, "test"); ibus_input_context_set_capabilities (context, IBUS_CAP_FOCUS); /* ibus_bus_set_global_engine() changes focused context engine. */ ibus_input_context_focus_in (context); change_context_engine (context); engine_desc = ibus_input_context_get_engine (context); g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, AFTER_ENGINE); g_object_unref (context); } static void test_context_engine_set_by_global (void) { IBusEngineDesc *engine_desc; IBusInputContext *context; if (!ibus_bus_get_use_global_engine (bus)) return; context = ibus_bus_create_input_context (bus, "test"); ibus_input_context_set_capabilities (context, IBUS_CAP_FOCUS); /* ibus_bus_set_global_engine() changes focused context engine. */ ibus_input_context_focus_in (context); change_global_engine (FALSE); /* ibus_input_context_set_engine() does not take effect when global engine is used. */ ibus_input_context_set_engine (context, BEFORE_ENGINE); engine_desc = ibus_input_context_get_engine (context); g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, AFTER_ENGINE); g_object_unref (context); } static void test_context_engine_set_by_focus (void) { IBusEngineDesc *engine_desc; IBusInputContext *context, *another_context; if (!ibus_bus_get_use_global_engine (bus)) return; context = ibus_bus_create_input_context (bus, "test"); ibus_input_context_set_capabilities (context, IBUS_CAP_FOCUS); another_context = ibus_bus_create_input_context (bus, "another"); ibus_input_context_set_capabilities (another_context, IBUS_CAP_FOCUS); ibus_input_context_focus_in (context); change_global_engine (FALSE); /* When focus is lost, context engine is set to "dummy". */ ibus_input_context_focus_in (another_context); engine_desc = ibus_input_context_get_engine (context); g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, "dummy"); engine_desc = ibus_input_context_get_engine (another_context); g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, AFTER_ENGINE); g_object_unref (context); g_object_unref (another_context); } gint main (gint argc, gchar **argv) { gint result; ibus_init (); g_test_init (&argc, &argv, NULL); bus = ibus_bus_new (); g_object_unref (bus); bus = ibus_bus_new (); // crosbug.com/17293 ibus_bus_set_watch_ibus_signal (bus, TRUE); g_test_add_func ("/ibus/engine-switch/global-engine", test_global_engine); g_test_add_func ("/ibus/engine-switch/context-engine", test_context_engine); g_test_add_func ("/ibus/engine-switch/context-engine-set-by-global", test_context_engine_set_by_global); g_test_add_func ("/ibus/engine-switch/context-engine-set-by-focus", test_context_engine_set_by_focus); result = g_test_run (); g_object_unref (bus); return result; }