From 63b857f037c74b6c91a009b59274099909dc21f1 Mon Sep 17 00:00:00 2001 From: Takao Fujiwara Date: Jun 21 2011 08:49:07 +0000 Subject: Added ibus-xx-icon-symbol.patch - Added ibus-xx-bridge-hotkey.patch --- diff --git a/.gitignore b/.gitignore index 58ef980..f33ca6e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ ibus-1.3.6.tar.gz /ibus_master_da.po /ibus-1.3.99.20110419.tar.gz /gnome-shell-ibus-plugins-20110601.tar.bz2 +/gnome-shell-ibus-plugins-20110621.tar.bz2 +/ibus-indicator.tar.bz2 diff --git a/ibus-435880-surrounding-text.patch b/ibus-435880-surrounding-text.patch deleted file mode 100644 index 2bde53c..0000000 --- a/ibus-435880-surrounding-text.patch +++ /dev/null @@ -1,375 +0,0 @@ -From c72e8177099fb9079e2f295c0bb2118b998cb0e8 Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Wed, 13 Apr 2011 16:26:54 +0900 -Subject: [PATCH] Backport caps feature from the Fedora internal patch. - ---- - client/gtk2/ibusimcontext.c | 34 ++++++++++- - src/ibusenginedesc.c | 132 +++++++++++++++++++++++++++++++++++++++++++ - src/ibusenginedesc.h | 11 ++++ - 3 files changed, 173 insertions(+), 4 deletions(-) - -diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c -index dc3640e..0ac1b70 100644 ---- a/client/gtk2/ibusimcontext.c -+++ b/client/gtk2/ibusimcontext.c -@@ -61,6 +61,7 @@ struct _IBusIMContext { - gboolean has_focus; - - guint32 time; -+ guint supported_caps; - gint caps; - - /* cancellable */ -@@ -150,6 +151,7 @@ static gboolean _slave_delete_surrounding_cb - static void _request_surrounding_text (IBusIMContext *context, - gboolean force); - static void _create_fake_input_context (void); -+static void _negotiate_capabilities (IBusIMContext *context); - - - -@@ -580,10 +582,11 @@ ibus_im_context_init (GObject *obj) - ibusimcontext->has_focus = FALSE; - ibusimcontext->time = GDK_CURRENT_TIME; - #ifdef ENABLE_SURROUNDING -- ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT; -+ ibusimcontext->supported_caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT; - #else -- ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS; -+ ibusimcontext->supported_caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS; - #endif -+ ibusimcontext->caps = ibusimcontext->supported_caps; - - - // Create slave im context -@@ -930,6 +933,27 @@ ibus_im_context_set_cursor_location (GtkIMContext *context, GdkRectangle *area) - } - - static void -+_negotiate_capabilities (IBusIMContext *context) -+{ -+ if (context->enable) { -+ IBusEngineDesc *engine = -+ ibus_input_context_get_engine (context->ibuscontext); -+ -+ if (engine) { -+ context->caps = context->supported_caps & -+ ibus_engine_desc_get_requires (engine); -+ ibus_input_context_set_capabilities (context->ibuscontext, -+ context->caps); -+ IDEBUG ("engine %s: supported caps = %u, engine wants = %u, caps = %u", -+ ibus_engine_desc_get_name (engine), -+ context->supported_caps, -+ ibus_engine_desc_get_requires (engine), -+ context->caps); -+ } -+ } -+} -+ -+static void - ibus_im_context_set_use_preedit (GtkIMContext *context, gboolean use_preedit) - { - IDEBUG ("%s", __FUNCTION__); -@@ -938,11 +962,12 @@ ibus_im_context_set_use_preedit (GtkIMContext *context, gboolean use_preedit) - - if(ibusimcontext->ibuscontext) { - if (use_preedit) { -- ibusimcontext->caps |= IBUS_CAP_PREEDIT_TEXT; -+ ibusimcontext->supported_caps |= IBUS_CAP_PREEDIT_TEXT; - } - else { -- ibusimcontext->caps &= ~IBUS_CAP_PREEDIT_TEXT; -+ ibusimcontext->supported_caps &= ~IBUS_CAP_PREEDIT_TEXT; - } -+ _negotiate_capabilities (ibusimcontext); - } - gtk_im_context_set_use_preedit (ibusimcontext->slave, use_preedit); - } -@@ -1320,6 +1345,7 @@ _ibus_context_enabled_cb (IBusInputContext *ibuscontext, - IDEBUG ("%s", __FUNCTION__); - - ibusimcontext->enable = TRUE; -+ _negotiate_capabilities (ibusimcontext); - - /* retrieve the initial surrounding-text (regardless of whether - * the current IBus engine needs surrounding-text) */ -diff --git a/src/ibusenginedesc.c b/src/ibusenginedesc.c -index ca5ef60..956ce73 100644 ---- a/src/ibusenginedesc.c -+++ b/src/ibusenginedesc.c -@@ -22,6 +22,7 @@ - #include - #include "ibusenginedesc.h" - #include "ibusxml.h" -+#include "ibusenumtypes.h" - - enum { - LAST_SIGNAL, -@@ -39,6 +40,7 @@ enum { - PROP_LAYOUT, - PROP_RANK, - PROP_HOTKEYS, -+ PROP_REQUIRES, - }; - - -@@ -54,6 +56,7 @@ struct _IBusEngineDescPrivate { - gchar *layout; - guint rank; - gchar *hotkeys; -+ guint requires; - }; - - #define IBUS_ENGINE_DESC_GET_PRIVATE(o) \ -@@ -79,9 +82,20 @@ static gboolean ibus_engine_desc_copy (IBusEngineDesc *des - const IBusEngineDesc *src); - static gboolean ibus_engine_desc_parse_xml_node (IBusEngineDesc *desc, - XMLNode *node); -+static void ibus_engine_desc_output_capabilities -+ (guint caps, -+ GString *output, -+ gint indent); -+static guint ibus_engine_desc_parse_capabilities -+ (XMLNode *node); - - G_DEFINE_TYPE (IBusEngineDesc, ibus_engine_desc, IBUS_TYPE_SERIALIZABLE) - -+#define DEFAULT_REQUIRES (IBUS_CAP_PREEDIT_TEXT | \ -+ IBUS_CAP_AUXILIARY_TEXT | \ -+ IBUS_CAP_LOOKUP_TABLE | \ -+ IBUS_CAP_FOCUS | \ -+ IBUS_CAP_PROPERTY) - - static void - ibus_engine_desc_class_init (IBusEngineDescClass *class) -@@ -232,6 +246,21 @@ ibus_engine_desc_class_init (IBusEngineDescClass *class) - "The hotkeys of engine description", - "", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); -+ -+ /** -+ * IBusEngineDesc:requires: -+ * -+ * The required capabilities of engine description -+ */ -+ g_object_class_install_property (gobject_class, -+ PROP_REQUIRES, -+ g_param_spec_uint ("requires", -+ "description requires", -+ "The required capabilities of engine description", -+ 0, -+ G_MAXUINT, -+ DEFAULT_REQUIRES, -+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - } - - static void -@@ -249,6 +278,7 @@ ibus_engine_desc_init (IBusEngineDesc *desc) - desc->priv->layout = NULL; - desc->priv->rank = 0; - desc->priv->hotkeys = NULL; -+ desc->priv->requires = DEFAULT_REQUIRES; - } - - static void -@@ -313,6 +343,9 @@ ibus_engine_desc_set_property (IBusEngineDesc *desc, - g_assert (desc->priv->hotkeys == NULL); - desc->priv->hotkeys = g_value_dup_string (value); - break; -+ case PROP_REQUIRES: -+ desc->priv->requires = g_value_get_uint (value); -+ break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (desc, prop_id, pspec); - } -@@ -355,6 +388,9 @@ ibus_engine_desc_get_property (IBusEngineDesc *desc, - case PROP_HOTKEYS: - g_value_set_string (value, ibus_engine_desc_get_hotkeys (desc)); - break; -+ case PROP_REQUIRES: -+ g_value_set_uint (value, ibus_engine_desc_get_requires (desc)); -+ break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (desc, prop_id, pspec); - } -@@ -382,9 +418,28 @@ ibus_engine_desc_serialize (IBusEngineDesc *desc, - g_variant_builder_add (builder, "u", desc->priv->rank); - g_variant_builder_add (builder, "s", NOTNULL (desc->priv->hotkeys)); - #undef NOTNULL -+ -+ /* append extra properties */ -+ GVariantBuilder array; -+ g_variant_builder_init (&array, G_VARIANT_TYPE ("a{sv}")); -+ g_variant_builder_add (&array, "{sv}", "requires", g_variant_new_uint32 (desc->priv->requires)); -+ g_variant_builder_add (builder, "v", g_variant_builder_end (&array)); -+ - return TRUE; - } - -+static gboolean -+ibus_engine_desc_deserialize_property (IBusEngineDesc *desc, -+ const gchar *name, -+ GVariant *variant) -+{ -+ if (g_strcmp0 (name, "requires") == 0) { -+ g_variant_get (variant, "u", &desc->priv->requires); -+ return TRUE; -+ } -+ return FALSE; -+} -+ - static gint - ibus_engine_desc_deserialize (IBusEngineDesc *desc, - GVariant *variant) -@@ -405,6 +460,23 @@ ibus_engine_desc_deserialize (IBusEngineDesc *desc, - g_variant_get_child (variant, retval++, "u", &desc->priv->rank); - g_variant_get_child (variant, retval++, "s", &desc->priv->hotkeys); - -+ /* extract extra properties */ -+ GVariantIter iter; -+ GVariant *child, *array; -+ -+ g_variant_get_child (variant, retval++, "v", &array); -+ g_variant_iter_init (&iter, array); -+ while ((child = g_variant_iter_next_value (&iter))) { -+ gchar *name; -+ GVariant *value; -+ g_variant_get (child, "{sv}", &name, &value); -+ if (ibus_engine_desc_deserialize_property (desc, name, value)) -+ retval++; -+ g_free (name); -+ g_variant_unref (value); -+ g_variant_unref (child); -+ } -+ - return retval; - } - -@@ -428,6 +500,7 @@ ibus_engine_desc_copy (IBusEngineDesc *dest, - dest->priv->layout = g_strdup (src->priv->layout); - dest->priv->rank = src->priv->rank; - dest->priv->hotkeys = g_strdup (src->priv->hotkeys); -+ dest->priv->requires = src->priv->requires; - return TRUE; - } - -@@ -439,6 +512,52 @@ ibus_engine_desc_copy (IBusEngineDesc *dest, - } \ - } - -+static void -+ibus_engine_desc_output_capabilities (guint caps, -+ GString *output, -+ gint indent) -+{ -+ GFlagsClass *flags_class; -+ gint i; -+ -+ flags_class = g_type_class_ref (IBUS_TYPE_CAPABILITE); -+ g_return_if_fail (G_TYPE_IS_FLAGS (IBUS_TYPE_CAPABILITE)); -+ for (i = 0; i < flags_class->n_values; i++) { -+ GFlagsValue *flags_value = &flags_class->values[i]; -+ if (caps & flags_value->value) { -+ g_string_append_indent (output, indent + 1); -+ g_string_append_printf (output, "%s\n", -+ flags_value->value_nick); -+ } -+ } -+ g_type_class_unref (flags_class); -+} -+ -+static guint -+ibus_engine_desc_parse_capabilities (XMLNode *node) -+{ -+ GFlagsClass *flags_class; -+ guint caps = 0; -+ GList *p; -+ -+ flags_class = g_type_class_ref (IBUS_TYPE_CAPABILITE); -+ for (p = node->sub_nodes; p != NULL; p = p->next) { -+ XMLNode *sub_node = (XMLNode *) p->data; -+ -+ if (g_strcmp0 (sub_node->name, "capability") == 0) { -+ gint i; -+ for (i = 0; i < flags_class->n_values; i++) { -+ GFlagsValue *flags_value = &flags_class->values[i]; -+ if (g_strcmp0 (flags_value->value_nick, sub_node->text) == 0) -+ caps |= flags_value->value; -+ } -+ } -+ } -+ g_type_class_unref (flags_class); -+ -+ return caps; -+} -+ - void - ibus_engine_desc_output (IBusEngineDesc *desc, - GString *output, -@@ -467,6 +586,13 @@ ibus_engine_desc_output (IBusEngineDesc *desc, - OUTPUT_ENTRY_1(hotkeys); - g_string_append_indent (output, indent + 1); - g_string_append_printf (output, "%u\n", desc->priv->rank); -+ -+ g_string_append_indent (output, indent + 1); -+ g_string_append (output, "\n"); -+ ibus_engine_desc_output_capabilities (desc->priv->requires, output, -+ indent + 2); -+ g_string_append_indent (output, indent + 1); -+ g_string_append (output, "\n"); - #undef OUTPUT_ENTRY - #undef OUTPUT_ENTRY_1 - g_string_append_indent (output, indent); -@@ -504,6 +630,11 @@ ibus_engine_desc_parse_xml_node (IBusEngineDesc *desc, - desc->priv->rank = atoi (sub_node->text); - continue; - } -+ if (g_strcmp0 (sub_node->name , "requires") == 0) { -+ desc->priv->requires = -+ ibus_engine_desc_parse_capabilities (sub_node); -+ continue; -+ } - g_warning (" element contains invalidate element <%s>", sub_node->name); - } - return TRUE; -@@ -526,6 +657,7 @@ IBUS_ENGINE_DESC_GET_PROPERTY (icon, const gchar *) - IBUS_ENGINE_DESC_GET_PROPERTY (layout, const gchar *) - IBUS_ENGINE_DESC_GET_PROPERTY (rank, guint) - IBUS_ENGINE_DESC_GET_PROPERTY (hotkeys, const gchar *) -+IBUS_ENGINE_DESC_GET_PROPERTY (requires, guint) - #undef IBUS_ENGINE_DESC_GET_PROPERTY - - IBusEngineDesc * -diff --git a/src/ibusenginedesc.h b/src/ibusenginedesc.h -index 9718b15..209d460 100644 ---- a/src/ibusenginedesc.h -+++ b/src/ibusenginedesc.h -@@ -90,6 +90,8 @@ typedef struct _IBusEngineDescClass IBusEngineDescClass; - * the front. - * hotkeys: One or more hotkeys for switching to this engine, separated by - * semi-colon. -+ * requires: Capabilities this engine will utilize. The value is the -+ * union of the IBusCapability flags. - */ - struct _IBusEngineDesc { - IBusSerializable parent; -@@ -249,6 +251,15 @@ guint ibus_engine_desc_get_rank (IBusEngineDesc *info); - const gchar *ibus_engine_desc_get_hotkeys (IBusEngineDesc *info); - - /** -+ * ibus_engine_desc_get_requires: -+ * @info: An IBusEngineDesc -+ * @returns: request capabilites property in IBusEngineDesc -+ * -+ * Return the capabilites property in IBusEngineDesc. -+ */ -+guint ibus_engine_desc_get_requires (IBusEngineDesc *info); -+ -+/** - * ibus_engine_desc_output: - * @info: An IBusEngineDesc - * @output: XML-formatted Input method engine description. --- -1.7.4.2 - diff --git a/ibus-530711-preload-sys.patch b/ibus-530711-preload-sys.patch index b071d6e..7dec5ba 100644 --- a/ibus-530711-preload-sys.patch +++ b/ibus-530711-preload-sys.patch @@ -1,12 +1,13 @@ -From 047452beffd7cb429bf4dfeb2371f120cc8041a6 Mon Sep 17 00:00:00 2001 +From 7f81445b3e6613d14f64253506a309095a37c8d7 Mon Sep 17 00:00:00 2001 From: fujiwarat -Date: Fri, 11 Mar 2011 16:07:09 +0900 +Date: Mon, 20 Jun 2011 19:04:42 +0900 Subject: [PATCH] Reload preload engines until users customize the list. The idea is, if users don't customize the preload_engines with ibus-setup, users would prefer to load the system default engines again by login. The gconf value 'preload_engine_mode' is -IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE by default. +IBUS_PRELOAD_ENGINE_MODE_USER by default but set +IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE for the initial login. If preload_engine_mode is IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE, ibus-daemon loads the system preload engines by langs. If preload_engine_mode is IBUS_PRELOAD_ENGINE_MODE_USER, @@ -15,22 +16,20 @@ On the other hand, if users enable the customized engine checkbutton on ibus-setup, ibus-setup sets 'preload_engine_mode' as IBUS_PRELOAD_ENGINE_MODE_USER and users can customize the value 'preload_engines'. -Loading system default may spend the startup time. If you mind it, -your dist may like to put TRUE in 'use_local_preload_engines' value. --- - bus/ibusimpl.c | 286 +++++++++++++++++++++++++++++++++++--------------- - data/ibus.schemas.in | 13 +++ + bus/ibusimpl.c | 402 +++++++++++++++++++++++++++++++++++++++----------- + data/ibus.schemas.in | 13 ++ ibus/common.py | 6 + - setup/main.py | 37 ++++++- + setup/main.py | 70 ++++++++- setup/setup.ui | 21 +++- src/ibustypes.h | 10 ++ - 6 files changed, 279 insertions(+), 94 deletions(-) + 6 files changed, 427 insertions(+), 95 deletions(-) diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c -index 8d4ec36..0caa8c7 100644 +index a7ae52b..bb4b8ae 100644 --- a/bus/ibusimpl.c +++ b/bus/ibusimpl.c -@@ -144,6 +144,9 @@ static void bus_ibus_impl_set_previo +@@ -144,6 +144,9 @@ static void bus_ibus_impl_set_previous_engine static void bus_ibus_impl_set_preload_engines (BusIBusImpl *ibus, GVariant *value); @@ -40,10 +39,28 @@ index 8d4ec36..0caa8c7 100644 static void bus_ibus_impl_set_use_sys_layout (BusIBusImpl *ibus, GVariant *value); -@@ -284,6 +287,142 @@ _panel_destroy_cb (BusPanelProxy *panel, - g_object_unref (panel); +@@ -285,6 +288,259 @@ _panel_destroy_cb (BusPanelProxy *panel, } + static void ++_config_set_value_done (GObject *object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ IBusConfig *config = (IBusConfig *) object; ++ GVariant *value = (GVariant *) user_data; ++ GError *error = NULL; ++ ++ g_assert (IBUS_IS_CONFIG (config)); ++ ++ if (!ibus_config_set_value_async_finish (config, res, &error)) { ++ if (error) { ++ g_error_free (error); ++ } ++ } ++ g_variant_unref (value); ++} ++ +#ifndef OS_CHROMEOS +static gint +_engine_desc_cmp (IBusEngineDesc *desc1, @@ -59,7 +76,7 @@ index 8d4ec36..0caa8c7 100644 +_get_config_preload_engine_mode (BusIBusImpl *ibus) +{ + GVariant *variant = NULL; -+ gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE; ++ gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_USER; + + g_assert (BUS_IS_IBUS_IMPL (ibus)); + @@ -68,6 +85,23 @@ index 8d4ec36..0caa8c7 100644 + } + + variant = ibus_config_get_value (ibus->config, "general", ++ "preload_engines"); ++ if (variant == NULL) { ++ /* Set LANG_RELATIVE mode for the initial login */ ++ preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE; ++ variant = g_variant_ref_sink (g_variant_new ("i", preload_engine_mode)); ++ ibus_config_set_value_async (ibus->config, "general", ++ "preload_engine_mode", variant, ++ -1, ++ NULL, ++ _config_set_value_done, ++ variant); ++ return preload_engine_mode; ++ } else { ++ g_variant_unref (variant); ++ } ++ ++ variant = ibus_config_get_value (ibus->config, "general", + "preload_engine_mode"); + if (variant != NULL) { + if (g_variant_classify (variant) == G_VARIANT_CLASS_INT32) { @@ -80,6 +114,82 @@ index 8d4ec36..0caa8c7 100644 +} +#endif + ++static int ++_compare_engine_list_value (GVariant *value_a, GVariant *value_b) ++{ ++ GVariant *value; ++ GVariantIter iter; ++ const gchar *engine_name = NULL; ++ gchar *concat_engine_names; ++ gchar *concat_engine_names_a = NULL; ++ gchar *concat_engine_names_b = NULL; ++ int retval = 0; ++ ++ value = value_a; ++ concat_engine_names = NULL; ++ if (value != NULL && g_variant_classify (value) == G_VARIANT_CLASS_ARRAY) { ++ g_variant_iter_init (&iter, value); ++ while (g_variant_iter_loop (&iter, "&s", &engine_name)) { ++ gchar *tmp = g_strdup_printf ("%s::%s", ++ concat_engine_names ? concat_engine_names : "", ++ engine_name ? engine_name : ""); ++ g_free (concat_engine_names); ++ concat_engine_names = tmp; ++ } ++ } ++ concat_engine_names_a = concat_engine_names; ++ ++ value = value_b; ++ concat_engine_names = NULL; ++ if (value != NULL && g_variant_classify (value) == G_VARIANT_CLASS_ARRAY) { ++ g_variant_iter_init (&iter, value); ++ while (g_variant_iter_loop (&iter, "&s", &engine_name)) { ++ gchar *tmp = g_strdup_printf ("%s::%s", ++ concat_engine_names ? concat_engine_names : "", ++ engine_name ? engine_name : ""); ++ g_free (concat_engine_names); ++ concat_engine_names = tmp; ++ } ++ } ++ concat_engine_names_b = concat_engine_names; ++ ++ retval = g_strcmp0 (concat_engine_names_a, concat_engine_names_b); ++ g_free (concat_engine_names_a); ++ g_free (concat_engine_names_b); ++ return retval; ++} ++ ++static void ++_preload_engines_config_get_value_done (GObject *object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ IBusConfig *config = (IBusConfig *) object; ++ GVariant *new_value = (GVariant *) user_data; ++ GVariant *value = NULL; ++ GError *error = NULL; ++ ++ g_assert (IBUS_IS_CONFIG (config)); ++ ++ value = ibus_config_get_value_async_finish (config, res, &error); ++ if (error) { ++ g_error_free (error); ++ } ++ if (_compare_engine_list_value (value, new_value) != 0) { ++ ibus_config_set_value_async (config, "general", ++ "preload_engines", new_value, ++ -1, ++ NULL, ++ _config_set_value_done, ++ new_value); ++ } else if (new_value) { ++ g_variant_unref (new_value); ++ } ++ if (value) { ++ g_variant_unref (value); ++ } ++} ++ +static void +_set_preload_engines (BusIBusImpl *ibus, + GVariant *value) @@ -103,11 +213,16 @@ index 8d4ec36..0caa8c7 100644 + } + + if (engine_list != NULL && -+ ibus->config != NULL && -+ ibus_config_get_value (ibus->config, "general", -+ "preload_engines") == NULL) { -+ ibus_config_set_value (ibus->config, "general", -+ "preload_engines", value); ++ ibus->config != NULL) { ++ /* sync function will effects the startup performance. ++ * We'd always like to save the value so that ibus-setup ++ * get the updated engine list. */ ++ ibus_config_get_value_async (ibus->config, "general", ++ "preload_engines", ++ -1, ++ NULL, ++ _preload_engines_config_get_value_done, ++ g_variant_ref_sink (value)); + } else { + /* We don't update preload_engines with an empty string for safety. + * Just unref the floating value. */ @@ -180,10 +295,11 @@ index 8d4ec36..0caa8c7 100644 +} +#endif + - static void ++static void bus_ibus_impl_set_hotkey (BusIBusImpl *ibus, GQuark hotkey, -@@ -394,35 +533,50 @@ static void + GVariant *value) +@@ -394,35 +650,50 @@ static void bus_ibus_impl_set_preload_engines (BusIBusImpl *ibus, GVariant *value) { @@ -220,14 +336,14 @@ index 8d4ec36..0caa8c7 100644 +/** + * bus_ibus_impl_set_preload_engine_mode: + * -+ * A function to be called when "preload_engines_mode" config is updated. ++ * A function to be called when "preload_engine_mode" config is updated. + */ +static void +bus_ibus_impl_set_preload_engine_mode (BusIBusImpl *ibus, + GVariant *value) +{ +#ifndef OS_CHROMEOS -+ gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE; ++ gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_USER; - if (ibus->engine_list) { - BusComponent *component = bus_component_from_engine_desc ((IBusEngineDesc *) ibus->engine_list->data); @@ -256,7 +372,7 @@ index 8d4ec36..0caa8c7 100644 } /** -@@ -503,89 +657,48 @@ bus_ibus_impl_set_use_global_engine (Bus +@@ -503,89 +774,47 @@ bus_ibus_impl_set_use_global_engine (BusIBusImpl *ibus, } } @@ -279,7 +395,8 @@ index 8d4ec36..0caa8c7 100644 + * The idea is, if users don't customize the preload_engines with ibus-setup, + * users would prefer to load the system default engines again by login. + * The gconf value 'preload_engine_mode' is -+ * IBUS_PRELOAD_ENGINE_MODE_USER by default. ++ * IBUS_PRELOAD_ENGINE_MODE_USER by default but set ++ * IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE for the initial login. + * If preload_engine_mode is IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE, + * ibus-daemon loads the system preload engines by langs. + * If preload_engine_mode is IBUS_PRELOAD_ENGINE_MODE_USER, @@ -288,8 +405,6 @@ index 8d4ec36..0caa8c7 100644 + * on ibus-setup, ibus-setup sets 'preload_engine_mode' as + * IBUS_PRELOAD_ENGINE_MODE_USER and users can customize the value + * 'preload_engines'. -+ * Loading system default may spend the startup time. If you mind it, -+ * your dist may like to put TRUE in 'use_local_preload_engines' value. */ static void bus_ibus_impl_set_default_preload_engines (BusIBusImpl *ibus) @@ -298,7 +413,7 @@ index 8d4ec36..0caa8c7 100644 - g_assert (BUS_IS_IBUS_IMPL (ibus)); - static gboolean done = FALSE; -+ gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE; ++ gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_USER; + + g_assert (BUS_IS_IBUS_IMPL (ibus)); @@ -369,16 +484,16 @@ index 8d4ec36..0caa8c7 100644 #endif } -@@ -601,6 +714,7 @@ const static struct { +@@ -601,6 +830,7 @@ const static struct { { "general/hotkey", "next_engine_in_menu", bus_ibus_impl_set_next_engine_in_menu }, { "general/hotkey", "previous_engine", bus_ibus_impl_set_previous_engine }, { "general", "preload_engines", bus_ibus_impl_set_preload_engines }, -+ { "general", "preload_engines_mode", bus_ibus_impl_set_preload_engine_mode }, ++ { "general", "preload_engine_mode", bus_ibus_impl_set_preload_engine_mode }, { "general", "use_system_keyboard_layout", bus_ibus_impl_set_use_sys_layout }, { "general", "use_global_engine", bus_ibus_impl_set_use_global_engine }, { "general", "embed_preedit_text", bus_ibus_impl_set_embed_preedit_text }, diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in -index 7ca4899..39922a0 100644 +index 7ca4899..d4334e1 100644 --- a/data/ibus.schemas.in +++ b/data/ibus.schemas.in @@ -13,6 +13,19 @@ @@ -389,7 +504,7 @@ index 7ca4899..39922a0 100644 + /desktop/ibus/general/preload_engine_mode + ibus + int -+ 1 ++ 0 + + Preload engine mode + Preload engines are loaded with this mode. @@ -402,7 +517,7 @@ index 7ca4899..39922a0 100644 /desktop/ibus/general/hotkey/trigger ibus diff --git a/ibus/common.py b/ibus/common.py -index e105f18..20c0710 100644 +index 6483aae..127ed93 100644 --- a/ibus/common.py +++ b/ibus/common.py @@ -40,6 +40,8 @@ __all__ = ( @@ -426,10 +541,18 @@ index e105f18..20c0710 100644 pass diff --git a/setup/main.py b/setup/main.py -index 7f4a040..9cdce02 100644 +index 7f4a040..192fb88 100644 --- a/setup/main.py +++ b/setup/main.py -@@ -213,15 +213,22 @@ class Setup(object): +@@ -92,6 +92,7 @@ class Setup(object): + # keyboard shortcut + # trigger + self.__config = self.__bus.get_config() ++ self.__config.connect("value-changed", self.__config_value_changed_cb) + shortcuts = self.__config.get_value( + "general/hotkey", "trigger", + ibus.CONFIG_GENERAL_SHORTCUT_TRIGGER_DEFAULT) +@@ -213,15 +214,22 @@ class Setup(object): self.__checkbutton_use_global_engine.connect("toggled", self.__checkbutton_use_global_engine_toggled_cb) # init engine page @@ -457,7 +580,7 @@ index 7f4a040..9cdce02 100644 self.__treeview = self.__builder.get_object("treeview_engines") self.__treeview.set_engines(engines) -@@ -265,6 +272,13 @@ class Setup(object): +@@ -265,6 +273,26 @@ class Setup(object): engine_names = map(lambda e: e.name, engines) self.__config.set_list("general", "preload_engines", engine_names, "s") @@ -468,10 +591,23 @@ index 7f4a040..9cdce02 100644 + engines = [tmp_dict[name] for name in engine_names if name in tmp_dict] + return engines + ++ def __compare_descs(self, engines_a, engines_b): ++ engines = engines_a ++ concat_engine_names = "" ++ for engine in engines: ++ concat_engine_names = "%s::%s" % (concat_engine_names, engine.name) ++ concat_engine_names_a = concat_engine_names ++ engines = engines_b ++ concat_engine_names = "" ++ for engine in engines: ++ concat_engine_names = "%s::%s" % (concat_engine_names, engine.name) ++ concat_engine_names_b = concat_engine_names ++ return concat_engine_names_a == concat_engine_names_b ++ def __button_engine_add_cb(self, button): engine = self.__combobox.get_active_engine() self.__treeview.append_engine(engine) -@@ -276,6 +290,19 @@ class Setup(object): +@@ -276,6 +304,32 @@ class Setup(object): about.run() about.destroy() @@ -483,6 +619,19 @@ index 7f4a040..9cdce02 100644 + self.__builder.get_object("hbox_customize_active_input_methods").set_sensitive(True) + self.__treeview.notify("engines") + else: ++ message = _("The list of your saved input methods will be " \ ++ "cleared immediately and the list will be " \ ++ "configured by the login language every time. " \ ++ "Do you agree with this?") ++ dlg = gtk.MessageDialog(type = gtk.MESSAGE_QUESTION, ++ buttons = gtk.BUTTONS_YES_NO, ++ message_format = message) ++ id = dlg.run() ++ dlg.destroy() ++ self.__flush_gtk_events() ++ if id != gtk.RESPONSE_YES: ++ button.set_active(True) ++ return + self.__config.set_value("general", + "preload_engine_mode", + ibus.common.PRELOAD_ENGINE_MODE_LANG_RELATIVE) @@ -491,6 +640,19 @@ index 7f4a040..9cdce02 100644 def __init_bus(self): try: self.__bus = ibus.Bus() +@@ -466,7 +520,11 @@ class Setup(object): + self.__config.set_value("general", "use_global_engine", value) + + def __config_value_changed_cb(self, bus, section, name, value): +- pass ++ if section == 'general' and name == 'preload_engines': ++ engines = self.__get_engine_descs_from_names(value) ++ current_engines = self.__treeview.get_engines() ++ if self.__compare_descs(engines, current_engines) == False: ++ self.__treeview.set_engines(engines) + + def __config_reloaded_cb(self, bus): + pass diff --git a/setup/setup.ui b/setup/setup.ui index f1e6d0b..562c091 100644 --- a/setup/setup.ui @@ -538,11 +700,11 @@ index f1e6d0b..562c091 100644 diff --git a/src/ibustypes.h b/src/ibustypes.h -index 035d124..0a9d7b2 100644 +index 6a31847..14b44fc 100644 --- a/src/ibustypes.h +++ b/src/ibustypes.h -@@ -177,6 +177,16 @@ typedef enum { - } IBusBusRequestNameReply; +@@ -186,6 +186,16 @@ typedef enum { + } IBusError; /** + * IBusPreloadEngineMode: @@ -559,5 +721,5 @@ index 035d124..0a9d7b2 100644 * @x: x coordinate. * @y: y coordinate. -- -1.7.4.1 +1.7.4.4 diff --git a/ibus-541492-xkb.patch b/ibus-541492-xkb.patch index 9100d48..21f0694 100644 --- a/ibus-541492-xkb.patch +++ b/ibus-541492-xkb.patch @@ -1,6 +1,6 @@ -From b6b83e9484abad910271b15222d3f76f206a1ff6 Mon Sep 17 00:00:00 2001 +From 7fab90a9962d3b4f8eff40cf08939873575d153e Mon Sep 17 00:00:00 2001 From: fujiwarat -Date: Wed, 1 Jun 2011 18:24:10 +0900 +Date: Tue, 21 Jun 2011 11:34:52 +0900 Subject: [PATCH] Add XKB layouts --- @@ -12,30 +12,36 @@ Subject: [PATCH] Add XKB layouts ibus/__init__.py | 2 + ibus/bus.py | 3 + ibus/interface/iibus.py | 3 + - ibus/xkblayout.py.in | 225 ++++++++++++++ - ibus/xkbxml.py.in | 413 ++++++++++++++++++++++++++ + ibus/xkblayout.py.in | 225 ++++++++++++++++ + ibus/xkbxml.py.in | 413 ++++++++++++++++++++++++++++++ setup/Makefile.am | 1 + setup/enginecombobox.py | 7 +- setup/main.py | 3 + - setup/setup.ui | 609 ++++++++++++++++++++++++++++++++++++++- - setup/xkbsetup.py | 454 +++++++++++++++++++++++++++++ + setup/setup.ui | 609 +++++++++++++++++++++++++++++++++++++++++++- + setup/xkbsetup.py | 454 +++++++++++++++++++++++++++++++++ + src/Makefile.am | 5 + + src/ibus.h | 1 + src/ibusfactory.c | 21 ++- src/ibusfactory.h | 5 +- + src/ibusxkbxml.c | 440 ++++++++++++++++++++++++++++++++ + src/ibusxkbxml.h | 172 +++++++++++++ ui/gtk/panel.py | 39 +++ - xkb/Makefile.am | 104 +++++++ - xkb/ibus-engine-xkb-main.c | 397 +++++++++++++++++++++++++ - xkb/ibus-engine-xkb-main.h | 46 +++ - xkb/ibus-xkb-main.c | 105 +++++++ - xkb/xkblayout.xml.in | 16 + + xkb/Makefile.am | 104 ++++++++ + xkb/ibus-engine-xkb-main.c | 397 +++++++++++++++++++++++++++++ + xkb/ibus-engine-xkb-main.h | 46 ++++ + xkb/ibus-xkb-main.c | 112 ++++++++ + xkb/xkblayout.xml.in | 16 ++ xkb/xkblayoutconfig.xml.in | 6 + - xkb/xkblib.c | 303 +++++++++++++++++++ - xkb/xkblib.h | 40 +++ - xkb/xkbxml.c | 696 ++++++++++++++++++++++++++++++++++++++++++++ - xkb/xkbxml.h | 189 ++++++++++++ - 28 files changed, 3808 insertions(+), 6 deletions(-) + xkb/xkblib.c | 327 ++++++++++++++++++++++++ + xkb/xkblib.h | 41 +++ + xkb/xkbxml.c | 335 ++++++++++++++++++++++++ + xkb/xkbxml.h | 110 ++++++++ + 32 files changed, 4018 insertions(+), 6 deletions(-) create mode 100644 ibus/xkblayout.py.in create mode 100644 ibus/xkbxml.py.in create mode 100644 setup/xkbsetup.py + create mode 100644 src/ibusxkbxml.c + create mode 100644 src/ibusxkbxml.h create mode 100644 xkb/Makefile.am create mode 100644 xkb/ibus-engine-xkb-main.c create mode 100644 xkb/ibus-engine-xkb-main.h @@ -48,7 +54,7 @@ Subject: [PATCH] Add XKB layouts create mode 100644 xkb/xkbxml.h diff --git a/Makefile.am b/Makefile.am -index 29c57e1..dbe0b6b 100644 +index 7be558b..59fbabb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,6 +42,12 @@ DAEMON_DIRS = \ @@ -73,7 +79,7 @@ index 29c57e1..dbe0b6b 100644 $(NULL) diff --git a/configure.ac b/configure.ac -index 8da8c6e..ce1526c 100644 +index 5544dfa..85e5e30 100644 --- a/configure.ac +++ b/configure.ac @@ -185,6 +185,60 @@ else @@ -297,7 +303,7 @@ index 678d517..7de56fc 100644 diff --git a/ibus/xkblayout.py.in b/ibus/xkblayout.py.in new file mode 100644 -index 0000000..6097ed1 +index 0000000..637f6c1 --- /dev/null +++ b/ibus/xkblayout.py.in @@ -0,0 +1,225 @@ @@ -305,9 +311,9 @@ index 0000000..6097ed1 +# +# ibus - The Input Bus +# -+# Copyright (c) 2010 Takao Fujiwara -+# Copyright (c) 2007-2010 Peng Huang -+# Copyright (c) 2007-2010 Red Hat, Inc. ++# Copyright (c) 2011 Takao Fujiwara ++# Copyright (c) 2011 Peng Huang ++# Copyright (c) 2011 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public @@ -371,6 +377,16 @@ index 0000000..6097ed1 + option = ','.join(option_array) + return (layout, option) + ++ def __get_output_from_cmdline(self, arg, string): ++ exec_command = "%s %s" % (self.__command, arg) ++ retval = None ++ for line in os.popen(exec_command).readlines(): ++ line = line.strip() ++ if line.startswith(string): ++ retval = line[len(string):] ++ break ++ return retval ++ + def use_xkb(self, enable): + if self.__command == None: + return @@ -379,38 +395,22 @@ index 0000000..6097ed1 + def get_layout(self): + if not self.__use_xkb: + return None -+ exec_command = "%s %s" % (self.__command, "--get") -+ retval = None -+ for line in os.popen(exec_command).readlines(): -+ line = line.strip() -+ if line.startswith("layout: "): -+ retval = line[len("layout: "):] -+ break -+ return retval ++ return self.__get_output_from_cmdline("--get", "layout: ") + + def get_model(self): + if not self.__use_xkb: + return None -+ exec_command = "%s %s" % (self.__command, "--get") -+ retval = None -+ for line in os.popen(exec_command).readlines(): -+ line = line.strip() -+ if line.startswith("model: "): -+ retval = line[len("model: "):] -+ break -+ return retval ++ return self.__get_output_from_cmdline("--get", "model: ") + + def get_option(self): + if not self.__use_xkb: + return None -+ exec_command = "%s %s" % (self.__command, "--get") -+ retval = None -+ for line in os.popen(exec_command).readlines(): -+ line = line.strip() -+ if line.startswith("option: "): -+ retval = line[len("option: "):] -+ break -+ return retval ++ return self.__get_output_from_cmdline("--get", "option: ") ++ ++ def get_group(self): ++ if not self.__use_xkb: ++ return 0 ++ return int(self.__get_output_from_cmdline("--get-group", "group: ")) + + def set_layout(self, layout="default", model="default", option="default"): + if not self.__use_xkb: @@ -520,6 +520,12 @@ index 0000000..6097ed1 + self.__default_option = option + self.__time_lag_session_xkb_option = False + ++ def get_default_layout(self): ++ return [self.__default_layout, self.__default_model]; ++ ++ def get_default_option(self): ++ return self.__default_option ++ + def reload_default_layout(self): + if not self.__use_xkb: + return @@ -528,7 +534,7 @@ index 0000000..6097ed1 + self.__default_option = self.get_option() diff --git a/ibus/xkbxml.py.in b/ibus/xkbxml.py.in new file mode 100644 -index 0000000..57f54da +index 0000000..7e5a44e --- /dev/null +++ b/ibus/xkbxml.py.in @@ -0,0 +1,413 @@ @@ -536,9 +542,9 @@ index 0000000..57f54da +# +# ibus - The Input Bus +# -+# Copyright (c) 2010 Takao Fujiwara -+# Copyright (c) 2007-2010 Peng Huang -+# Copyright (c) 2007-2010 Red Hat, Inc. ++# Copyright (c) 2011 Takao Fujiwara ++# Copyright (c) 2011 Peng Huang ++# Copyright (c) 2011 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public @@ -1664,7 +1670,7 @@ index 0a69df8..f1e6d0b 100644 diff --git a/setup/xkbsetup.py b/setup/xkbsetup.py new file mode 100644 -index 0000000..74d5212 +index 0000000..1685bff --- /dev/null +++ b/setup/xkbsetup.py @@ -0,0 +1,454 @@ @@ -1672,9 +1678,9 @@ index 0000000..74d5212 +# +# ibus - The Input Bus +# -+# Copyright (c) 2010 Takao Fujiwara -+# Copyright (c) 2007-2010 Peng Huang -+# Copyright (c) 2007-2010 Red Hat, Inc. ++# Copyright (c) 2011 Takao Fujiwara ++# Copyright (c) 2011 Peng Huang ++# Copyright (c) 2011 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public @@ -2122,6 +2128,34 @@ index 0000000..74d5212 + label.set_text(label.get_text()) + expander.set_data("checked", checked) + +diff --git a/src/Makefile.am b/src/Makefile.am +index a53bd23..6454522 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -184,6 +184,11 @@ typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) + CLEANFILES += $(dist_gir_DATA) $(typelibs_DATA) + endif + ++if ENABLE_XKB ++ibus_sources += ibusxkbxml.c ++ibus_headers += ibusxkbxml.h ++endif ++ + # gen enum types + ibusenumtypes.h: $(ibus_headers) ibusenumtypes.h.template + $(AM_V_GEN) ( top_builddir=`cd $(top_builddir) && pwd`; \ +diff --git a/src/ibus.h b/src/ibus.h +index c408f3d..6bb9ff5 100644 +--- a/src/ibus.h ++++ b/src/ibus.h +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/src/ibusfactory.c b/src/ibusfactory.c index 11d9a6d..7770216 100644 --- a/src/ibusfactory.c @@ -2202,219 +2236,18 @@ index 47c06e0..102081c 100644 }; /** -diff --git a/ui/gtk/panel.py b/ui/gtk/panel.py -index 90be1d5..de64920 100644 ---- a/ui/gtk/panel.py -+++ b/ui/gtk/panel.py -@@ -132,6 +132,22 @@ class Panel(ibus.PanelBase): - self.__config_load_show_im_name() - # self.__bus.request_name(ibus.panel.IBUS_SERVICE_PANEL, 0) - -+ # init xkb -+ self.__xkblayout = ibus.XKBLayout(self.__config) -+ use_xkb = self.__config.get_value("general", "use_system_keyboard_layout", False) -+ if not use_xkb: -+ self.__xkblayout.use_xkb(use_xkb) -+ value = str(self.__config.get_value("general", "system_keyboard_layout", '')) -+ if value == '': -+ value = 'default' -+ if value != 'default': -+ self.__xkblayout.set_default_layout(value) -+ value = str(self.__config.get_value("general", "system_keyboard_option", '')) -+ if value == '': -+ value = 'default' -+ if value != 'default': -+ self.__xkblayout.set_default_option(value) -+ - def set_cursor_location(self, x, y, w, h): - self.__candidate_panel.set_cursor_location(x, y, w, h) - -@@ -226,14 +242,20 @@ class Panel(ibus.PanelBase): - if not enabled: - self.__set_im_icon(ICON_KEYBOARD) - self.__set_im_name(None) -+ if self.__bus.get_use_sys_layout(): -+ self.__xkblayout.set_layout() - else: - engine = self.__focus_ic.get_engine() - if engine: - self.__set_im_icon(engine.icon) - self.__set_im_name(engine.longname) -+ if self.__bus.get_use_sys_layout(): -+ self.__xkblayout.set_layout(self.__engine_get_layout_wrapper(engine)) - else: - self.__set_im_icon(ICON_KEYBOARD) - self.__set_im_name(None) -+ if self.__bus.get_use_sys_layout(): -+ self.__xkblayout.set_layout() - self.__language_bar.focus_in() - - def focus_out(self, ic): -@@ -243,6 +265,8 @@ class Panel(ibus.PanelBase): - self.__language_bar.focus_out() - self.__set_im_icon(ICON_KEYBOARD) - self.__set_im_name(None) -+ if self.__bus.get_use_sys_layout(): -+ self.__xkblayout.set_layout() - - def state_changed(self): - if not self.__focus_ic: -@@ -255,14 +279,20 @@ class Panel(ibus.PanelBase): - self.reset() - self.__set_im_icon(ICON_KEYBOARD) - self.__set_im_name(None) -+ if self.__bus.get_use_sys_layout(): -+ self.__xkblayout.set_layout() - else: - engine = self.__focus_ic.get_engine() - if engine: - self.__set_im_icon(engine.icon) - self.__set_im_name(engine.longname) -+ if self.__bus.get_use_sys_layout(): -+ self.__xkblayout.set_layout(self.__engine_get_layout_wrapper(engine)) - else: - self.__set_im_icon(ICON_KEYBOARD) - self.__set_im_name(None) -+ if self.__bus.get_use_sys_layout(): -+ self.__xkblayout.set_layout() - - - def reset(self): -@@ -542,3 +572,12 @@ class Panel(ibus.PanelBase): - flags=glib.SPAWN_DO_NOT_REAP_CHILD)[0] - self.__setup_pid = pid - glib.child_watch_add(self.__setup_pid, self.__child_watch_cb) -+ -+ def __engine_get_layout_wrapper(self, engine): -+ # This code is for the back compatibility. -+ # Should we remove the codes after all IM engines are changed -+ # to "default" layout? -+ if engine.name != None and engine.name.startswith("xkb:layout:"): -+ return engine.layout -+ else: -+ return "default" -diff --git a/xkb/Makefile.am b/xkb/Makefile.am -new file mode 100644 -index 0000000..64b1fc8 ---- /dev/null -+++ b/xkb/Makefile.am -@@ -0,0 +1,104 @@ -+# vim:set noet ts=4: -+# -+# ibus - The Input Bus -+# -+# Copyright (C) 2010 Takao Fujiwara -+# Copyright (c) 2007-2010 Peng Huang -+# Copyright (c) 2007-2010 Red Hat, Inc. -+# -+# This library is free software; you can redistribute it and/or -+# modify it under the terms of the GNU Lesser General Public -+# License as published by the Free Software Foundation; either -+# version 2 of the License, or (at your option) any later version. -+# -+# This library is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU Lesser General Public License for more details. -+# -+# You should have received a copy of the GNU Lesser General Public -+# License along with this program; if not, write to the -+# Free Software Foundation, Inc., 59 Temple Place, Suite 330, -+# Boston, MA 02111-1307 USA -+ -+libibus = $(top_builddir)/src/libibus-@IBUS_API_VERSION@.la -+ -+INCLUDES = \ -+ -I$(top_srcdir) \ -+ -I$(top_srcdir)/src \ -+ -DIBUS_LOCALEDIR=\"$(datadir)/locale\" \ -+ -DLIBEXECDIR=\""$(libexecdir)"\" \ -+ $(NULL) -+ -+noinst_PROGRAMS = $(TESTS) -+libexec_PROGRAMS = -+EXTRA_DIST = -+DISTCLEANFILES = -+ -+if ENABLE_XKB -+libexec_PROGRAMS += ibus-xkb -+ibus_xkb_SOURCES = \ -+ ibus-xkb-main.c \ -+ xkblib.h \ -+ xkblib.c \ -+ $(NULL) -+ibus_xkb_CFLAGS = \ -+ @XKB_CFLAGS@ \ -+ @X11_CFLAGS@ \ -+ @GLIB2_CFLAGS@ \ -+ $(NULL) -+ibus_xkb_LDADD = \ -+ @XKB_LIBS@ \ -+ @X11_LIBS@ \ -+ @GLIB2_LIBS@ \ -+ $(libibus) \ -+ $(NULL) -+ -+libexec_PROGRAMS += ibus-engine-xkb -+ibus_engine_xkb_SOURCES = \ -+ ibus-engine-xkb-main.c \ -+ ibus-engine-xkb-main.h \ -+ xkbxml.c \ -+ xkbxml.h \ -+ $(NULL) -+ibus_engine_xkb_CFLAGS = \ -+ @GLIB2_CFLAGS@ \ -+ @GOBJECT2_CFLAGS@ \ -+ @GCONF_CFLAGS@ \ -+ $(NULL) -+ibus_engine_xkb_LDADD = \ -+ @GLIB2_LIBS@ \ -+ @GOBJECT2_LIBS@ \ -+ @GCONF_LIBS@ \ -+ $(libibus) \ -+ $(NULL) -+ -+xkblayoutdir = $(datadir)/ibus/component -+xkblayout_in_files = xkblayout.xml.in -+xkblayout_DATA = $(xkblayout_in_files:.xml.in=.xml) -+ -+xkblayoutconfigdir = $(datadir)/ibus/xkb -+xkblayoutconfig_in_files = xkblayoutconfig.xml.in -+xkblayoutconfig_DATA = $(xkblayoutconfig_in_files:.xml.in=.xml) -+ -+%.xml : %.xml.in -+ @sed -e "s|\@libexecdir\@|$(libexecdir)|g" \ -+ -e "s|\@datadir\@|$(datadir)|g" \ -+ -e "s|\@XKB_PRELOAD_LAYOUTS\@|$(XKB_PRELOAD_LAYOUTS)|g" \ -+ $< > $@ -+ -+INCLUDES += \ -+ -DXKBLAYOUTCONFIG_FILE=\""$(xkblayoutconfigdir)/$(xkblayoutconfig_DATA)"\" \ -+ $(NULL) -+ -+EXTRA_DIST += \ -+ $(xkblayout_in_files) \ -+ $(xkblayoutconfig_in_files) \ -+ $(NULL) -+ -+DISTCLEANFILES += \ -+ $(xkblayout_DATA) \ -+ $(xkblayoutconfig_DATA) \ -+ $(NULL) -+ -+endif -diff --git a/xkb/ibus-engine-xkb-main.c b/xkb/ibus-engine-xkb-main.c +diff --git a/src/ibusxkbxml.c b/src/ibusxkbxml.c new file mode 100644 -index 0000000..e1861e8 +index 0000000..c630eb9 --- /dev/null -+++ b/xkb/ibus-engine-xkb-main.c -@@ -0,0 +1,397 @@ ++++ b/src/ibusxkbxml.c +@@ -0,0 +1,440 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* vim:set et sts=4: */ +/* bus - The Input Bus -+ * Copyright (C) 2010 Takao Fujiwara -+ * Copyright (C) 2008-2010 Peng Huang -+ * Copyright (C) 2008-2010 Red Hat, Inc. ++ * Copyright (C) 2011 Takao Fujiwara ++ * Copyright (C) 2011 Peng Huang ++ * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public @@ -2435,29 +2268,854 @@ index 0000000..e1861e8 +#include +#endif + -+#include -+#include -+#include ++#include + -+#ifdef ENABLE_NLS -+#include -+#endif ++#include "ibus.h" + -+#include "ibus-engine-xkb-main.h" -+#include "xkbxml.h" ++#ifndef XKB_RULES_XML_FILE ++#define XKB_RULES_XML_FILE "/usr/share/X11/xkb/rules/evdev.xml" ++#endif + -+#define IBUS_TYPE_XKB_ENGINE (ibus_xkb_engine_get_type ()) ++#define IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE(o) \ ++ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryPrivate)) + -+static IBusBus *bus = NULL; -+static IBusFactory *factory = NULL; -+static IBusEngineClass *parent_class = NULL; -+static gboolean ibus = FALSE; -+static gboolean xml = FALSE; ++typedef struct _IBusXKBConfigRegistryPrivate IBusXKBConfigRegistryPrivate; + -+static const GOptionEntry entries[] = -+{ -+ { "ibus", 'i', 0, G_OPTION_ARG_NONE, &ibus, "component is executed by ibus", NULL }, -+ { "xml", 'x', 0, G_OPTION_ARG_NONE, &xml, "print component xml", NULL }, ++struct _IBusXKBConfigRegistryPrivate { ++ GHashTable *layout_list; ++ GHashTable *layout_lang; ++ GHashTable *layout_desc; ++ GHashTable *variant_desc; ++}; ++ ++ ++/* functions prototype */ ++static void ibus_xkb_config_registry_destroy ++ (IBusXKBConfigRegistry *xkb_config); ++ ++G_DEFINE_TYPE (IBusXKBConfigRegistry, ibus_xkb_config_registry, IBUS_TYPE_OBJECT) ++ ++static void ++parse_xkb_xml_languagelist_node (IBusXKBConfigRegistryPrivate *priv, ++ XMLNode *parent_node, ++ const gchar *layout_name) ++{ ++ XMLNode *node = parent_node; ++ XMLNode *sub_node; ++ GList *p; ++ GList *lang_list = NULL; ++ ++ g_assert (node != NULL); ++ g_assert (layout_name != NULL); ++ for (p = node->sub_nodes; p; p = p->next) { ++ sub_node = (XMLNode *) p->data; ++ if (g_strcmp0 (sub_node->name, "iso639Id") == 0) { ++ lang_list = g_list_append (lang_list, ++ (gpointer) g_strdup (sub_node->text)); ++ continue; ++ } ++ } ++ if (lang_list == NULL) { ++ /* some nodes have no lang */ ++ return; ++ } ++ if (g_hash_table_lookup (priv->layout_lang, layout_name) != NULL) { ++ g_warning ("duplicated name %s exists", layout_name); ++ return; ++ } ++ g_hash_table_insert (priv->layout_lang, ++ (gpointer) g_strdup (layout_name), ++ (gpointer) lang_list); ++} ++ ++static const gchar * ++parse_xkb_xml_configitem_node (IBusXKBConfigRegistryPrivate *priv, ++ XMLNode *parent_node) ++{ ++ XMLNode *node = parent_node; ++ XMLNode *sub_node; ++ GList *p; ++ gchar *name = NULL; ++ gchar *description = NULL; ++ ++ g_assert (node != NULL); ++ for (p = node->sub_nodes; p; p = p->next) { ++ sub_node = (XMLNode *) p->data; ++ if (g_strcmp0 (sub_node->name, "name") == 0) { ++ name = sub_node->text; ++ continue; ++ } ++ if (g_strcmp0 (sub_node->name, "description") == 0) { ++ description = sub_node->text; ++ continue; ++ } ++ if (g_strcmp0 (sub_node->name, "languageList") == 0) { ++ if (name == NULL) { ++ g_warning ("layout name is NULL in node %s", node->name); ++ continue; ++ } ++ parse_xkb_xml_languagelist_node (priv, sub_node, name); ++ continue; ++ } ++ } ++ if (name == NULL) { ++ g_warning ("No name in layout node"); ++ return NULL; ++ } ++ if (g_hash_table_lookup (priv->layout_desc, name) != NULL) { ++ g_warning ("duplicated name %s exists", name); ++ return name; ++ } ++ g_hash_table_insert (priv->layout_desc, ++ (gpointer) g_strdup (name), ++ (gpointer) g_strdup (description)); ++ ++ return name; ++} ++ ++static const gchar * ++parse_xkb_xml_variant_configitem_node (IBusXKBConfigRegistryPrivate *priv, ++ XMLNode *parent_node, ++ const gchar *layout_name) ++{ ++ XMLNode *node = parent_node; ++ XMLNode *sub_node; ++ GList *p; ++ gchar *name = NULL; ++ gchar *description = NULL; ++ gchar *variant_lang_name = NULL; ++ ++ g_assert (node != NULL); ++ g_assert (layout_name != NULL); ++ for (p = node->sub_nodes; p; p = p->next) { ++ sub_node = (XMLNode *) p->data; ++ if (g_strcmp0 (sub_node->name, "name") == 0) { ++ name = sub_node->text; ++ continue; ++ } ++ if (g_strcmp0 (sub_node->name, "description") == 0) { ++ description = sub_node->text; ++ continue; ++ } ++ if (g_strcmp0 (sub_node->name, "languageList") == 0) { ++ if (name == NULL) { ++ g_warning ("layout name is NULL in node %s", node->name); ++ continue; ++ } ++ variant_lang_name = g_strdup_printf ("%s(%s)", layout_name, name); ++ parse_xkb_xml_languagelist_node (priv, sub_node, variant_lang_name); ++ g_free (variant_lang_name); ++ continue; ++ } ++ } ++ if (name == NULL) { ++ g_warning ("No name in layout node"); ++ return NULL; ++ } ++ if (g_hash_table_lookup (priv->variant_desc, name) != NULL) { ++ /* This is an expected case. */ ++ return name; ++ } ++ g_hash_table_insert (priv->variant_desc, ++ (gpointer) g_strdup (name), ++ (gpointer) g_strdup (description)); ++ return name; ++} ++ ++static const gchar * ++parse_xkb_xml_variant_node (IBusXKBConfigRegistryPrivate *priv, ++ XMLNode *parent_node, ++ const gchar *layout_name) ++{ ++ XMLNode *node = parent_node; ++ XMLNode *sub_node; ++ GList *p; ++ const gchar *variant_name = NULL; ++ ++ g_assert (node != NULL); ++ g_assert (layout_name != NULL); ++ for (p = node->sub_nodes; p; p = p->next) { ++ sub_node = (XMLNode *) p->data; ++ if (g_strcmp0 (sub_node->name, "configItem") == 0) { ++ variant_name = parse_xkb_xml_variant_configitem_node (priv, sub_node, layout_name); ++ continue; ++ } ++ } ++ return variant_name; ++} ++ ++static GList * ++parse_xkb_xml_variantlist_node (IBusXKBConfigRegistryPrivate *priv, ++ XMLNode *parent_node, ++ const gchar *layout_name, ++ GList *variant_list) ++{ ++ XMLNode *node = parent_node; ++ XMLNode *sub_node; ++ GList *p; ++ const gchar *variant_name = NULL; ++ ++ g_assert (node != NULL); ++ g_assert (layout_name != NULL); ++ for (p = node->sub_nodes; p; p = p->next) { ++ sub_node = (XMLNode *) p->data; ++ if (g_strcmp0 (sub_node->name, "variant") == 0) { ++ variant_name = parse_xkb_xml_variant_node (priv, sub_node, layout_name); ++ if (variant_name != NULL) { ++ variant_list = g_list_append (variant_list, ++ (gpointer) g_strdup (variant_name)); ++ } ++ continue; ++ } ++ } ++ return variant_list; ++} ++ ++static void ++parse_xkb_xml_layout_node (IBusXKBConfigRegistryPrivate *priv, ++ XMLNode *parent_node) ++{ ++ XMLNode *node = parent_node; ++ XMLNode *sub_node; ++ GList *p; ++ const gchar *name = NULL; ++ GList *variant_list = NULL; ++ ++ g_assert (node != NULL); ++ for (p = node->sub_nodes; p; p = p->next) { ++ sub_node = (XMLNode *) p->data; ++ if (g_strcmp0 (sub_node->name, "configItem") == 0) { ++ name = parse_xkb_xml_configitem_node (priv, sub_node); ++ continue; ++ } ++ if (g_strcmp0 (sub_node->name, "variantList") == 0) { ++ if (name == NULL) { ++ g_warning ("layout name is NULL in node %s", node->name); ++ continue; ++ } ++ variant_list = parse_xkb_xml_variantlist_node (priv, sub_node, ++ name, ++ variant_list); ++ continue; ++ } ++ } ++ if (g_hash_table_lookup (priv->layout_list, name) != NULL) { ++ g_warning ("duplicated name %s exists", name); ++ return; ++ } ++ g_hash_table_insert (priv->layout_list, ++ (gpointer) g_strdup (name), ++ (gpointer) variant_list); ++} ++ ++static void ++parse_xkb_xml_top_node (IBusXKBConfigRegistryPrivate *priv, ++ XMLNode *parent_node) ++{ ++ XMLNode *node = parent_node; ++ XMLNode *sub_node; ++ GList *p; ++ ++ g_assert (priv != NULL); ++ g_assert (node != NULL); ++ ++ if (g_strcmp0 (node->name, "xkbConfigRegistry") != 0) { ++ g_warning ("node has no xkbConfigRegistry name"); ++ return; ++ } ++ for (p = node->sub_nodes; p; p = p->next) { ++ sub_node = (XMLNode *) p->data; ++ if (g_strcmp0 (sub_node->name, "layoutList") == 0) { ++ break; ++ } ++ } ++ if (p == NULL) { ++ g_warning ("xkbConfigRegistry node has no layoutList node"); ++ return; ++ } ++ node = sub_node; ++ for (p = node->sub_nodes; p; p = p->next) { ++ sub_node = (XMLNode *) p->data; ++ if (g_strcmp0 (sub_node->name, "layout") == 0) { ++ parse_xkb_xml_layout_node (priv, sub_node); ++ continue; ++ } ++ } ++} ++ ++static void ++free_lang_list (GList *list) ++{ ++ GList *l = list; ++ while (l) { ++ g_free (l->data); ++ l->data = NULL; ++ l = l->next; ++ } ++ g_list_free (list); ++} ++ ++static void ++parse_xkb_config_registry_file (IBusXKBConfigRegistryPrivate *priv, ++ const gchar *file) ++{ ++ XMLNode *node; ++ ++ g_assert (file != NULL); ++ ++ priv->layout_list = g_hash_table_new_full (g_str_hash, ++ (GEqualFunc) g_str_equal, ++ (GDestroyNotify) g_free, ++ (GDestroyNotify) free_lang_list); ++ priv->layout_desc = g_hash_table_new_full (g_str_hash, ++ (GEqualFunc) g_str_equal, ++ (GDestroyNotify) g_free, ++ (GDestroyNotify) g_free); ++ priv->layout_lang = g_hash_table_new_full (g_str_hash, ++ (GEqualFunc) g_str_equal, ++ (GDestroyNotify) g_free, ++ (GDestroyNotify) free_lang_list); ++ priv->variant_desc = g_hash_table_new_full (g_str_hash, ++ (GEqualFunc) g_str_equal, ++ (GDestroyNotify) g_free, ++ (GDestroyNotify) g_free); ++ node = ibus_xml_parse_file (file); ++ parse_xkb_xml_top_node (priv, node); ++ ibus_xml_free (node); ++} ++ ++static void ++ibus_xkb_config_registry_init (IBusXKBConfigRegistry *xkb_config) ++{ ++ IBusXKBConfigRegistryPrivate *priv; ++ const gchar *file = XKB_RULES_XML_FILE; ++ ++ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config); ++ parse_xkb_config_registry_file (priv, file); ++} ++ ++static void ++ibus_xkb_config_registry_destroy (IBusXKBConfigRegistry *xkb_config) ++{ ++ IBusXKBConfigRegistryPrivate *priv; ++ ++ g_return_if_fail (xkb_config != NULL); ++ ++ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config); ++ ++ g_hash_table_destroy (priv->layout_list); ++ priv->layout_list = NULL; ++ g_hash_table_destroy (priv->layout_lang); ++ priv->layout_lang= NULL; ++ g_hash_table_destroy (priv->layout_desc); ++ priv->layout_desc= NULL; ++ g_hash_table_destroy (priv->variant_desc); ++ priv->variant_desc = NULL; ++ ++ IBUS_OBJECT_CLASS(ibus_xkb_config_registry_parent_class)->destroy (IBUS_OBJECT (xkb_config)); ++} ++ ++static void ++ibus_xkb_config_registry_class_init (IBusXKBConfigRegistryClass *klass) ++{ ++ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass); ++ ++ g_type_class_add_private (klass, sizeof (IBusXKBConfigRegistryPrivate)); ++ ++ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_xkb_config_registry_destroy; ++} ++ ++IBusXKBConfigRegistry * ++ibus_xkb_config_registry_new (void) ++{ ++ IBusXKBConfigRegistry *xkb_config; ++ ++ xkb_config = IBUS_XKB_CONFIG_REGISTRY (g_object_new (IBUS_TYPE_XKB_CONFIG_REGISTRY, NULL)); ++ return xkb_config; ++} ++ ++#define TABLE_FUNC(field_name) const GHashTable * \ ++ibus_xkb_config_registry_get_##field_name (IBusXKBConfigRegistry *xkb_config) \ ++{ \ ++ IBusXKBConfigRegistryPrivate *priv; \ ++ \ ++ g_return_val_if_fail (xkb_config != NULL, NULL); \ ++ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config); \ ++ return priv->field_name; \ ++} ++ ++TABLE_FUNC (layout_list) ++TABLE_FUNC (layout_lang) ++TABLE_FUNC (layout_desc) ++TABLE_FUNC (variant_desc) ++ ++#undef TABLE_FUNC ++ ++#define TABLE_LOOKUP_LIST_FUNC(field_name, value) GList * \ ++ibus_xkb_config_registry_##field_name##_get_##value (IBusXKBConfigRegistry *xkb_config, const gchar *key) \ ++{ \ ++ GHashTable *table; \ ++ GList *list = NULL; \ ++ \ ++ table = (GHashTable *) \ ++ ibus_xkb_config_registry_get_##field_name (xkb_config); \ ++ list = (GList *) g_hash_table_lookup (table, key); \ ++ return g_list_copy (list); \ ++} ++ ++#define TABLE_LOOKUP_STRING_FUNC(field_name, value) gchar * \ ++ibus_xkb_config_registry_##field_name##_get_##value (IBusXKBConfigRegistry *xkb_config, const gchar *key) \ ++{ \ ++ GHashTable *table; \ ++ const gchar *desc = NULL; \ ++ \ ++ table = (GHashTable *) \ ++ ibus_xkb_config_registry_get_##field_name (xkb_config); \ ++ desc = (const gchar *) g_hash_table_lookup (table, key); \ ++ return g_strdup (desc); \ ++} ++ ++TABLE_LOOKUP_LIST_FUNC (layout_list, variants) ++TABLE_LOOKUP_LIST_FUNC (layout_lang, langs) ++TABLE_LOOKUP_STRING_FUNC (layout_desc, desc) ++TABLE_LOOKUP_STRING_FUNC (variant_desc, desc) ++ ++#undef TABLE_LOOKUP_LIST_FUNC ++#undef TABLE_LOOKUP_STRING_FUNC +diff --git a/src/ibusxkbxml.h b/src/ibusxkbxml.h +new file mode 100644 +index 0000000..6986b5c +--- /dev/null ++++ b/src/ibusxkbxml.h +@@ -0,0 +1,172 @@ ++/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ ++/* vim:set et sts=4: */ ++/* bus - The Input Bus ++ * Copyright (C) 2011 Takao Fujiwara ++ * Copyright (C) 2011 Peng Huang ++ * Copyright (C) 2011 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 02111-1307, USA. ++ */ ++#ifndef __IBUS_XKBXML_H_ ++#define __IBUS_XKBXML_H_ ++ ++#include "ibus.h" ++ ++/* ++ * Type macros. ++ */ ++/* define IBusXKBConfigRegistry macros */ ++#define IBUS_TYPE_XKB_CONFIG_REGISTRY \ ++ (ibus_xkb_config_registry_get_type ()) ++#define IBUS_XKB_CONFIG_REGISTRY(obj) \ ++ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistry)) ++#define IBUS_XKB_CONFIG_REGISTRY_CLASS(klass) \ ++ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryClass)) ++#define IBUS_IS_XKB_CONFIG_REGISTRY(obj) \ ++ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY)) ++#define IBUS_IS_XKB_CONFIG_REGISTRY_CLASS(klass) \ ++ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_XKB_CONFIG_REGISTRY)) ++#define IBUS_XKB_CONFIG_REGISTRY_GET_CLASS(obj) \ ++ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryClass)) ++ ++G_BEGIN_DECLS ++ ++typedef struct _IBusXKBConfigRegistry IBusXKBConfigRegistry; ++typedef struct _IBusXKBConfigRegistryClass IBusXKBConfigRegistryClass; ++ ++struct _IBusXKBConfigRegistry { ++ IBusObject parent; ++}; ++ ++struct _IBusXKBConfigRegistryClass { ++ IBusObjectClass parent; ++ /* signals */ ++ /*< private >*/ ++ /* padding */ ++ gpointer pdummy[8]; ++}; ++ ++ ++GType ibus_xkb_config_registry_get_type ++ (void); ++ ++/** ++ * ibus_xkb_config_registry_new: ++ * @returns: A newly allocated IBusXKBConfigRegistry ++ * ++ * New an IBusXKBConfigRegistry. ++ */ ++IBusXKBConfigRegistry * ++ ibus_xkb_config_registry_new ++ (void); ++ ++/** ++ * ibus_xkb_config_registry_get_layout_list: (skip) ++ * @xkb_config: An IBusXKBConfigRegistry. ++ * @returns: A const GHashTable ++ * ++ * a const GHashTable ++ */ ++const GHashTable * ++ ibus_xkb_config_registry_get_layout_list ++ (IBusXKBConfigRegistry *xkb_config); ++ ++/** ++ * ibus_xkb_config_registry_get_layout_lang: (skip) ++ * @xkb_config: An IBusXKBConfigRegistry. ++ * @returns: A const GHashTable ++ * ++ * a const GHashTable ++ */ ++const GHashTable * ++ ibus_xkb_config_registry_get_layout_lang ++ (IBusXKBConfigRegistry *xkb_config); ++ ++/** ++ * ibus_xkb_config_registry_get_layout_desc: (skip) ++ * @xkb_config: An IBusXKBConfigRegistry. ++ * @returns: A const GHashTable ++ * ++ * a const GHashTable ++ */ ++const GHashTable * ++ ibus_xkb_config_registry_get_layout_desc ++ (IBusXKBConfigRegistry *xkb_config); ++ ++/** ++ * ibus_xkb_config_registry_get_variant_desc: (skip) ++ * @xkb_config: An IBusXKBConfigRegistry. ++ * @returns: A const GHashTable ++ * ++ * a const GHashTable ++ */ ++const GHashTable * ++ ibus_xkb_config_registry_get_variant_desc ++ (IBusXKBConfigRegistry *xkb_config); ++ ++/** ++ * ibus_xkb_config_registry_layout_list_get_variants: ++ * @xkb_config: An IBusXKBConfigRegistry. ++ * @layout: A layout. ++ * @returns: (transfer container) (element-type utf8): A GList ++ * ++ * a GList ++ */ ++GList * ++ ibus_xkb_config_registry_layout_list_get_variants ++ (IBusXKBConfigRegistry *xkb_config, ++ const gchar *layout); ++ ++/** ++ * ibus_xkb_config_registry_layout_lang_get_langs: ++ * @xkb_config: An IBusXKBConfigRegistry. ++ * @layout: A layout. ++ * @returns: (transfer container) (element-type utf8): A GList ++ * ++ * a GList ++ */ ++GList * ++ ibus_xkb_config_registry_layout_lang_get_langs ++ (IBusXKBConfigRegistry *xkb_config, ++ const gchar *layout); ++ ++/** ++ * ibus_xkb_config_registry_layout_desc_get_desc: ++ * @xkb_config: An IBusXKBConfigRegistry. ++ * @layout: A layout. ++ * @returns: A layout description ++ * ++ * a layout description ++ */ ++gchar * ++ ibus_xkb_config_registry_layout_desc_get_desc ++ (IBusXKBConfigRegistry *xkb_config, ++ const gchar *layout); ++ ++/** ++ * ibus_xkb_config_registry_variant_desc_get_desc: ++ * @xkb_config: An IBusXKBConfigRegistry. ++ * @variant: A variant. ++ * @returns: A variant description ++ * ++ * a variant description ++ */ ++gchar * ++ ibus_xkb_config_registry_variant_desc_get_desc ++ (IBusXKBConfigRegistry *xkb_config, ++ const gchar *variant); ++G_END_DECLS ++#endif +diff --git a/ui/gtk/panel.py b/ui/gtk/panel.py +index 90be1d5..de64920 100644 +--- a/ui/gtk/panel.py ++++ b/ui/gtk/panel.py +@@ -132,6 +132,22 @@ class Panel(ibus.PanelBase): + self.__config_load_show_im_name() + # self.__bus.request_name(ibus.panel.IBUS_SERVICE_PANEL, 0) + ++ # init xkb ++ self.__xkblayout = ibus.XKBLayout(self.__config) ++ use_xkb = self.__config.get_value("general", "use_system_keyboard_layout", False) ++ if not use_xkb: ++ self.__xkblayout.use_xkb(use_xkb) ++ value = str(self.__config.get_value("general", "system_keyboard_layout", '')) ++ if value == '': ++ value = 'default' ++ if value != 'default': ++ self.__xkblayout.set_default_layout(value) ++ value = str(self.__config.get_value("general", "system_keyboard_option", '')) ++ if value == '': ++ value = 'default' ++ if value != 'default': ++ self.__xkblayout.set_default_option(value) ++ + def set_cursor_location(self, x, y, w, h): + self.__candidate_panel.set_cursor_location(x, y, w, h) + +@@ -226,14 +242,20 @@ class Panel(ibus.PanelBase): + if not enabled: + self.__set_im_icon(ICON_KEYBOARD) + self.__set_im_name(None) ++ if self.__bus.get_use_sys_layout(): ++ self.__xkblayout.set_layout() + else: + engine = self.__focus_ic.get_engine() + if engine: + self.__set_im_icon(engine.icon) + self.__set_im_name(engine.longname) ++ if self.__bus.get_use_sys_layout(): ++ self.__xkblayout.set_layout(self.__engine_get_layout_wrapper(engine)) + else: + self.__set_im_icon(ICON_KEYBOARD) + self.__set_im_name(None) ++ if self.__bus.get_use_sys_layout(): ++ self.__xkblayout.set_layout() + self.__language_bar.focus_in() + + def focus_out(self, ic): +@@ -243,6 +265,8 @@ class Panel(ibus.PanelBase): + self.__language_bar.focus_out() + self.__set_im_icon(ICON_KEYBOARD) + self.__set_im_name(None) ++ if self.__bus.get_use_sys_layout(): ++ self.__xkblayout.set_layout() + + def state_changed(self): + if not self.__focus_ic: +@@ -255,14 +279,20 @@ class Panel(ibus.PanelBase): + self.reset() + self.__set_im_icon(ICON_KEYBOARD) + self.__set_im_name(None) ++ if self.__bus.get_use_sys_layout(): ++ self.__xkblayout.set_layout() + else: + engine = self.__focus_ic.get_engine() + if engine: + self.__set_im_icon(engine.icon) + self.__set_im_name(engine.longname) ++ if self.__bus.get_use_sys_layout(): ++ self.__xkblayout.set_layout(self.__engine_get_layout_wrapper(engine)) + else: + self.__set_im_icon(ICON_KEYBOARD) + self.__set_im_name(None) ++ if self.__bus.get_use_sys_layout(): ++ self.__xkblayout.set_layout() + + + def reset(self): +@@ -542,3 +572,12 @@ class Panel(ibus.PanelBase): + flags=glib.SPAWN_DO_NOT_REAP_CHILD)[0] + self.__setup_pid = pid + glib.child_watch_add(self.__setup_pid, self.__child_watch_cb) ++ ++ def __engine_get_layout_wrapper(self, engine): ++ # This code is for the back compatibility. ++ # Should we remove the codes after all IM engines are changed ++ # to "default" layout? ++ if engine.name != None and engine.name.startswith("xkb:layout:"): ++ return engine.layout ++ else: ++ return "default" +diff --git a/xkb/Makefile.am b/xkb/Makefile.am +new file mode 100644 +index 0000000..ad9cdd9 +--- /dev/null ++++ b/xkb/Makefile.am +@@ -0,0 +1,104 @@ ++# vim:set noet ts=4: ++# ++# ibus - The Input Bus ++# ++# Copyright (C) 2011 Takao Fujiwara ++# Copyright (c) 2011 Peng Huang ++# Copyright (c) 2011 Red Hat, Inc. ++# ++# This library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2 of the License, or (at your option) any later version. ++# ++# This library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the ++# Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++# Boston, MA 02111-1307 USA ++ ++libibus = $(top_builddir)/src/libibus-@IBUS_API_VERSION@.la ++ ++INCLUDES = \ ++ -I$(top_srcdir) \ ++ -I$(top_srcdir)/src \ ++ -DIBUS_LOCALEDIR=\"$(datadir)/locale\" \ ++ -DLIBEXECDIR=\""$(libexecdir)"\" \ ++ $(NULL) ++ ++noinst_PROGRAMS = $(TESTS) ++libexec_PROGRAMS = ++EXTRA_DIST = ++DISTCLEANFILES = ++ ++if ENABLE_XKB ++libexec_PROGRAMS += ibus-xkb ++ibus_xkb_SOURCES = \ ++ ibus-xkb-main.c \ ++ xkblib.h \ ++ xkblib.c \ ++ $(NULL) ++ibus_xkb_CFLAGS = \ ++ @XKB_CFLAGS@ \ ++ @X11_CFLAGS@ \ ++ @GLIB2_CFLAGS@ \ ++ $(NULL) ++ibus_xkb_LDADD = \ ++ @XKB_LIBS@ \ ++ @X11_LIBS@ \ ++ @GLIB2_LIBS@ \ ++ $(libibus) \ ++ $(NULL) ++ ++libexec_PROGRAMS += ibus-engine-xkb ++ibus_engine_xkb_SOURCES = \ ++ ibus-engine-xkb-main.c \ ++ ibus-engine-xkb-main.h \ ++ xkbxml.c \ ++ xkbxml.h \ ++ $(NULL) ++ibus_engine_xkb_CFLAGS = \ ++ @GLIB2_CFLAGS@ \ ++ @GOBJECT2_CFLAGS@ \ ++ @GCONF_CFLAGS@ \ ++ $(NULL) ++ibus_engine_xkb_LDADD = \ ++ @GLIB2_LIBS@ \ ++ @GOBJECT2_LIBS@ \ ++ @GCONF_LIBS@ \ ++ $(libibus) \ ++ $(NULL) ++ ++xkblayoutdir = $(datadir)/ibus/component ++xkblayout_in_files = xkblayout.xml.in ++xkblayout_DATA = $(xkblayout_in_files:.xml.in=.xml) ++ ++xkblayoutconfigdir = $(datadir)/ibus/xkb ++xkblayoutconfig_in_files = xkblayoutconfig.xml.in ++xkblayoutconfig_DATA = $(xkblayoutconfig_in_files:.xml.in=.xml) ++ ++%.xml : %.xml.in ++ @sed -e "s|\@libexecdir\@|$(libexecdir)|g" \ ++ -e "s|\@datadir\@|$(datadir)|g" \ ++ -e "s|\@XKB_PRELOAD_LAYOUTS\@|$(XKB_PRELOAD_LAYOUTS)|g" \ ++ $< > $@ ++ ++INCLUDES += \ ++ -DXKBLAYOUTCONFIG_FILE=\""$(xkblayoutconfigdir)/$(xkblayoutconfig_DATA)"\" \ ++ $(NULL) ++ ++EXTRA_DIST += \ ++ $(xkblayout_in_files) \ ++ $(xkblayoutconfig_in_files) \ ++ $(NULL) ++ ++DISTCLEANFILES += \ ++ $(xkblayout_DATA) \ ++ $(xkblayoutconfig_DATA) \ ++ $(NULL) ++ ++endif +diff --git a/xkb/ibus-engine-xkb-main.c b/xkb/ibus-engine-xkb-main.c +new file mode 100644 +index 0000000..5d748cc +--- /dev/null ++++ b/xkb/ibus-engine-xkb-main.c +@@ -0,0 +1,397 @@ ++/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ ++/* vim:set et sts=4: */ ++/* bus - The Input Bus ++ * Copyright (C) 2011 Takao Fujiwara ++ * Copyright (C) 2011 Peng Huang ++ * Copyright (C) 2011 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 02111-1307, USA. ++ */ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++ ++#ifdef ENABLE_NLS ++#include ++#endif ++ ++#include "ibus-engine-xkb-main.h" ++#include "xkbxml.h" ++ ++#define IBUS_TYPE_XKB_ENGINE (ibus_xkb_engine_get_type ()) ++ ++static IBusBus *bus = NULL; ++static IBusFactory *factory = NULL; ++static IBusEngineClass *parent_class = NULL; ++static gboolean ibus = FALSE; ++static gboolean xml = FALSE; ++ ++static const GOptionEntry entries[] = ++{ ++ { "ibus", 'i', 0, G_OPTION_ARG_NONE, &ibus, "component is executed by ibus", NULL }, ++ { "xml", 'x', 0, G_OPTION_ARG_NONE, &xml, "print component xml", NULL }, + { NULL }, +}; + @@ -2808,16 +3466,16 @@ index 0000000..e1861e8 +} diff --git a/xkb/ibus-engine-xkb-main.h b/xkb/ibus-engine-xkb-main.h new file mode 100644 -index 0000000..8007631 +index 0000000..c17c857 --- /dev/null +++ b/xkb/ibus-engine-xkb-main.h @@ -0,0 +1,46 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* vim:set et sts=4: */ +/* bus - The Input Bus -+ * Copyright (C) 2010 Takao Fujiwara -+ * Copyright (C) 2008-2010 Peng Huang -+ * Copyright (C) 2008-2010 Red Hat, Inc. ++ * Copyright (C) 2011 Takao Fujiwara ++ * Copyright (C) 2011 Peng Huang ++ * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public @@ -2860,16 +3518,16 @@ index 0000000..8007631 +#endif diff --git a/xkb/ibus-xkb-main.c b/xkb/ibus-xkb-main.c new file mode 100644 -index 0000000..9db7d0a +index 0000000..ef57553 --- /dev/null +++ b/xkb/ibus-xkb-main.c -@@ -0,0 +1,105 @@ +@@ -0,0 +1,112 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* vim:set et sts=4: */ +/* bus - The Input Bus -+ * Copyright (C) 2010 Takao Fujiwara -+ * Copyright (C) 2008-2010 Peng Huang -+ * Copyright (C) 2008-2010 Red Hat, Inc. ++ * Copyright (C) 2011 Takao Fujiwara ++ * Copyright (C) 2011 Peng Huang ++ * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public @@ -2902,9 +3560,11 @@ index 0000000..9db7d0a +#include "xkblib.h" + +static gboolean get_layout = FALSE; ++static gboolean get_group = FALSE; +static gchar *layout = NULL; +static gchar *model = NULL; +static gchar *option = NULL; ++static int group = 0; + +static const GOptionEntry entries[] = +{ @@ -2913,6 +3573,7 @@ index 0000000..9db7d0a + { "layout", 'l', 0, G_OPTION_ARG_STRING, &layout, N_("Set xkb layout"), "layout" }, + { "model", 'm', 0, G_OPTION_ARG_STRING, &model, N_("Set xkb model"), "model" }, + { "option", 'o', 0, G_OPTION_ARG_STRING, &option, N_("Set xkb option"), "option" }, ++ { "get-group", 'G', 0, G_OPTION_ARG_NONE, &get_group, N_("Get current xkb state"), NULL }, + { NULL }, +}; + @@ -2964,6 +3625,10 @@ index 0000000..9db7d0a + g_free (model); + g_free (option); + } ++ if (get_group) { ++ group = ibus_xkb_get_current_group (); ++ g_printf ("group: %d\n", group); ++ } + + ibus_xkb_finit (); + @@ -3005,16 +3670,16 @@ index 0000000..b1212d1 + diff --git a/xkb/xkblib.c b/xkb/xkblib.c new file mode 100644 -index 0000000..640f783 +index 0000000..293cdaf --- /dev/null +++ b/xkb/xkblib.c -@@ -0,0 +1,303 @@ +@@ -0,0 +1,327 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* vim:set et sts=4: */ +/* bus - The Input Bus -+ * Copyright (C) 2010 Takao Fujiwara -+ * Copyright (C) 2008-2010 Peng Huang -+ * Copyright (C) 2008-2010 Red Hat, Inc. ++ * Copyright (C) 2011 Takao Fujiwara ++ * Copyright (C) 2011 Peng Huang ++ * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public @@ -3292,7 +3957,7 @@ index 0000000..640f783 + + if (default_layouts == NULL) { + g_warning ("Your system seems not to support XKB."); -+ return NULL; ++ return FALSE; + } + + if (layouts == NULL || g_strcmp0 (layouts, "default") == 0) { @@ -3312,18 +3977,42 @@ index 0000000..640f783 + + return retval; +} ++ ++int ++ibus_xkb_get_current_group (void) ++{ ++ Display *xdisplay = get_xdisplay (NULL); ++ XkbStateRec state; ++ ++ if (default_layouts == NULL) { ++ g_warning ("Your system seems not to support XKB."); ++ return 0; ++ } ++ ++ if (xdisplay == NULL) { ++ g_warning ("ibus-xkb is not initialized."); ++ return 0; ++ } ++ ++ if (XkbGetState (xdisplay, XkbUseCoreKbd, &state) != Success) { ++ g_warning ("Could not get state"); ++ return 0; ++ } ++ ++ return state.group; ++} diff --git a/xkb/xkblib.h b/xkb/xkblib.h new file mode 100644 -index 0000000..09d506d +index 0000000..15e5d18 --- /dev/null +++ b/xkb/xkblib.h -@@ -0,0 +1,40 @@ +@@ -0,0 +1,41 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* vim:set et sts=4: */ +/* bus - The Input Bus -+ * Copyright (C) 2010 Takao Fujiwara -+ * Copyright (C) 2008-2010 Peng Huang -+ * Copyright (C) 2008-2010 Red Hat, Inc. ++ * Copyright (C) 2011 Takao Fujiwara ++ * Copyright (C) 2011 Peng Huang ++ * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public @@ -3355,21 +4044,22 @@ index 0000000..09d506d +gboolean ibus_xkb_set_layout (const char *layouts, + const char *variants, + const char *options); ++int ibus_xkb_get_current_group (void); + +G_END_DECLS +#endif diff --git a/xkb/xkbxml.c b/xkb/xkbxml.c new file mode 100644 -index 0000000..f5582ff +index 0000000..2ce7bcf --- /dev/null +++ b/xkb/xkbxml.c -@@ -0,0 +1,696 @@ +@@ -0,0 +1,335 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* vim:set et sts=4: */ +/* bus - The Input Bus -+ * Copyright (C) 2010 Takao Fujiwara -+ * Copyright (C) 2008-2010 Peng Huang -+ * Copyright (C) 2008-2010 Red Hat, Inc. ++ * Copyright (C) 2011 Takao Fujiwara ++ * Copyright (C) 2011 Peng Huang ++ * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public @@ -3392,294 +4082,29 @@ index 0000000..f5582ff + +#include + -+#include "xkbxml.h" -+#include "ibus.h" -+ -+#ifndef XKB_RULES_XML_FILE -+#define XKB_RULES_XML_FILE "/usr/share/X11/xkb/rules/evdev.xml" -+#endif -+ -+#define IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE(o) \ -+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryPrivate)) -+#define IBUS_XKB_LAYOUT_CONFIG_GET_PRIVATE(o) \ -+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_XKB_LAYOUT_CONFIG, IBusXKBLayoutConfigPrivate)) -+ -+typedef struct _IBusXKBConfigRegistryPrivate IBusXKBConfigRegistryPrivate; -+typedef struct _IBusXKBLayoutConfigPrivate IBusXKBLayoutConfigPrivate; -+ -+enum { -+ PROP_0, -+ PROP_SYSTEM_CONFIG_FILE, -+}; -+ -+struct _IBusXKBConfigRegistryPrivate { -+ GHashTable *layout_list; -+ GHashTable *layout_lang; -+ GHashTable *layout_desc; -+ GHashTable *variant_desc; -+}; -+ -+struct _IBusXKBLayoutConfigPrivate { -+ gchar *system_config_file; -+ GList *preload_layouts; -+}; -+ -+/* functions prototype */ -+static void ibus_xkb_config_registry_destroy -+ (IBusXKBConfigRegistry *xkb_config); -+static void ibus_xkb_layout_config_destroy -+ (IBusXKBLayoutConfig *xkb_layout_config); -+ -+G_DEFINE_TYPE (IBusXKBConfigRegistry, ibus_xkb_config_registry, IBUS_TYPE_OBJECT) -+G_DEFINE_TYPE (IBusXKBLayoutConfig, ibus_xkb_layout_config, IBUS_TYPE_OBJECT) -+ -+static void -+parse_xkb_xml_languagelist_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node, -+ const gchar *layout_name) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ GList *lang_list = NULL; -+ -+ g_assert (node != NULL); -+ g_assert (layout_name != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "iso639Id") == 0) { -+ lang_list = g_list_append (lang_list, -+ (gpointer) g_strdup (sub_node->text)); -+ continue; -+ } -+ } -+ if (lang_list == NULL) { -+ /* some nodes have no lang */ -+ return; -+ } -+ if (g_hash_table_lookup (priv->layout_lang, layout_name) != NULL) { -+ g_warning ("duplicated name %s exists", layout_name); -+ return; -+ } -+ g_hash_table_insert (priv->layout_lang, -+ (gpointer) g_strdup (layout_name), -+ (gpointer) lang_list); -+} -+ -+static const gchar * -+parse_xkb_xml_configitem_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ gchar *name = NULL; -+ gchar *description = NULL; -+ -+ g_assert (node != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "name") == 0) { -+ name = sub_node->text; -+ continue; -+ } -+ if (g_strcmp0 (sub_node->name, "description") == 0) { -+ description = sub_node->text; -+ continue; -+ } -+ if (g_strcmp0 (sub_node->name, "languageList") == 0) { -+ if (name == NULL) { -+ g_warning ("layout name is NULL in node %s", node->name); -+ continue; -+ } -+ parse_xkb_xml_languagelist_node (priv, sub_node, name); -+ continue; -+ } -+ } -+ if (name == NULL) { -+ g_warning ("No name in layout node"); -+ return NULL; -+ } -+ if (g_hash_table_lookup (priv->layout_desc, name) != NULL) { -+ g_warning ("duplicated name %s exists", name); -+ return name; -+ } -+ g_hash_table_insert (priv->layout_desc, -+ (gpointer) g_strdup (name), -+ (gpointer) g_strdup (description)); -+ -+ return name; -+} -+ -+static const gchar * -+parse_xkb_xml_variant_configitem_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node, -+ const gchar *layout_name) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ gchar *name = NULL; -+ gchar *description = NULL; -+ gchar *variant_lang_name = NULL; -+ -+ g_assert (node != NULL); -+ g_assert (layout_name != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "name") == 0) { -+ name = sub_node->text; -+ continue; -+ } -+ if (g_strcmp0 (sub_node->name, "description") == 0) { -+ description = sub_node->text; -+ continue; -+ } -+ if (g_strcmp0 (sub_node->name, "languageList") == 0) { -+ if (name == NULL) { -+ g_warning ("layout name is NULL in node %s", node->name); -+ continue; -+ } -+ variant_lang_name = g_strdup_printf ("%s(%s)", layout_name, name); -+ parse_xkb_xml_languagelist_node (priv, sub_node, variant_lang_name); -+ g_free (variant_lang_name); -+ continue; -+ } -+ } -+ if (name == NULL) { -+ g_warning ("No name in layout node"); -+ return NULL; -+ } -+ if (g_hash_table_lookup (priv->variant_desc, name) != NULL) { -+ /* This is an expected case. */ -+ return name; -+ } -+ g_hash_table_insert (priv->variant_desc, -+ (gpointer) g_strdup (name), -+ (gpointer) g_strdup (description)); -+ return name; -+} -+ -+static const gchar * -+parse_xkb_xml_variant_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node, -+ const gchar *layout_name) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ const gchar *variant_name = NULL; -+ -+ g_assert (node != NULL); -+ g_assert (layout_name != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "configItem") == 0) { -+ variant_name = parse_xkb_xml_variant_configitem_node (priv, sub_node, layout_name); -+ continue; -+ } -+ } -+ return variant_name; -+} -+ -+static GList * -+parse_xkb_xml_variantlist_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node, -+ const gchar *layout_name, -+ GList *variant_list) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ const gchar *variant_name = NULL; -+ -+ g_assert (node != NULL); -+ g_assert (layout_name != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "variant") == 0) { -+ variant_name = parse_xkb_xml_variant_node (priv, sub_node, layout_name); -+ if (variant_name != NULL) { -+ variant_list = g_list_append (variant_list, -+ (gpointer) g_strdup (variant_name)); -+ } -+ continue; -+ } -+ } -+ return variant_list; -+} ++#include "xkbxml.h" ++#include "ibus.h" + -+static void -+parse_xkb_xml_layout_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ const gchar *name = NULL; -+ GList *variant_list = NULL; ++#define IBUS_XKB_LAYOUT_CONFIG_GET_PRIVATE(o) \ ++ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_XKB_LAYOUT_CONFIG, IBusXKBLayoutConfigPrivate)) + -+ g_assert (node != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "configItem") == 0) { -+ name = parse_xkb_xml_configitem_node (priv, sub_node); -+ continue; -+ } -+ if (g_strcmp0 (sub_node->name, "variantList") == 0) { -+ if (name == NULL) { -+ g_warning ("layout name is NULL in node %s", node->name); -+ continue; -+ } -+ variant_list = parse_xkb_xml_variantlist_node (priv, sub_node, -+ name, -+ variant_list); -+ continue; -+ } -+ } -+ if (g_hash_table_lookup (priv->layout_list, name) != NULL) { -+ g_warning ("duplicated name %s exists", name); -+ return; -+ } -+ g_hash_table_insert (priv->layout_list, -+ (gpointer) g_strdup (name), -+ (gpointer) variant_list); -+} ++typedef struct _IBusXKBLayoutConfigPrivate IBusXKBLayoutConfigPrivate; + -+static void -+parse_xkb_xml_top_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; ++enum { ++ PROP_0, ++ PROP_SYSTEM_CONFIG_FILE, ++}; + -+ g_assert (priv != NULL); -+ g_assert (node != NULL); ++struct _IBusXKBLayoutConfigPrivate { ++ gchar *system_config_file; ++ GList *preload_layouts; ++}; + -+ if (g_strcmp0 (node->name, "xkbConfigRegistry") != 0) { -+ g_warning ("node has no xkbConfigRegistry name"); -+ return; -+ } -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "layoutList") == 0) { -+ break; -+ } -+ } -+ if (p == NULL) { -+ g_warning ("xkbConfigRegistry node has no layoutList node"); -+ return; -+ } -+ node = sub_node; -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "layout") == 0) { -+ parse_xkb_xml_layout_node (priv, sub_node); -+ continue; -+ } -+ } -+} ++/* functions prototype */ ++static void ibus_xkb_layout_config_destroy ++ (IBusXKBLayoutConfig *xkb_layout_config); ++ ++G_DEFINE_TYPE (IBusXKBLayoutConfig, ibus_xkb_layout_config, IBUS_TYPE_OBJECT) + +static void +free_lang_list (GList *list) @@ -3693,35 +4118,6 @@ index 0000000..f5582ff + g_list_free (list); +} + -+static void -+parse_xkb_config_registry_file (IBusXKBConfigRegistryPrivate *priv, -+ const gchar *file) -+{ -+ XMLNode *node; -+ -+ g_assert (file != NULL); -+ -+ priv->layout_list = g_hash_table_new_full (g_str_hash, -+ (GEqualFunc) g_str_equal, -+ (GDestroyNotify) g_free, -+ (GDestroyNotify) free_lang_list); -+ priv->layout_desc = g_hash_table_new_full (g_str_hash, -+ (GEqualFunc) g_str_equal, -+ (GDestroyNotify) g_free, -+ (GDestroyNotify) g_free); -+ priv->layout_lang = g_hash_table_new_full (g_str_hash, -+ (GEqualFunc) g_str_equal, -+ (GDestroyNotify) g_free, -+ (GDestroyNotify) free_lang_list); -+ priv->variant_desc = g_hash_table_new_full (g_str_hash, -+ (GEqualFunc) g_str_equal, -+ (GDestroyNotify) g_free, -+ (GDestroyNotify) g_free); -+ node = ibus_xml_parse_file (file); -+ parse_xkb_xml_top_node (priv, node); -+ ibus_xml_free (node); -+} -+ +static GList * +parse_xkblayoutconfig_file (gchar *path) +{ @@ -3794,47 +4190,6 @@ index 0000000..f5582ff +} + +static void -+ibus_xkb_config_registry_init (IBusXKBConfigRegistry *xkb_config) -+{ -+ IBusXKBConfigRegistryPrivate *priv; -+ const gchar *file = XKB_RULES_XML_FILE; -+ -+ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config); -+ parse_xkb_config_registry_file (priv, file); -+} -+ -+static void -+ibus_xkb_config_registry_destroy (IBusXKBConfigRegistry *xkb_config) -+{ -+ IBusXKBConfigRegistryPrivate *priv; -+ -+ g_return_if_fail (xkb_config != NULL); -+ -+ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config); -+ -+ g_hash_table_destroy (priv->layout_list); -+ priv->layout_list = NULL; -+ g_hash_table_destroy (priv->layout_lang); -+ priv->layout_lang= NULL; -+ g_hash_table_destroy (priv->layout_desc); -+ priv->layout_desc= NULL; -+ g_hash_table_destroy (priv->variant_desc); -+ priv->variant_desc = NULL; -+ -+ IBUS_OBJECT_CLASS(ibus_xkb_config_registry_parent_class)->destroy (IBUS_OBJECT (xkb_config)); -+} -+ -+static void -+ibus_xkb_config_registry_class_init (IBusXKBConfigRegistryClass *klass) -+{ -+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass); -+ -+ g_type_class_add_private (klass, sizeof (IBusXKBConfigRegistryPrivate)); -+ -+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_xkb_config_registry_destroy; -+} -+ -+static void +ibus_xkb_layout_config_init (IBusXKBLayoutConfig *xkb_layout_config) +{ + IBusXKBLayoutConfigPrivate *priv; @@ -3945,32 +4300,6 @@ index 0000000..f5582ff + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + -+IBusXKBConfigRegistry * -+ibus_xkb_config_registry_new (void) -+{ -+ IBusXKBConfigRegistry *xkb_config; -+ -+ xkb_config = IBUS_XKB_CONFIG_REGISTRY (g_object_new (IBUS_TYPE_XKB_CONFIG_REGISTRY, NULL)); -+ return xkb_config; -+} -+ -+#define TABLE_FUNC(field_name) const GHashTable * \ -+ibus_xkb_config_registry_get_##field_name (IBusXKBConfigRegistry *xkb_config) \ -+{ \ -+ IBusXKBConfigRegistryPrivate *priv; \ -+ \ -+ g_return_val_if_fail (xkb_config != NULL, NULL); \ -+ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config); \ -+ return priv->field_name; \ -+} -+ -+TABLE_FUNC (layout_list) -+TABLE_FUNC (layout_lang) -+TABLE_FUNC (layout_desc) -+TABLE_FUNC (variant_desc) -+ -+#undef TABLE_FUNC -+ +IBusComponent * +ibus_xkb_component_new (void) +{ @@ -4062,16 +4391,16 @@ index 0000000..f5582ff +} diff --git a/xkb/xkbxml.h b/xkb/xkbxml.h new file mode 100644 -index 0000000..f4858fa +index 0000000..56811ef --- /dev/null +++ b/xkb/xkbxml.h -@@ -0,0 +1,189 @@ +@@ -0,0 +1,110 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* vim:set et sts=4: */ +/* bus - The Input Bus -+ * Copyright (C) 2010 Takao Fujiwara -+ * Copyright (C) 2008-2010 Peng Huang -+ * Copyright (C) 2008-2010 Red Hat, Inc. ++ * Copyright (C) 2011 Takao Fujiwara ++ * Copyright (C) 2011 Peng Huang ++ * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public @@ -4088,28 +4417,14 @@ index 0000000..f4858fa + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ -+#ifndef __IBUS_XKB_H_ -+#define __IBUS_XKB_H_ ++#ifndef __XKBXML_H_ ++#define __XKBXML_H_ + +#include "ibus.h" + +/* + * Type macros. + */ -+/* define IBusXKBConfigRegistry macros */ -+#define IBUS_TYPE_XKB_CONFIG_REGISTRY \ -+ (ibus_xkb_config_registry_get_type ()) -+#define IBUS_XKB_CONFIG_REGISTRY(obj) \ -+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistry)) -+#define IBUS_XKB_CONFIG_REGISTRY_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryClass)) -+#define IBUS_IS_XKB_CONFIG_REGISTRY(obj) \ -+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY)) -+#define IBUS_IS_XKB_CONFIG_REGISTRY_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_XKB_CONFIG_REGISTRY)) -+#define IBUS_XKB_CONFIG_REGISTRY_GET_CLASS(obj) \ -+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryClass)) -+ +/* define IBusXKBLayoutConfig macros */ +#define IBUS_TYPE_XKB_LAYOUT_CONFIG \ + (ibus_xkb_layout_config_get_type ()) @@ -4126,23 +4441,9 @@ index 0000000..f4858fa + +G_BEGIN_DECLS + -+typedef struct _IBusXKBConfigRegistry IBusXKBConfigRegistry; -+typedef struct _IBusXKBConfigRegistryClass IBusXKBConfigRegistryClass; +typedef struct _IBusXKBLayoutConfig IBusXKBLayoutConfig; +typedef struct _IBusXKBLayoutConfigClass IBusXKBLayoutConfigClass; + -+struct _IBusXKBConfigRegistry { -+ IBusObject parent; -+}; -+ -+struct _IBusXKBConfigRegistryClass { -+ IBusObjectClass parent; -+ /* signals */ -+ /*< private >*/ -+ /* padding */ -+ gpointer pdummy[8]; -+}; -+ +struct _IBusXKBLayoutConfig { + IBusObject parent; +}; @@ -4156,57 +4457,6 @@ index 0000000..f4858fa +}; + + -+GType ibus_xkb_config_registry_get_type -+ (void); -+/** -+ * ibus_xkb_config_registry_new: -+ * @returns: A newly allocated IBusXKBConfigRegistry -+ * -+ * New an IBusXKBConfigRegistry. -+ */ -+IBusXKBConfigRegistry * -+ ibus_xkb_config_registry_new -+ (void); -+/** -+ * ibus_xkb_config_registry_get_layout_list: -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @returns: A const GHashTable -+ * -+ * a const GHashTable -+ */ -+const GHashTable * -+ ibus_xkb_config_registry_get_layout_list -+ (IBusXKBConfigRegistry *xkb_config); -+/** -+ * ibus_xkb_config_registry_get_layout_lang: -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @returns: A const GHashTable -+ * -+ * a const GHashTable -+ */ -+const GHashTable * -+ ibus_xkb_config_registry_get_layout_lang -+ (IBusXKBConfigRegistry *xkb_config); -+/** -+ * ibus_xkb_config_registry_get_layout_desc: -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @returns: A const GHashTable -+ * -+ * a const GHashTable -+ */ -+const GHashTable * -+ ibus_xkb_config_registry_get_layout_desc -+ (IBusXKBConfigRegistry *xkb_config); -+/** -+ * ibus_xkb_config_registry_get_variant_desc: -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @returns: A const GHashTable -+ * -+ * a const GHashTable -+ */ -+const GHashTable * -+ ibus_xkb_config_registry_get_variant_desc -+ (IBusXKBConfigRegistry *xkb_config); +/** + * ibus_xkb_component_new: + * @returns: A newly allocated IBusComponent. diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch index c6a8da5..4be8960 100644 --- a/ibus-HEAD.patch +++ b/ibus-HEAD.patch @@ -226,3 +226,744 @@ index 0e9418e..39ad784 100644 -- 1.7.4.4 +From d059132885d3c90647f08f3083e39daa9f82b700 Mon Sep 17 00:00:00 2001 +From: Ryo Onodera +Date: Tue, 17 May 2011 20:07:40 +0900 +Subject: [PATCH] fix wrong forward key event signature + +--- + ibus/engine.py | 4 ++-- + ibus/interface/iengine.py | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/ibus/engine.py b/ibus/engine.py +index 8cbcee3..fe5dd98 100644 +--- a/ibus/engine.py ++++ b/ibus/engine.py +@@ -114,8 +114,8 @@ class EngineBase(object.Object): + text = serializable.serialize_object(text) + return self.__proxy.CommitText(text) + +- def forward_key_event(self, keyval, state): +- return self.__proxy.ForwardKeyEvent(keyval, state) ++ def forward_key_event(self, keyval, keycode, state): ++ return self.__proxy.ForwardKeyEvent(keyval, keycode, state) + + def update_preedit_text(self, text, cursor_pos, visible, mode=common.IBUS_ENGINE_PREEDIT_CLEAR): + text = serializable.serialize_object(text) +diff --git a/ibus/interface/iengine.py b/ibus/interface/iengine.py +index 0e0f4ee..9e0d981 100644 +--- a/ibus/interface/iengine.py ++++ b/ibus/interface/iengine.py +@@ -104,8 +104,8 @@ class IEngine(dbus.service.Object): + @signal(signature="v") + def CommitText(self, text): pass + +- @signal(signature="uu") +- def ForwardKeyEvent(self, keyval, state): pass ++ @signal(signature="uuu") ++ def ForwardKeyEvent(self, keyval, keycode, state): pass + + @signal(signature="vubu") + def UpdatePreeditText(self, text, cursor_pos, visible, mode): pass +-- +1.7.4.4 + +From d3e750eab6db7035f494fcdb328b87b2923e33a2 Mon Sep 17 00:00:00 2001 +From: Yusuke Sato +Date: Wed, 1 Jun 2011 23:37:14 +0900 +Subject: [PATCH] Send the new capabilities to ibus-daemon in + ibus_im_context_set_use_preedit. + +BUG=none +TEST=none + +Review URL: http://codereview.appspot.com/4529103 +--- + client/gtk2/ibusimcontext.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c +index ebae09d..4a894b0 100644 +--- a/client/gtk2/ibusimcontext.c ++++ b/client/gtk2/ibusimcontext.c +@@ -942,6 +942,8 @@ ibus_im_context_set_use_preedit (GtkIMContext *context, gboolean use_preedit) + else { + ibusimcontext->caps &= ~IBUS_CAP_PREEDIT_TEXT; + } ++ ibus_input_context_set_capabilities (ibusimcontext->ibuscontext, ++ ibusimcontext->caps); + } + gtk_im_context_set_use_preedit (ibusimcontext->slave, use_preedit); + } +-- +1.7.4.4 + +From 52425daa537a32bed1781958e1ef62dbf199ad8b Mon Sep 17 00:00:00 2001 +From: Peng Huang +Date: Mon, 6 Jun 2011 09:30:27 -0400 +Subject: [PATCH] Fix Python input context binding. + +Export "forward-key-event" and "delete-surrounding-text" signals to Python; clear __needs_surrounding_text property on "enabled" and "disabled" signals. + +BUG=none +TEST=briefly tested, at least I don't see any regression + +Review URL: http://codereview.appspot.com/4437062 +--- + ibus/inputcontext.py | 26 +++++++++++++++++++++++++- + ibus/interface/iinputcontext.py | 3 +++ + 2 files changed, 28 insertions(+), 1 deletions(-) + +diff --git a/ibus/inputcontext.py b/ibus/inputcontext.py +index d143727..ceeb56d 100644 +--- a/ibus/inputcontext.py ++++ b/ibus/inputcontext.py +@@ -116,6 +116,16 @@ class InputContext(object.Object): + gobject.TYPE_NONE, + () + ), ++ "forward-key-event" : ( ++ gobject.SIGNAL_RUN_LAST, ++ gobject.TYPE_NONE, ++ (gobject.TYPE_UINT, gobject.TYPE_UINT, gobject.TYPE_UINT) ++ ), ++ "delete-surrounding-text" : ( ++ gobject.SIGNAL_RUN_LAST, ++ gobject.TYPE_NONE, ++ (gobject.TYPE_INT, gobject.TYPE_UINT) ++ ), + } + + def __init__(self, bus, path, watch_signals=False): +@@ -142,8 +152,14 @@ class InputContext(object.Object): + self.__signal_matches.append(m) + m = self.__context.connect_to_signal("RequireSurroundingText", self.__require_surrounding_text_cb) + self.__signal_matches.append(m) ++ m = self.__context.connect_to_signal("Enabled", self.__enabled_cb) ++ self.__signal_matches.append(m) ++ m = self.__context.connect_to_signal("Disabled", self.__disabled_cb) ++ self.__signal_matches.append(m) + +- m = self.__context.connect_to_signal("Enabled", lambda *args: self.emit("enabled")) ++ m = self.__context.connect_to_signal("ForwardKeyEvent", lambda *args: self.emit("forward-key-event", *args)) ++ self.__signal_matches.append(m) ++ m = self.__context.connect_to_signal("DeleteSurroundingText", lambda *args: self.emit("delete-surrounding-text", *args)) + self.__signal_matches.append(m) + m = self.__context.connect_to_signal("Disabled", lambda *args: self.emit("disabled")) + self.__signal_matches.append(m) +@@ -168,6 +184,14 @@ class InputContext(object.Object): + m = self.__context.connect_to_signal("CursorDownLookupTable", lambda *args: self.emit("cursor-down-lookup-table")) + self.__signal_matches.append(m) + ++ def __enabled_cb(self, *args): ++ self.__needs_surrounding_text = False ++ self.emit("enabled") ++ ++ def __disabled_cb(self, *args): ++ self.__needs_surrounding_text = False ++ self.emit("disabled") ++ + def __commit_text_cb(self, *args): + text = serializable.deserialize_object(args[0]) + self.emit("commit-text", text) +diff --git a/ibus/interface/iinputcontext.py b/ibus/interface/iinputcontext.py +index 2db1c9b..1d3cd2a 100644 +--- a/ibus/interface/iinputcontext.py ++++ b/ibus/interface/iinputcontext.py +@@ -95,6 +95,9 @@ class IInputContext(dbus.service.Object): + @signal(signature="uuu") + def ForwardKeyEvent(self, keyval, keycode, state): pass + ++ @signal(signature="iu") ++ def DeleteSurroundingText(self, offset_from_cursor, nchars): pass ++ + @signal(signature="vub") + def UpdatePreeditText(self, text, cursor_pos, visible): pass + +-- +1.7.4.4 + +From 59ce675e335e599ed18d74ab8849b9a5fe75d4be Mon Sep 17 00:00:00 2001 +From: Peng Huang +Date: Mon, 13 Jun 2011 13:18:29 -0400 +Subject: [PATCH] Fix some race condition between idle and timeout + events. Also fix a memory leak. + +BUG=http://crosbug.com/16387 +TEST=Linux desktop + +Review URL: http://codereview.appspot.com/4568072 +--- + bus/engineproxy.c | 46 ++++++++++++++++++++++++++++++---------------- + 1 files changed, 30 insertions(+), 16 deletions(-) + +diff --git a/bus/engineproxy.c b/bus/engineproxy.c +index 0c6f45d..f74af12 100644 +--- a/bus/engineproxy.c ++++ b/bus/engineproxy.c +@@ -603,7 +603,8 @@ bus_engine_proxy_new_internal (const gchar *path, + g_assert (IBUS_IS_ENGINE_DESC (desc)); + g_assert (G_IS_DBUS_CONNECTION (connection)); + +- ++ GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | ++ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES; + BusEngineProxy *engine = + (BusEngineProxy *) g_initable_new (BUS_TYPE_ENGINE_PROXY, + NULL, +@@ -613,7 +614,7 @@ bus_engine_proxy_new_internal (const gchar *path, + "g-interface-name", IBUS_INTERFACE_ENGINE, + "g-object-path", path, + "g-default-timeout", g_gdbus_timeout, +- "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, ++ "g-flags", flags, + NULL); + const gchar *layout = ibus_engine_desc_get_layout (desc); + if (layout != NULL && layout[0] != '\0') { +@@ -638,24 +639,33 @@ static void + engine_proxy_new_data_free (EngineProxyNewData *data) + { + if (data->simple != NULL) { +- if (data->handler_id != 0) +- g_signal_handler_disconnect (data->component, data->handler_id); + g_object_unref (data->simple); + } + +- if (data->component != NULL) ++ if (data->desc != NULL) { ++ g_object_unref (data->desc); ++ } ++ ++ if (data->component != NULL) { ++ if (data->handler_id != 0) { ++ g_signal_handler_disconnect (data->component, data->handler_id); ++ } + g_object_unref (data->component); ++ } + +- if (data->factory != NULL) ++ if (data->factory != NULL) { + g_object_unref (data->factory); ++ } + +- if (data->timeout_id != 0) ++ if (data->timeout_id != 0) { + g_source_remove (data->timeout_id); ++ } + + if (data->cancellable != NULL) { +- if (data->cancelled_handler_id != 0) ++ if (data->cancelled_handler_id != 0) { + g_cancellable_disconnect (data->cancellable, +- data->cancelled_handler_id); ++ data->cancelled_handler_id); ++ } + g_object_unref (data->cancellable); + } + +@@ -772,7 +782,8 @@ timeout_cb (EngineProxyNewData *data) + /** + * cancelled_cb: + * +- * A callback function to be called when someone calls g_cancellable_cancel() for the cancellable object for bus_engine_proxy_new. ++ * A callback function to be called when someone calls g_cancellable_cancel() ++ * for the cancellable object for bus_engine_proxy_new. + * Call the GAsyncReadyCallback. + */ + static gboolean +@@ -793,8 +804,12 @@ static void + cancelled_cb (GCancellable *cancellable, + EngineProxyNewData *data) + { +- /* Cancel the bus_engine_proxy_new() in idle to avoid deadlock */ +- g_idle_add ((GSourceFunc) cancelled_idle_cb, data); ++ /* Cancel the bus_engine_proxy_new() in idle to avoid deadlock. ++ * And use HIGH priority to avoid timeout event happening before ++ * idle callback. */ ++ g_idle_add_full (G_PRIORITY_HIGH, ++ (GSourceFunc) cancelled_idle_cb, ++ data, NULL); + } + + void +@@ -831,13 +846,12 @@ bus_engine_proxy_new (IBusEngineDesc *desc, + data->simple = simple; + data->timeout = timeout; + +- g_object_set_data ((GObject *)data->simple, "EngineProxyNewData", data); +- + data->factory = bus_component_get_factory (data->component); + + if (data->factory == NULL) { +- /* The factory is not ready yet. Create the factory first, and wait for the "notify::factory" signal. +- * In the handler of "notify::factory", we'll create the engine proxy. */ ++ /* The factory is not ready yet. Create the factory first, and wait for ++ * the "notify::factory" signal. In the handler of "notify::factory", ++ * we'll create the engine proxy. */ + data->handler_id = g_signal_connect (data->component, + "notify::factory", + G_CALLBACK (notify_factory_cb), +-- +1.7.4.4 + +From fc9dedec30f724e91e7b3bb9111177e96b58ee43 Mon Sep 17 00:00:00 2001 +From: Peng Huang +Date: Wed, 15 Jun 2011 10:38:17 -0400 +Subject: [PATCH] Add IBUS_ERROR domain and reply IBUS_ERROR_NO_ENGINE + in org.freedesktop.IBus.InputContext.GetEngine + +BUG=None +TEST=Manually + +Review URL: http://codereview.appspot.com/4528140 +--- + bus/inputcontext.c | 7 ++++- + src/Makefile.am | 2 + + src/ibus.h | 1 + + src/ibuserror.c | 41 +++++++++++++++++++++++++++++++++ + src/ibuserror.h | 46 +++++++++++++++++++++++++++++++++++++ + src/ibusinputcontext.c | 15 +++++++++-- + src/ibusshare.c | 1 + + src/ibustypes.h | 9 +++++++ + src/tests/ibus-gi-inputcontext.py | 34 +++++++++++++++++++++++++++ + 9 files changed, 151 insertions(+), 5 deletions(-) + create mode 100644 src/ibuserror.c + create mode 100644 src/ibuserror.h + create mode 100755 src/tests/ibus-gi-inputcontext.py + +diff --git a/bus/inputcontext.c b/bus/inputcontext.c +index bad90ec..1567c5f 100644 +--- a/bus/inputcontext.c ++++ b/bus/inputcontext.c +@@ -1040,8 +1040,11 @@ _ic_get_engine (BusInputContext *context, + g_variant_new ("(v)", ibus_serializable_serialize ((IBusSerializable *)desc))); + } + else { +- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, +- "Input context does not have engine."); ++ g_dbus_method_invocation_return_error ( ++ invocation, ++ IBUS_ERROR, ++ IBUS_ERROR_NO_ENGINE, ++ "Input context does not have engine."); + } + } + +diff --git a/src/Makefile.am b/src/Makefile.am +index 632fc72..a53bd23 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -70,6 +70,7 @@ ibus_sources = \ + ibusservice.c \ + ibusfactory.c \ + ibusengine.c \ ++ ibuserror.c \ + ibustext.c \ + ibuskeymap.c \ + ibusattribute.c \ +@@ -114,6 +115,7 @@ ibus_headers = \ + ibusservice.h \ + ibusfactory.h \ + ibusengine.h \ ++ ibuserror.h \ + ibustext.h \ + ibuskeymap.h \ + ibusattribute.h \ +diff --git a/src/ibus.h b/src/ibus.h +index 8df7160..c408f3d 100644 +--- a/src/ibus.h ++++ b/src/ibus.h +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + #include + #include + #include +diff --git a/src/ibuserror.c b/src/ibuserror.c +new file mode 100644 +index 0000000..c50c164 +--- /dev/null ++++ b/src/ibuserror.c +@@ -0,0 +1,41 @@ ++/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ ++/* vim:set et sts=4: */ ++/* ibus - The Input Bus ++ * Copyright (C) 2011 Peng Huang ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 02111-1307, USA. ++ */ ++ ++#include "ibuserror.h" ++ ++#include ++#include "ibustypes.h" ++ ++static const GDBusErrorEntry ibus_error_entries[] = ++{ ++ { IBUS_ERROR_NO_ENGINE, "org.freedesktop.IBus.Error.NoEngine" }, ++}; ++ ++GQuark ++ibus_error_quark (void) ++{ ++ static volatile gsize quark_volatile = 0; ++ g_dbus_error_register_error_domain ("ibus-error-quark", ++ &quark_volatile, ++ ibus_error_entries, ++ G_N_ELEMENTS (ibus_error_entries)); ++ return (GQuark) quark_volatile; ++} +diff --git a/src/ibuserror.h b/src/ibuserror.h +new file mode 100644 +index 0000000..75c64b9 +--- /dev/null ++++ b/src/ibuserror.h +@@ -0,0 +1,46 @@ ++/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ ++/* vim:set et sts=4: */ ++/* ibus - The Input Bus ++ * Copyright (C) 2011 Peng Huang ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 02111-1307, USA. ++ */ ++ ++#if !defined (__IBUS_H_INSIDE__) && !defined (IBUS_COMPILATION) ++#error "Only can be included directly" ++#endif ++ ++/** ++ * SECTION: ibusshare ++ * @short_description: Shared utility functions and definition. ++ * @stability: Stable ++ * ++ * This file defines some utility functions and definition ++ * which are shared among ibus component and services. ++ */ ++ ++#ifndef __IBUS_ERROR_H_ ++#define __IBUS_ERROR_H_ ++ ++#include ++ ++G_BEGIN_DECLS ++ ++#define IBUS_ERROR ibus_error_quark() ++GQuark ibus_error_quark (void); ++ ++G_END_DECLS ++#endif +diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c +index e6f97e8..78d454e 100644 +--- a/src/ibusinputcontext.c ++++ b/src/ibusinputcontext.c +@@ -27,6 +27,7 @@ + #include "ibusattribute.h" + #include "ibuslookuptable.h" + #include "ibusproplist.h" ++#include "ibuserror.h" + + #define IBUS_INPUT_CONTEXT_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_INPUT_CONTEXT, IBusInputContextPrivate)) +@@ -1164,7 +1165,7 @@ IBusEngineDesc * + ibus_input_context_get_engine (IBusInputContext *context) + { + g_assert (IBUS_IS_INPUT_CONTEXT (context)); +- GVariant *result; ++ GVariant *result = NULL; + GError *error = NULL; + result = g_dbus_proxy_call_sync ((GDBusProxy *) context, + "GetEngine", /* method_name */ +@@ -1174,9 +1175,17 @@ ibus_input_context_get_engine (IBusInputContext *context) + NULL, /* cancellable */ + &error /* error */ + ); +- + if (result == NULL) { +- g_warning ("%s.GetEngine: %s", IBUS_INTERFACE_INPUT_CONTEXT, error->message); ++ if (g_error_matches (error, IBUS_ERROR, IBUS_ERROR_NO_ENGINE)) { ++ g_debug ("%s.GetEngine: %s", ++ IBUS_INTERFACE_INPUT_CONTEXT, ++ error->message); ++ } ++ else { ++ g_warning ("%s.GetEngine: %s", ++ IBUS_INTERFACE_INPUT_CONTEXT, ++ error->message); ++ } + g_error_free (error); + return NULL; + } +diff --git a/src/ibusshare.c b/src/ibusshare.c +index 1b8ae2a..19f9f65 100644 +--- a/src/ibusshare.c ++++ b/src/ibusshare.c +@@ -318,6 +318,7 @@ void + ibus_init (void) + { + g_type_init (); ++ IBUS_ERROR; + IBUS_TYPE_TEXT; + IBUS_TYPE_ATTRIBUTE; + IBUS_TYPE_ATTR_LIST; +diff --git a/src/ibustypes.h b/src/ibustypes.h +index 6a31847..8146719 100644 +--- a/src/ibustypes.h ++++ b/src/ibustypes.h +@@ -177,6 +177,15 @@ typedef enum { + } IBusBusRequestNameReply; + + /** ++ * IBusError: ++ * @IBUS_ERROR_NO_ENGINE: ++ * There is no engine associated with input context. ++ */ ++typedef enum { ++ IBUS_ERROR_NO_ENGINE, ++} IBusError; ++ ++/** + * IBusRectangle: + * @x: x coordinate. + * @y: y coordinate. +diff --git a/src/tests/ibus-gi-inputcontext.py b/src/tests/ibus-gi-inputcontext.py +new file mode 100755 +index 0000000..80fb97b +--- /dev/null ++++ b/src/tests/ibus-gi-inputcontext.py +@@ -0,0 +1,34 @@ ++#!/usr/bin/env python ++# vim:set et sts=4 sw=4: ++# ++# ibus - The Input Bus ++# ++# Copyright (c) 2011 Peng Huang ++# ++# This library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2 of the License, or (at your option) any later version. ++# ++# This library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the ++# Free Software Foundation, Inc., 59 Temple Place, Suite 330, ++# Boston, MA 02111-1307 USA ++ ++ ++import glib ++import gio ++from gi.repository import IBus ++IBus.init() ++main = glib.MainLoop() ++bus = IBus.Bus() ++ic = bus.create_input_context("ibus-test") ++ic.get_engine() ++ic.get_engine() ++ic.get_engine() ++ic.get_engine() +-- +1.7.4.4 + +From aec97ac090980dfcd7eeef55c1755f6cd3f87a01 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Sat, 18 Jun 2011 00:03:07 -0400 +Subject: [PATCH] Simplify surrounding-text initialization. + +Currently the immodule tries to retrieve surrounding-text unconditionally +on focus_in and enabled. These calls could be eliminated if engine were +able to proclaim that it will need surrounding-text. + +This patch extends ibus_engine_get_surrounding_text() to allow this. +Engines that need surrounding-text are expected to have: + + /* Indicate we will use surrounding-text. */ + ibus_engine_get_surrounding_text (engine, NULL, NULL); + +in their enable() method. This would work because enable() is called before +SetCapabilities DBus call. + +BUG=none +TEST=manually with ibus-m17n, with the above change. + +Review URL: http://codereview.appspot.com/4613043 +Patch from Daiki Ueno . +--- + client/gtk2/ibusimcontext.c | 23 +++++++++-------------- + src/ibusengine.c | 10 ++++++---- + src/ibusengine.h | 9 +++++++-- + 3 files changed, 22 insertions(+), 20 deletions(-) + +diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c +index ec764ef..a4e7a16 100644 +--- a/client/gtk2/ibusimcontext.c ++++ b/client/gtk2/ibusimcontext.c +@@ -147,8 +147,7 @@ static gboolean _slave_delete_surroundin + gint offset_from_cursor, + guint nchars, + IBusIMContext *context); +-static void _request_surrounding_text (IBusIMContext *context, +- gboolean force); ++static void _request_surrounding_text (IBusIMContext *context); + static void _create_fake_input_context (void); + + +@@ -263,17 +262,13 @@ _process_key_event_done (GObject *o + /* emit "retrieve-surrounding" glib signal of GtkIMContext, if + * context->caps has IBUS_CAP_SURROUNDING_TEXT and the current IBus + * engine needs surrounding-text. +- * +- * if "force" is TRUE, emit the signal regardless of whether the +- * engine needs surrounding-text. + */ + static void +-_request_surrounding_text (IBusIMContext *context, gboolean force) ++_request_surrounding_text (IBusIMContext *context) + { +- if (context->enable && ++ if (context && context->enable && + (context->caps & IBUS_CAP_SURROUNDING_TEXT) != 0 && +- (force || +- ibus_input_context_needs_surrounding_text (context->ibuscontext))) { ++ ibus_input_context_needs_surrounding_text (context->ibuscontext)) { + gboolean return_value; + IDEBUG ("requesting surrounding text"); + g_signal_emit (context, _signal_retrieve_surrounding_id, 0, +@@ -368,9 +363,8 @@ _key_snooper_cb (GtkWidget *widget, + + } while (0); + +- _request_surrounding_text (ibusimcontext, FALSE); +- + if (ibusimcontext != NULL) { ++ _request_surrounding_text (ibusimcontext); + ibusimcontext->time = event->time; + } + +@@ -680,7 +674,7 @@ ibus_im_context_filter_keypress (GtkIMCo + if (ibusimcontext->client_window == NULL && event->window != NULL) + gtk_im_context_set_client_window ((GtkIMContext *)ibusimcontext, event->window); + +- _request_surrounding_text (ibusimcontext, FALSE); ++ _request_surrounding_text (ibusimcontext); + + if (ibusimcontext != NULL) { + ibusimcontext->time = event->time; +@@ -763,7 +757,7 @@ ibus_im_context_focus_in (GtkIMContext * + + /* retrieve the initial surrounding-text (regardless of whether + * the current IBus engine needs surrounding-text) */ +- _request_surrounding_text (ibusimcontext, TRUE); ++ _request_surrounding_text (ibusimcontext); + + g_object_add_weak_pointer ((GObject *) context, + (gpointer *) &_focus_im_context); +@@ -1000,7 +996,7 @@ _ibus_context_commit_text_cb (IBusInputC + + g_signal_emit (ibusimcontext, _signal_commit_id, 0, text->text); + +- _request_surrounding_text (ibusimcontext, FALSE); ++ _request_surrounding_text (ibusimcontext); + } + + static gboolean +@@ -1296,7 +1292,7 @@ _ibus_context_show_preedit_text_cb (IBus + g_signal_emit (ibusimcontext, _signal_preedit_start_id, 0); + g_signal_emit (ibusimcontext, _signal_preedit_changed_id, 0); + +- _request_surrounding_text (ibusimcontext, FALSE); ++ _request_surrounding_text (ibusimcontext); + } + + static void +@@ -1323,7 +1319,7 @@ _ibus_context_enabled_cb (IBusInputConte + + /* retrieve the initial surrounding-text (regardless of whether + * the current IBus engine needs surrounding-text) */ +- _request_surrounding_text (ibusimcontext, TRUE); ++ _request_surrounding_text (ibusimcontext); + } + + static void +diff --git a/src/ibusengine.c b/src/ibusengine.c +index f545bef..620d07f 100644 +--- a/src/ibusengine.c ++++ b/src/ibusengine.c +@@ -1382,13 +1382,15 @@ ibus_engine_get_surrounding_text (IBusEngine *engine, + IBusEnginePrivate *priv; + + g_return_if_fail (IBUS_IS_ENGINE (engine)); +- g_return_if_fail (text != NULL); +- g_return_if_fail (cursor_pos != NULL); ++ g_return_if_fail ((text != NULL && cursor_pos != NULL) || ++ (text == NULL && cursor_pos == NULL)); + + priv = IBUS_ENGINE_GET_PRIVATE (engine); + +- *text = g_object_ref (priv->surrounding_text); +- *cursor_pos = priv->surrounding_cursor_pos; ++ if (text && cursor_pos) { ++ *text = g_object_ref (priv->surrounding_text); ++ *cursor_pos = priv->surrounding_cursor_pos; ++ } + + /* tell the client that this engine will utilize surrounding-text + * feature, which causes periodical update. Note that the client +diff --git a/src/ibusengine.h b/src/ibusengine.h +index 29b8f1d..6da342a 100644 +--- a/src/ibusengine.h ++++ b/src/ibusengine.h +@@ -407,11 +407,16 @@ void ibus_engine_delete_surrounding_text(IBusEngine *engine, + /** + * ibus_engine_get_surrounding_text: + * @engine: An IBusEngine. +- * @text: Location to store surrounding text. +- * @cursor_pos: Cursor position in characters in @text. ++ * @text: (allow-none): Location to store surrounding text. ++ * @cursor_pos: (allow-none): Cursor position in characters in @text. + * + * Get surrounding text. + * ++ * It is also used to tell the input-context that the engine will ++ * utilize surrounding-text. In that case, it must be called in ++ * #IBusEngine::enable handler, with both @text and @cursor set to ++ * %NULL. ++ * + * @see_also #IBusEngine::set-surrounding-text + */ + void ibus_engine_get_surrounding_text(IBusEngine *engine, +-- +1.7.4.4 + diff --git a/ibus-xx-bridge-hotkey.patch b/ibus-xx-bridge-hotkey.patch new file mode 100644 index 0000000..824dd81 --- /dev/null +++ b/ibus-xx-bridge-hotkey.patch @@ -0,0 +1,874 @@ +From a3a7b364410511b3a17f2b1566ba4c4c4f0de2cf Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Tue, 21 Jun 2011 17:00:54 +0900 +Subject: [PATCH] Add a bridge hotkey which use prev-next engines instead + of on-off. + +--- + bus/Makefile.am | 20 ++-- + bus/ibusimpl.c | 244 ++++++++++++++++++++++++++++---------- + bus/registry.c | 35 ++++++ + configure.ac | 31 +++++ + data/Makefile.am | 6 +- + data/ibus.schemas.in | 286 -------------------------------------------- + data/ibus.schemas.in.in | 286 ++++++++++++++++++++++++++++++++++++++++++++ + ibus/_config.py.in | 6 + + ibus/inputcontext.py | 4 + + src/Makefile.am | 1 + + src/ibusbus.c | 6 + + src/ibusbus.h | 9 ++ + src/ibusenginedesc.c | 4 + + src/ibushotkey.c | 11 ++ + src/ibushotkey.h | 11 ++ + ui/gtk/panel.py | 60 +++++++++- + xkb/Makefile.am | 2 + + xkb/ibus-engine-xkb-main.c | 8 ++ + xkb/xkbxml.c | 8 +- + 19 files changed, 677 insertions(+), 361 deletions(-) + delete mode 100644 data/ibus.schemas.in + create mode 100644 data/ibus.schemas.in.in + +diff --git a/bus/Makefile.am b/bus/Makefile.am +index 074b456..0efaa1b 100644 +--- a/bus/Makefile.am ++++ b/bus/Makefile.am +@@ -29,15 +29,17 @@ INCLUDES = \ + -I$(top_builddir)/src \ + $(NULL) + +-AM_CFLAGS = \ +- @GLIB2_CFLAGS@ \ +- @GIO2_CFLAGS@ \ +- @GTHREAD2_CFLAGS@ \ +- -DG_LOG_DOMAIN=\"IBUS\" \ +- -DPKGDATADIR=\"$(pkgdatadir)\" \ +- -DLIBEXECDIR=\"$(libexecdir)\" \ +- -DBINDIR=\"@bindir@\" \ +- $(INCLUDES) \ ++AM_CFLAGS = \ ++ @GLIB2_CFLAGS@ \ ++ @GIO2_CFLAGS@ \ ++ @GTHREAD2_CFLAGS@ \ ++ -DG_LOG_DOMAIN=\"IBUS\" \ ++ -DPKGDATADIR=\"$(pkgdatadir)\" \ ++ -DLIBEXECDIR=\"$(libexecdir)\" \ ++ -DBINDIR=\"@bindir@\" \ ++ -DUSE_BRIDGE_HOTKEY=$(USE_BRIDGE_HOTKEY) \ ++ -DDEFAULT_BRIDGE_ENGINE_NAME=\"$(DEFAULT_BRIDGE_ENGINE_NAME)\" \ ++ $(INCLUDES) \ + $(NULL) + AM_LDADD = \ + @GOBJECT2_LIBS@ \ +diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c +index 38d6d11..3b2d539 100644 +--- a/bus/ibusimpl.c ++++ b/bus/ibusimpl.c +@@ -20,6 +20,10 @@ + * Boston, MA 02111-1307, USA. + */ + ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ + #include + #include + #include +@@ -79,6 +83,8 @@ struct _BusIBusImpl { + /* engine-specific hotkeys */ + IBusHotkeyProfile *engines_hotkey_profile; + GHashTable *hotkey_to_engines_map; ++ ++ IBusEngineDesc *prev_hotkey_engine; + }; + + struct _BusIBusImplClass { +@@ -285,6 +291,30 @@ _panel_destroy_cb (BusPanelProxy *panel, + g_object_unref (panel); + } + ++static IBusEngineDesc * ++_find_engine_desc_by_name (BusIBusImpl *ibus, ++ const gchar *engine_name) ++{ ++ IBusEngineDesc *desc = NULL; ++ GList *p; ++ ++ /* find engine in registered engine list */ ++ for (p = ibus->register_engine_list; p != NULL; p = p->next) { ++ desc = (IBusEngineDesc *) p->data; ++ if (g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name) == 0) ++ return desc; ++ } ++ ++ /* find engine in preload engine list */ ++ for (p = ibus->engine_list; p != NULL; p = p->next) { ++ desc = (IBusEngineDesc *) p->data; ++ if (g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name) == 0) ++ return desc; ++ } ++ ++ return NULL; ++} ++ + static void + _config_set_value_done (GObject *object, + GAsyncResult *res, +@@ -475,8 +505,17 @@ _set_preload_engines (BusIBusImpl *ibus, + g_variant_unref (value); + } + +- g_list_foreach (engine_list, (GFunc) g_object_ref, NULL); + ibus->engine_list = engine_list; ++#if USE_BRIDGE_HOTKEY ++ if (_find_engine_desc_by_name (ibus, DEFAULT_BRIDGE_ENGINE_NAME) == NULL) { ++ IBusEngineDesc *engine = bus_registry_find_engine_by_name (ibus->registry, ++ DEFAULT_BRIDGE_ENGINE_NAME); ++ g_assert (engine != NULL); ++ engine_list = g_list_append (engine_list, engine); ++ ibus->engine_list = engine_list; ++ } ++#endif ++ g_list_foreach (engine_list, (GFunc) g_object_ref, NULL); + + if (ibus->engine_list) { + BusComponent *component = bus_component_from_engine_desc ((IBusEngineDesc *) ibus->engine_list->data); +@@ -1182,28 +1221,110 @@ _ibus_get_address (BusIBusImpl + g_variant_new ("(s)", bus_server_get_address ())); + } + +-static IBusEngineDesc * +-_find_engine_desc_by_name (BusIBusImpl *ibus, +- const gchar *engine_name) +-{ +- IBusEngineDesc *desc = NULL; +- GList *p; ++/** ++ * _foreach_remove_engine_hotkey: ++ * ++ * Remove the engine-specific hot key of the engine, and update ibus->engines_hotkey_profile. ++ */ ++gboolean ++_foreach_remove_engine_hotkey (gpointer key, ++ gpointer value, ++ gpointer data) ++{ ++ GQuark event = GPOINTER_TO_UINT (value); ++ struct _impl_and_desc { ++ BusIBusImpl *ibus; ++ IBusEngineDesc *desc; ++ } *id = (struct _impl_and_desc *) data; ++ BusIBusImpl *ibus = id->ibus; ++ IBusEngineDesc *desc = id->desc; ++ GList *engine_list; + +- /* find engine in registered engine list */ +- for (p = ibus->register_engine_list; p != NULL; p = p->next) { +- desc = (IBusEngineDesc *) p->data; +- if (g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name) == 0) +- return desc; ++ g_assert (ibus != NULL); ++ g_assert (desc != NULL); ++ ++ if (event == 0) { ++ return FALSE; + } + +- /* find engine in preload engine list */ +- for (p = ibus->engine_list; p != NULL; p = p->next) { +- desc = (IBusEngineDesc *) p->data; +- if (g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name) == 0) +- return desc; ++ engine_list = g_hash_table_lookup (ibus->hotkey_to_engines_map, ++ GUINT_TO_POINTER (event)); ++ ++ /* As we will rebuild the engines hotkey map whenever an engine was ++ * added or removed, we don't need to hold a reference of the engine ++ * here. */ ++ if (engine_list && g_list_find (engine_list, desc) != NULL) { ++ engine_list = g_list_remove (engine_list, desc); + } + +- return NULL; ++ /* We need to steal the value before adding it back, otherwise it will ++ * be destroyed. */ ++ g_hash_table_steal (ibus->hotkey_to_engines_map, GUINT_TO_POINTER (event)); ++ ++ if (engine_list != NULL) { ++ g_hash_table_insert (ibus->hotkey_to_engines_map, ++ GUINT_TO_POINTER (event), engine_list); ++ } ++ ++ return FALSE; ++} ++ ++/** ++ * _add_engine_hotkey_with_hotkeys: ++ * ++ * Check the engine-specific hot key of the engine, and update ibus->engines_hotkey_profile. ++ */ ++static void ++_add_engine_hotkey_with_hotkeys (IBusEngineDesc *engine, ++ BusIBusImpl *ibus, ++ const gchar *hotkeys) ++{ ++ gchar **hotkey_list; ++ gchar **p; ++ gchar *hotkey; ++ GList *engine_list; ++ ++ GQuark event; ++ guint keyval; ++ guint modifiers; ++ ++ g_assert (engine != NULL); ++ g_assert (hotkeys && *hotkeys); ++ ++ hotkey_list = g_strsplit_set (hotkeys, ";,", 0); ++ ++ for (p = hotkey_list; p && *p; ++p) { ++ hotkey = g_strstrip (*p); ++ if (!*hotkey || !ibus_key_event_from_string (hotkey, &keyval, &modifiers)) { ++ continue; ++ } ++ ++ /* If the hotkey already exists, we won't need to add it again. */ ++ event = ibus_hotkey_profile_lookup_hotkey (ibus->engines_hotkey_profile, ++ keyval, modifiers); ++ if (event == 0) { ++ event = g_quark_from_string (hotkey); ++ ibus_hotkey_profile_add_hotkey (ibus->engines_hotkey_profile, ++ keyval, modifiers, event); ++ } ++ ++ engine_list = g_hash_table_lookup (ibus->hotkey_to_engines_map, ++ GUINT_TO_POINTER (event)); ++ ++ /* As we will rebuild the engines hotkey map whenever an engine was ++ * added or removed, we don't need to hold a reference of the engine ++ * here. */ ++ engine_list = g_list_append (engine_list, engine); ++ ++ /* We need to steal the value before adding it back, otherwise it will ++ * be destroyed. */ ++ g_hash_table_steal (ibus->hotkey_to_engines_map, GUINT_TO_POINTER (event)); ++ ++ g_hash_table_insert (ibus->hotkey_to_engines_map, ++ GUINT_TO_POINTER (event), engine_list); ++ } ++ ++ g_strfreev (hotkey_list); + } + + /** +@@ -1216,7 +1337,39 @@ _context_request_engine_cb (BusInputCont + const gchar *engine_name, + BusIBusImpl *ibus) + { +- return bus_ibus_impl_get_engine_desc (ibus, engine_name); ++ IBusEngineDesc *desc = bus_ibus_impl_get_engine_desc (ibus, engine_name); ++ struct _impl_and_desc { ++ BusIBusImpl *ibus; ++ IBusEngineDesc *desc; ++ } id = {ibus, desc}; ++ ++#if USE_BRIDGE_HOTKEY ++ IBusEngineDesc *current_desc = NULL; ++ if (context) { ++ BusEngineProxy *engine = bus_input_context_get_engine (context); ++ if (engine != NULL) { ++ current_desc = bus_engine_proxy_get_desc (engine); ++ } ++ } ++ if (current_desc) { ++ ibus->prev_hotkey_engine = current_desc; ++ } ++ if (current_desc != NULL && desc != NULL && ++ g_strcmp0 (ibus_engine_desc_get_name (current_desc), ++ ibus_engine_desc_get_name (desc)) != 0 && ++ g_strcmp0 (ibus_engine_desc_get_name (desc), ++ DEFAULT_BRIDGE_ENGINE_NAME) == 0) { ++ const gchar *hotkeys = ibus_engine_desc_get_hotkeys (current_desc); ++ if (!hotkeys || !*hotkeys) { ++ hotkeys = "Control+space"; ++ } ++ ibus_hotkey_profile_foreach_hotkey (ibus->engines_hotkey_profile, ++ _foreach_remove_engine_hotkey, ++ &id); ++ _add_engine_hotkey_with_hotkeys (desc, ibus, hotkeys); ++ } ++#endif ++ return desc; + } + + /** +@@ -2357,6 +2510,11 @@ bus_ibus_impl_filter_keyboard_shortcuts + * the same hotkey, then we should switch to the next engine with the + * same hotkey in the list. Otherwise, we just switch to the first + * engine in the list. */ ++#if USE_BRIDGE_HOTKEY ++ if (ibus->prev_hotkey_engine) { ++ new_engine_desc = ibus->prev_hotkey_engine; ++ } ++#else + GList *p = engine_list; + for (; p->next != NULL; p = p->next) { + if (current_engine_desc == (IBusEngineDesc *) p->data) { +@@ -2364,9 +2522,14 @@ bus_ibus_impl_filter_keyboard_shortcuts + break; + } + } ++#endif + + if (current_engine_desc != new_engine_desc) { ++ ibus->prev_hotkey_engine = current_engine_desc; + bus_ibus_impl_set_context_engine_from_desc (ibus, context, new_engine_desc); ++ } else { ++ g_warning ("The engine %s is registered twice in hotkeys", ++ ibus_engine_desc_get_name (current_engine_desc)); + } + + return TRUE; +@@ -2470,14 +2633,6 @@ static void + _add_engine_hotkey (IBusEngineDesc *engine, BusIBusImpl *ibus) + { + const gchar *hotkeys; +- gchar **hotkey_list; +- gchar **p; +- gchar *hotkey; +- GList *engine_list; +- +- GQuark event; +- guint keyval; +- guint modifiers; + + if (!engine) { + return; +@@ -2489,40 +2644,7 @@ _add_engine_hotkey (IBusEngineDesc *engi + return; + } + +- hotkey_list = g_strsplit_set (hotkeys, ";,", 0); +- +- for (p = hotkey_list; p && *p; ++p) { +- hotkey = g_strstrip (*p); +- if (!*hotkey || !ibus_key_event_from_string (hotkey, &keyval, &modifiers)) { +- continue; +- } +- +- /* If the hotkey already exists, we won't need to add it again. */ +- event = ibus_hotkey_profile_lookup_hotkey (ibus->engines_hotkey_profile, +- keyval, modifiers); +- if (event == 0) { +- event = g_quark_from_string (hotkey); +- ibus_hotkey_profile_add_hotkey (ibus->engines_hotkey_profile, +- keyval, modifiers, event); +- } +- +- engine_list = g_hash_table_lookup (ibus->hotkey_to_engines_map, +- GUINT_TO_POINTER (event)); +- +- /* As we will rebuild the engines hotkey map whenever an engine was +- * added or removed, we don't need to hold a reference of the engine +- * here. */ +- engine_list = g_list_append (engine_list, engine); +- +- /* We need to steal the value before adding it back, otherwise it will +- * be destroyed. */ +- g_hash_table_steal (ibus->hotkey_to_engines_map, GUINT_TO_POINTER (event)); +- +- g_hash_table_insert (ibus->hotkey_to_engines_map, +- GUINT_TO_POINTER (event), engine_list); +- } +- +- g_strfreev (hotkey_list); ++ _add_engine_hotkey_with_hotkeys (engine, ibus, hotkeys); + } + + /** +diff --git a/bus/registry.c b/bus/registry.c +index bc6680d..f47f727 100644 +--- a/bus/registry.c ++++ b/bus/registry.c +@@ -19,6 +19,11 @@ + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ + #include "registry.h" + #include + #include +@@ -101,6 +106,9 @@ bus_registry_init (BusRegistry *registry) + registry->observed_paths = NULL; + registry->components = NULL; + registry->engine_table = g_hash_table_new (g_str_hash, g_str_equal); ++#if USE_BRIDGE_HOTKEY ++ gboolean has_default_engine = FALSE; ++#endif + + #ifdef G_THREADS_ENABLED + /* If glib supports thread, we'll create a thread to monitor changes in IME +@@ -145,12 +153,39 @@ bus_registry_init (BusRegistry *registry) + GList *p1; + for (p1 = engines; p1 != NULL; p1 = p1->next) { + IBusEngineDesc *desc = (IBusEngineDesc *) p1->data; ++#if USE_BRIDGE_HOTKEY ++ if (g_strcmp0 (ibus_engine_desc_get_name (desc), ++ DEFAULT_BRIDGE_ENGINE_NAME) == 0) { ++ has_default_engine = TRUE; ++ } ++#endif + g_hash_table_insert (registry->engine_table, + (gpointer) ibus_engine_desc_get_name (desc), + desc); + } + g_list_free (engines); + } ++ ++#if USE_BRIDGE_HOTKEY ++ if (has_default_engine == FALSE) { ++ bus_registry_remove_all (registry); ++ bus_registry_load (registry); ++ bus_registry_save_cache (registry); ++ ++ for (p = registry->components; p != NULL; p = p->next) { ++ BusComponent *comp = (BusComponent *) p->data; ++ GList *engines = bus_component_get_engines (comp); ++ GList *p1; ++ for (p1 = engines; p1 != NULL; p1 = p1->next) { ++ IBusEngineDesc *desc = (IBusEngineDesc *) p1->data; ++ g_hash_table_insert (registry->engine_table, ++ (gpointer) ibus_engine_desc_get_name (desc), ++ desc); ++ } ++ g_list_free (engines); ++ } ++ } ++#endif + } + + static void +diff --git a/configure.ac b/configure.ac +index 85e5e30..a6974d4 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -438,6 +438,34 @@ else + enable_surrounding_text="no (disabled, use --enable-surrounding-text to enable)" + fi + ++# option for bridge hotkey ++AC_ARG_ENABLE(bridge-hotkey, ++ AS_HELP_STRING([--enable-bridge-hotkey], ++ [Enable bridge hotkey instead of ON/OFF hotkey]), ++ [enable_bridge_hotkey=$enableval], ++ [enable_bridge_hotkey=no] ++) ++ ++if test x"$enable_bridge_hotkey" = x"yes"; then ++ USE_BRIDGE_HOTKEY=1 ++ TRIGGER_HOTKEYS="" ++else ++ USE_BRIDGE_HOTKEY=0 ++ TRIGGER_HOTKEYS="Control+space,Zenkaku_Hankaku,Alt+Kanji,Alt+grave,Hangul,Alt+Release+Alt_R" ++ enable_bridge_hotkey="no (disabled, use --enable-bridge-hotkey to enable)" ++fi ++AC_SUBST(USE_BRIDGE_HOTKEY) ++AC_SUBST(TRIGGER_HOTKEYS) ++ ++# define default bridge engine name ++AC_ARG_WITH(bridge-engine, ++ AS_HELP_STRING([--with-bridge-engine[=bridge_engine_name]], ++ [Set bridge engine name in IM bridge hotkey. (default: xkb:layout:default)]), ++ [DEFAULT_BRIDGE_ENGINE_NAME=$with_bridge_engine], ++ [DEFAULT_BRIDGE_ENGINE_NAME="xkb:layout:default"] ++) ++AC_SUBST(DEFAULT_BRIDGE_ENGINE_NAME) ++ + # check iso-codes + PKG_CHECK_MODULES(ISOCODES, [ + iso-codes +@@ -464,6 +492,7 @@ bus/Makefile + util/Makefile + util/IMdkit/Makefile + data/Makefile ++data/ibus.schemas.in + data/icons/Makefile + data/keymaps/Makefile + docs/Makefile +@@ -512,5 +541,7 @@ Build options: + No snooper regexes "$NO_SNOOPER_APPS" + Panel icon "$IBUS_ICON_KEYBOARD" + Enable surrounding-text $enable_surrounding_text ++ Enable bridge hotkey $enable_bridge_hotkey ++ Default bridge engine $DEFAULT_BRIDGE_ENGINE_NAME + ]) + +diff --git a/data/Makefile.am b/data/Makefile.am +index ba9f4bb..a909e5b 100644 +--- a/data/Makefile.am ++++ b/data/Makefile.am +@@ -26,7 +26,8 @@ SUBDIRS = \ + $(NULL) + + schemasdir = $(GCONF_SCHEMA_FILE_DIR) +-schemas_in_files = ibus.schemas.in ++schemas_in_in_files = ibus.schemas.in.in ++schemas_in_files = $(schemas_in_in_files:.schemas.in.in=.schemas.in) + schemas_DATA = $(schemas_in_files:.schemas.in=.schemas) + @INTLTOOL_SCHEMAS_RULE@ + +@@ -41,11 +42,12 @@ if GCONF_SCHEMAS_INSTALL + endif + + EXTRA_DIST = \ +- $(schemas_in_files) \ ++ $(schemas_in_in_files) \ + $(NULL) + + DISTCLEANFILES = \ + $(schemas_DATA) \ ++ $(schemas_in_files) \ + $(NULL) + + -include $(top_srcdir)/git.mk +diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in.in +index 7ca4899..42d9297 +--- a/data/ibus.schemas.in ++++ b/data/ibus.schemas.in.in +@@ -31,7 +31,7 @@ + ibus + list + string +- [Control+space,Zenkaku_Hankaku,Alt+Kanji,Alt+grave,Hangul,Alt+Release+Alt_R] ++ [@TRIGGER_HOTKEYS@] + + Trigger shortcut keys + The shortcut keys for turning input method on or off +diff --git a/ibus/_config.py.in b/ibus/_config.py.in +index a830136..4c3c980 100644 +--- a/ibus/_config.py.in ++++ b/ibus/_config.py.in +@@ -25,6 +25,8 @@ __all__ = ( + "get_copyright", + "get_license", + "get_ICON_KEYBOARD", ++ "use_bridge_hotkey", ++ "DEFAULT_BRIDGE_ENGINE_NAME", + "ISOCODES_PREFIX", + "_" + ) +@@ -51,4 +53,8 @@ def get_ICON_KEYBOARD(): + icon = 'ibus-keyboard' + return icon + ++def use_bridge_hotkey(): ++ return True if @USE_BRIDGE_HOTKEY@ == 1 else False ++ ++DEFAULT_BRIDGE_ENGINE_NAME='@DEFAULT_BRIDGE_ENGINE_NAME@' + ISOCODES_PREFIX='@ISOCODES_PREFIX@' +diff --git a/ibus/inputcontext.py b/ibus/inputcontext.py +index ceeb56d..2694fa3 100644 +--- a/ibus/inputcontext.py ++++ b/ibus/inputcontext.py +@@ -28,6 +28,7 @@ import sys + import gobject + import dbus + import dbus.lowlevel ++import _config + import object + import common + import serializable +@@ -282,6 +283,9 @@ class InputContext(object.Object): + def set_engine(self, engine): + return self.__context.SetEngine(engine.name) + ++ def set_bridge_engine(self): ++ return self.__context.SetEngine(_config.DEFAULT_BRIDGE_ENGINE_NAME) ++ + def introspect(self): + return self.__context.Introspect() + +diff --git a/src/Makefile.am b/src/Makefile.am +index 6454522..443b0db 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -46,6 +46,7 @@ AM_CPPFLAGS = \ + -DIBUS_DATA_DIR=\"$(pkgdatadir)\" \ + -DIBUS_COMPILATION \ + -DISOCODES_PREFIX=\"$(ISOCODES_PREFIX)\" \ ++ -DUSE_BRIDGE_HOTKEY=$(USE_BRIDGE_HOTKEY) \ + $(NULL) + + # ibus library +diff --git a/src/ibusbus.c b/src/ibusbus.c +index 39ad784..5a8f9a9 100644 +--- a/src/ibusbus.c ++++ b/src/ibusbus.c +@@ -1902,3 +1902,9 @@ ibus_bus_call_async (IBusBus *bus, + (GAsyncReadyCallback) ibus_bus_call_async_done, + simple); + } ++ ++gboolean ++ibus_bus_use_bridge_hotkey (IBusBus *bus) ++{ ++ return (USE_BRIDGE_HOTKEY == 1) ? TRUE : FALSE; ++} +diff --git a/src/ibusbus.h b/src/ibusbus.h +index 77d3916..4bdf760 100644 +--- a/src/ibusbus.h ++++ b/src/ibusbus.h +@@ -971,5 +971,14 @@ void ibus_bus_set_watch_ibus_signal + */ + IBusConfig *ibus_bus_get_config (IBusBus *bus); + ++/** ++ * ibus_bus_use_bridge_hotkey: ++ * @bus: An #IBusBus. ++ * @returns: %TRUE if @bus use bridge hotkey, %FALSE otherwise. ++ * ++ * Return %TRUE if @bus use bridge hotkey. ++ */ ++gboolean ibus_bus_use_bridge_hotkey (IBusBus *bus); ++ + G_END_DECLS + #endif +diff --git a/src/ibusenginedesc.c b/src/ibusenginedesc.c +index d3800e1..a9e68be 100644 +--- a/src/ibusenginedesc.c ++++ b/src/ibusenginedesc.c +@@ -233,7 +233,11 @@ ibus_engine_desc_class_init (IBusEngineDescClass *class) + g_param_spec_string ("hotkeys", + "description hotkeys", + "The hotkeys of engine description", ++#if USE_BRIDGE_HOTKEY ++ "Control+space", ++#else + "", ++#endif + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + /** +diff --git a/src/ibushotkey.c b/src/ibushotkey.c +index 32f8338..bef7dfc 100644 +--- a/src/ibushotkey.c ++++ b/src/ibushotkey.c +@@ -562,3 +562,14 @@ ibus_hotkey_profile_lookup_hotkey (IBusHotkeyProfile *profile, + + return (GQuark) GPOINTER_TO_UINT (g_tree_lookup (priv->hotkeys, &hotkey)); + } ++ ++void ++ibus_hotkey_profile_foreach_hotkey (IBusHotkeyProfile *profile, ++ GTraverseFunc func, ++ gpointer user_data) ++{ ++ IBusHotkeyProfilePrivate *priv; ++ priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile); ++ ++ g_tree_foreach (priv->hotkeys, func, user_data); ++} +diff --git a/src/ibushotkey.h b/src/ibushotkey.h +index 9a341f6..92ec6af 100644 +--- a/src/ibushotkey.h ++++ b/src/ibushotkey.h +@@ -179,5 +179,16 @@ GQuark ibus_hotkey_profile_lookup_hotkey + guint keyval, + guint modifiers); + ++/** ++ * ibus_hotkey_profile_foreach_hotkey: ++ * @profile: An IBusHotkeyProfile. ++ * @func: (scope call): A GTraverseFunc for g_tree_traverse. ++ * @user_data: A gpointer for g_tree_traverse. ++ */ ++void ibus_hotkey_profile_foreach_hotkey ++ (IBusHotkeyProfile *profile, ++ GTraverseFunc func, ++ gpointer user_data); ++ + G_END_DECLS + #endif +diff --git a/ui/gtk/panel.py b/ui/gtk/panel.py +index de64920..7f2edcd 100644 +--- a/ui/gtk/panel.py ++++ b/ui/gtk/panel.py +@@ -133,6 +133,11 @@ class Panel(ibus.PanelBase): + # self.__bus.request_name(ibus.panel.IBUS_SERVICE_PANEL, 0) + + # init xkb ++ self.__default_layout = 'default' ++ self.__default_model = 'default' ++ self.__default_option = 'default' ++ self.__disabled_engine = None ++ + self.__xkblayout = ibus.XKBLayout(self.__config) + use_xkb = self.__config.get_value("general", "use_system_keyboard_layout", False) + if not use_xkb: +@@ -142,11 +147,18 @@ class Panel(ibus.PanelBase): + value = 'default' + if value != 'default': + self.__xkblayout.set_default_layout(value) ++ if value.find('(') >= 0: ++ self.__default_layout = value.split('(')[0] ++ self.__default_model = value.split('(')[1].split(')')[0] ++ else: ++ self.__default_layout = value ++ self.__default_model = None + value = str(self.__config.get_value("general", "system_keyboard_option", '')) + if value == '': + value = 'default' + if value != 'default': + self.__xkblayout.set_default_option(value) ++ self.__default_option = value + + def set_cursor_location(self, x, y, w, h): + self.__candidate_panel.set_cursor_location(x, y, w, h) +@@ -233,6 +245,41 @@ class Panel(ibus.PanelBase): + def __set_im_name(self, name): + self.__language_bar.set_im_name(name) + ++ def __set_default_layout_engine(self): ++ default_layout = self.__default_layout ++ default_model = self.__default_model ++ if default_layout == 'default': ++ default_layout = self.__xkblayout.get_default_layout()[0] ++ default_model = None ++ if default_model == 'default': ++ default_model = self.__xkblayout.get_default_layout()[1] ++ layouts = default_layout.split(',') ++ group = self.__xkblayout.get_group() ++ layout = layouts[group] ++ model = None ++ if default_model != None and default_model != '': ++ models = default_model.split(',') ++ if group < models.length: ++ model = models[group] ++ registry = ibus.XKBConfigRegistry() ++ langs = registry.get_layout_lang()[layout] ++ lang = 'en' ++ im_icon = layout[:2] ++ if langs != None: ++ im_icon = langs[0][:2] ++ lang = str(langs[0]) ++ if self.__disabled_engine == None: ++ self.__disabled_engine = registry.engine_desc_new(lang, ++ self.__default_layout, ++ 'Default Layout', ++ default_model, ++ None) ++ if self.__focus_ic != None: ++ prev_engine = self.__focus_ic.get_engine() ++ if prev_engine == None or \ ++ prev_engine.name != self.__disabled_engine.name: ++ self.__focus_ic.set_bridge_engine() ++ + def focus_in(self, ic): + self.reset() + self.__focus_ic = ibus.InputContext(self.__bus, ic) +@@ -240,6 +287,9 @@ class Panel(ibus.PanelBase): + self.__language_bar.set_enabled(enabled) + + if not enabled: ++ if ibus.use_bridge_hotkey(): ++ self.__set_default_layout_engine() ++ + self.__set_im_icon(ICON_KEYBOARD) + self.__set_im_name(None) + if self.__bus.get_use_sys_layout(): +@@ -453,7 +503,12 @@ class Panel(ibus.PanelBase): + size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU) + menu = gtk.Menu() + for i, engine in enumerate(engines): +- lang = ibus.get_language_name(engine.language) ++ language = engine.language ++ if ibus.use_bridge_hotkey() and \ ++ engine.name == ibus.DEFAULT_BRIDGE_ENGINE_NAME and \ ++ self.__disabled_engine != None: ++ language = self.__disabled_engine.language ++ lang = ibus.get_language_name(language) + item = gtk.ImageMenuItem("%s - %s" % (lang, engine.longname)) + if current_engine and current_engine.name == engine.name: + for widget in item.get_children(): +@@ -471,7 +526,8 @@ class Panel(ibus.PanelBase): + item.connect("activate", self.__im_menu_item_activate_cb, None) + if self.__focus_ic == None or not self.__focus_ic.is_enabled(): + item.set_sensitive(False) +- menu.add(item) ++ if not ibus.use_bridge_hotkey(): ++ menu.add(item) + + menu.show_all() + menu.set_take_focus(False) +diff --git a/xkb/Makefile.am b/xkb/Makefile.am +index ad9cdd9..c4d5afb 100644 +--- a/xkb/Makefile.am ++++ b/xkb/Makefile.am +@@ -28,6 +28,8 @@ INCLUDES = \ + -I$(top_srcdir)/src \ + -DIBUS_LOCALEDIR=\"$(datadir)/locale\" \ + -DLIBEXECDIR=\""$(libexecdir)"\" \ ++ -DUSE_BRIDGE_HOTKEY=$(USE_BRIDGE_HOTKEY) \ ++ -DDEFAULT_BRIDGE_ENGINE_NAME=\"$(DEFAULT_BRIDGE_ENGINE_NAME)\" \ + $(NULL) + + noinst_PROGRAMS = $(TESTS) +diff --git a/xkb/ibus-engine-xkb-main.c b/xkb/ibus-engine-xkb-main.c +index 5d748cc..a80f349 100644 +--- a/xkb/ibus-engine-xkb-main.c ++++ b/xkb/ibus-engine-xkb-main.c +@@ -288,6 +288,14 @@ print_component () + layout_desc = (GHashTable *) ibus_xkb_config_registry_get_layout_desc (config_registry); + variant_desc = (GHashTable *) ibus_xkb_config_registry_get_variant_desc (config_registry); + component = ibus_xkb_component_new (); ++#if USE_BRIDGE_HOTKEY ++ engine = ibus_xkb_engine_desc_new ("en", ++ "default", ++ "Default Layout", ++ NULL, ++ NULL); ++ ibus_component_add_engine (component, engine); ++#endif + for (keys = g_hash_table_get_keys (layout_list); keys; keys = keys->next) { + if (keys->data == NULL) { + continue; +diff --git a/xkb/xkbxml.c b/xkb/xkbxml.c +index 2ce7bcf..de6648f 100644 +--- a/xkb/xkbxml.c ++++ b/xkb/xkbxml.c +@@ -273,6 +273,7 @@ ibus_xkb_engine_desc_new (const gchar *lang, + gchar *longname = NULL; + gchar *desc = NULL; + gchar *engine_layout = NULL; ++ const gchar *icon = "ibus-engine"; + + g_return_val_if_fail (lang != NULL && layout != NULL, NULL); + +@@ -294,6 +295,11 @@ ibus_xkb_engine_desc_new (const gchar *lang, + desc = g_strdup_printf ("XKB %s keyboard layout", layout); + engine_layout = g_strdup (layout); + } ++#if USE_BRIDGE_HOTKEY ++ if (g_strcmp0 (name, DEFAULT_BRIDGE_ENGINE_NAME) == 0) { ++ icon = "input-keyboard-symbolic"; ++ } ++#endif + + engine = ibus_engine_desc_new (name, + longname, +@@ -301,7 +307,7 @@ ibus_xkb_engine_desc_new (const gchar *lang, + lang, + "LGPL2.1", + "Takao Fujiwara ", +- "ibus-engine", ++ icon, + engine_layout); + + g_free (name); +-- +1.7.4.4 + diff --git a/ibus-xx-icon-symbol.patch b/ibus-xx-icon-symbol.patch new file mode 100644 index 0000000..eb0802d --- /dev/null +++ b/ibus-xx-icon-symbol.patch @@ -0,0 +1,331 @@ +From ec02d646dccd213e1309011160d9d73a26174044 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Mon, 20 Jun 2011 19:10:21 +0900 +Subject: [PATCH] Add icon_symbol property in IBusEngineDesc. + +--- + bus/engineproxy.c | 22 +++++++++++++++ + bus/ibusimpl.c | 33 ++++++++++++++++++++++ + bus/ibusimpl.h | 4 +++ + ibus/engine.py | 3 ++ + ibus/interface/iengine.py | 3 ++ + src/ibusenginedesc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ + src/ibusenginedesc.h | 10 +++++++ + 7 files changed, 141 insertions(+), 0 deletions(-) + +diff --git a/bus/engineproxy.c b/bus/engineproxy.c +index f74af12..5c0cbb2 100644 +--- a/bus/engineproxy.c ++++ b/bus/engineproxy.c +@@ -591,6 +591,28 @@ bus_engine_proxy_g_signal (GDBusProxy *proxy, + return; + } + ++ if (g_strcmp0 (signal_name, "SetIconSymbol") == 0) { ++ const gchar *name = NULL; ++ gchar *icon_symbol = NULL; ++ GValue value = { 0, }; ++ ++ name = ibus_engine_desc_get_name (engine->desc); ++ g_return_if_fail (name != NULL); ++ g_variant_get (parameters, "(s)", &icon_symbol); ++ g_return_if_fail (icon_symbol != NULL); ++ ++ g_value_init (&value, G_TYPE_STRING); ++ g_value_set_string (&value, icon_symbol); ++ g_object_set_property (G_OBJECT (engine->desc), "icon_symbol", &value); ++ g_value_unset (&value); ++ ++ bus_ibus_impl_set_icon_symbol_with_engine_name (BUS_DEFAULT_IBUS, ++ name, ++ icon_symbol); ++ g_free (icon_symbol); ++ return; ++ } ++ + g_return_if_reached (); + } + +diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c +index b356b2c..38d6d11 100644 +--- a/bus/ibusimpl.c ++++ b/bus/ibusimpl.c +@@ -2342,3 +2342,36 @@ bus_ibus_impl_get_focused_input_context (BusIBusImpl *ibus) + + return ibus->focused_context; + } ++ ++void ++bus_ibus_impl_set_icon_symbol_with_engine_name (BusIBusImpl *ibus, ++ const gchar *name, ++ const gchar *icon_symbol) ++{ ++ IBusEngineDesc *desc = NULL; ++ GValue value = { 0, }; ++ ++ g_assert (BUS_IS_IBUS_IMPL (ibus)); ++ g_assert (name != NULL); ++ g_assert (icon_symbol != NULL); ++ ++ desc = bus_ibus_impl_get_engine_desc (ibus, name); ++ ++ if (desc == NULL) { ++ return; ++ } ++ ++ g_value_init (&value, G_TYPE_STRING); ++ g_value_set_string (&value, icon_symbol); ++ g_object_set_property (G_OBJECT (desc), "icon_symbol", &value); ++ g_value_unset (&value); ++ ++ /* Update status icon. ++ * "enabled" signal is caught by ibus->panel and ibus->panel calls ++ * StateChanged dbus method. */ ++ if (ibus->panel && ibus->focused_context) { ++ if (bus_input_context_is_enabled (ibus->focused_context)) { ++ bus_input_context_enable (ibus->focused_context); ++ } ++ } ++} +diff --git a/bus/ibusimpl.h b/bus/ibusimpl.h +index 42edbf8..4f37cbc 100644 +--- a/bus/ibusimpl.h ++++ b/bus/ibusimpl.h +@@ -99,6 +99,10 @@ gboolean bus_ibus_impl_is_embed_preedit_text + (BusIBusImpl *ibus); + BusInputContext *bus_ibus_impl_get_focused_input_context + (BusIBusImpl *ibus); ++void bus_ibus_impl_set_icon_symbol_with_engine_name ++ (BusIBusImpl *ibus, ++ const gchar *name, ++ const gchar *icon_symbol); + + G_END_DECLS + #endif +diff --git a/ibus/engine.py b/ibus/engine.py +index fe5dd98..e827408 100644 +--- a/ibus/engine.py ++++ b/ibus/engine.py +@@ -176,6 +176,9 @@ class EngineBase(object.Object): + self.__proxy = None + super(EngineBase,self).do_destroy() + ++ def set_icon_symbol(self, icon_symbol): ++ return self.__proxy.SetIconSymbol(icon_symbol) ++ + + class EngineProxy(interface.IEngine): + def __init__(self, engine, conn, object_path): +diff --git a/ibus/interface/iengine.py b/ibus/interface/iengine.py +index 9e0d981..7cefcdf 100644 +--- a/ibus/interface/iengine.py ++++ b/ibus/interface/iengine.py +@@ -157,3 +157,6 @@ class IEngine(dbus.service.Object): + + @signal() + def RequireSurroundingText(self): pass ++ ++ @signal(signature="s") ++ def SetIconSymbol(self, icon_symbol): pass +diff --git a/src/ibusenginedesc.c b/src/ibusenginedesc.c +index ca5ef60..d3800e1 100644 +--- a/src/ibusenginedesc.c ++++ b/src/ibusenginedesc.c +@@ -22,6 +22,7 @@ + #include + #include "ibusenginedesc.h" + #include "ibusxml.h" ++#include "ibusenumtypes.h" + + enum { + LAST_SIGNAL, +@@ -39,6 +40,7 @@ enum { + PROP_LAYOUT, + PROP_RANK, + PROP_HOTKEYS, ++ PROP_ICON_SYMBOL, + }; + + +@@ -54,6 +56,7 @@ struct _IBusEngineDescPrivate { + gchar *layout; + guint rank; + gchar *hotkeys; ++ gchar *icon_symbol; + }; + + #define IBUS_ENGINE_DESC_GET_PRIVATE(o) \ +@@ -232,6 +235,19 @@ ibus_engine_desc_class_init (IBusEngineDescClass *class) + "The hotkeys of engine description", + "", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); ++ ++ /** ++ * IBusEngineDesc:icon_symbol: ++ * ++ * The symbol chars of engine description instead of icon image ++ */ ++ g_object_class_install_property (gobject_class, ++ PROP_ICON_SYMBOL, ++ g_param_spec_string ("icon_symbol", ++ "description icon_symbol", ++ "The icon symbol chars of engine description", ++ "", ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + } + + static void +@@ -249,6 +265,7 @@ ibus_engine_desc_init (IBusEngineDesc *desc) + desc->priv->layout = NULL; + desc->priv->rank = 0; + desc->priv->hotkeys = NULL; ++ desc->priv->icon_symbol = NULL; + } + + static void +@@ -263,6 +280,7 @@ ibus_engine_desc_destroy (IBusEngineDesc *desc) + g_free (desc->priv->icon); + g_free (desc->priv->layout); + g_free (desc->priv->hotkeys); ++ g_free (desc->priv->icon_symbol); + + IBUS_OBJECT_CLASS (ibus_engine_desc_parent_class)->destroy (IBUS_OBJECT (desc)); + } +@@ -313,6 +331,10 @@ ibus_engine_desc_set_property (IBusEngineDesc *desc, + g_assert (desc->priv->hotkeys == NULL); + desc->priv->hotkeys = g_value_dup_string (value); + break; ++ case PROP_ICON_SYMBOL: ++ g_free (desc->priv->icon_symbol); ++ desc->priv->icon_symbol = g_value_dup_string (value); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (desc, prop_id, pspec); + } +@@ -355,6 +377,9 @@ ibus_engine_desc_get_property (IBusEngineDesc *desc, + case PROP_HOTKEYS: + g_value_set_string (value, ibus_engine_desc_get_hotkeys (desc)); + break; ++ case PROP_ICON_SYMBOL: ++ g_value_set_string (value, ibus_engine_desc_get_icon_symbol (desc)); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (desc, prop_id, pspec); + } +@@ -382,9 +407,28 @@ ibus_engine_desc_serialize (IBusEngineDesc *desc, + g_variant_builder_add (builder, "u", desc->priv->rank); + g_variant_builder_add (builder, "s", NOTNULL (desc->priv->hotkeys)); + #undef NOTNULL ++ ++ /* append extra properties */ ++ GVariantBuilder array; ++ g_variant_builder_init (&array, G_VARIANT_TYPE ("a{sv}")); ++ g_variant_builder_add (&array, "{sv}", "icon_symbol", g_variant_new_string (desc->priv->icon_symbol)); ++ g_variant_builder_add (builder, "v", g_variant_builder_end (&array)); ++ + return TRUE; + } + ++static gboolean ++ibus_engine_desc_deserialize_property (IBusEngineDesc *desc, ++ const gchar *name, ++ GVariant *variant) ++{ ++ if (g_strcmp0 (name, "icon_symbol") == 0) { ++ g_variant_get (variant, "s", &desc->priv->icon_symbol); ++ return TRUE; ++ } ++ return FALSE; ++} ++ + static gint + ibus_engine_desc_deserialize (IBusEngineDesc *desc, + GVariant *variant) +@@ -405,6 +449,23 @@ ibus_engine_desc_deserialize (IBusEngineDesc *desc, + g_variant_get_child (variant, retval++, "u", &desc->priv->rank); + g_variant_get_child (variant, retval++, "s", &desc->priv->hotkeys); + ++ /* extract extra properties */ ++ GVariantIter iter; ++ GVariant *child, *array; ++ ++ g_variant_get_child (variant, retval++, "v", &array); ++ g_variant_iter_init (&iter, array); ++ while ((child = g_variant_iter_next_value (&iter))) { ++ gchar *name; ++ GVariant *value; ++ g_variant_get (child, "{sv}", &name, &value); ++ if (ibus_engine_desc_deserialize_property (desc, name, value)) ++ retval++; ++ g_free (name); ++ g_variant_unref (value); ++ g_variant_unref (child); ++ } ++ + return retval; + } + +@@ -428,6 +489,7 @@ ibus_engine_desc_copy (IBusEngineDesc *dest, + dest->priv->layout = g_strdup (src->priv->layout); + dest->priv->rank = src->priv->rank; + dest->priv->hotkeys = g_strdup (src->priv->hotkeys); ++ dest->priv->icon_symbol = g_strdup (src->priv->icon_symbol); + return TRUE; + } + +@@ -465,6 +527,7 @@ ibus_engine_desc_output (IBusEngineDesc *desc, + OUTPUT_ENTRY_1(icon); + OUTPUT_ENTRY_1(layout); + OUTPUT_ENTRY_1(hotkeys); ++ OUTPUT_ENTRY_1(icon_symbol); + g_string_append_indent (output, indent + 1); + g_string_append_printf (output, "%u\n", desc->priv->rank); + #undef OUTPUT_ENTRY +@@ -498,6 +561,7 @@ ibus_engine_desc_parse_xml_node (IBusEngineDesc *desc, + PARSE_ENTRY_1(icon); + PARSE_ENTRY_1(layout); + PARSE_ENTRY_1(hotkeys); ++ PARSE_ENTRY_1(icon_symbol); + #undef PARSE_ENTRY + #undef PARSE_ENTRY_1 + if (g_strcmp0 (sub_node->name , "rank") == 0) { +@@ -526,6 +590,7 @@ IBUS_ENGINE_DESC_GET_PROPERTY (icon, const gchar *) + IBUS_ENGINE_DESC_GET_PROPERTY (layout, const gchar *) + IBUS_ENGINE_DESC_GET_PROPERTY (rank, guint) + IBUS_ENGINE_DESC_GET_PROPERTY (hotkeys, const gchar *) ++IBUS_ENGINE_DESC_GET_PROPERTY (icon_symbol, const gchar *) + #undef IBUS_ENGINE_DESC_GET_PROPERTY + + IBusEngineDesc * +@@ -573,6 +638,7 @@ ibus_engine_desc_new_varargs (const gchar *first_property_name, ...) + g_assert (desc->priv->icon); + g_assert (desc->priv->layout); + g_assert (desc->priv->hotkeys); ++ g_assert (desc->priv->icon_symbol); + + return desc; + } +diff --git a/src/ibusenginedesc.h b/src/ibusenginedesc.h +index 9718b15..e3194c3 100644 +--- a/src/ibusenginedesc.h ++++ b/src/ibusenginedesc.h +@@ -249,6 +249,16 @@ guint ibus_engine_desc_get_rank (IBusEngineDesc *info); + const gchar *ibus_engine_desc_get_hotkeys (IBusEngineDesc *info); + + /** ++ * ibus_engine_desc_get_icon_symbol: ++ * @info: An IBusEngineDesc ++ * @returns: icon_symbol property in IBusEngineDesc ++ * ++ * Return the icon_symbol property in IBusEngineDesc. It should not be freed. ++ */ ++const gchar *ibus_engine_desc_get_icon_symbol ++ (IBusEngineDesc *info); ++ ++/** + * ibus_engine_desc_output: + * @info: An IBusEngineDesc + * @output: XML-formatted Input method engine description. +-- +1.7.4.4 + diff --git a/ibus-xx-setup-frequent-lang.patch b/ibus-xx-setup-frequent-lang.patch index a019fa8..a65949e 100644 --- a/ibus-xx-setup-frequent-lang.patch +++ b/ibus-xx-setup-frequent-lang.patch @@ -1,6 +1,6 @@ -From 231285d6d9e1b0b868edb842b46c30974a5c517a Mon Sep 17 00:00:00 2001 +From 735a4d98ac057ded317dae9b85777ce56d8af0fd Mon Sep 17 00:00:00 2001 From: fujiwarat -Date: Wed, 25 May 2011 18:52:25 +0900 +Date: Mon, 20 Jun 2011 19:04:51 +0900 Subject: [PATCH] Enable ibus-setup to show the frequently used languages only in IME list. @@ -10,10 +10,10 @@ Subject: [PATCH] Enable ibus-setup to show the frequently used languages setup/main.py | 1 + 3 files changed, 300 insertions(+), 22 deletions(-) -diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in -index 39922a0..2e33b2c 100644 ---- a/data/ibus.schemas.in -+++ b/data/ibus.schemas.in +diff --git a/data/ibus.schemas.in.in b/data/ibus.schemas.in.in +index d4334e1..5ef2ac2 100644 +--- a/data/ibus.schemas.in.in ++++ b/data/ibus.schemas.in.in @@ -239,6 +239,174 @@ @@ -413,10 +413,10 @@ index 7383177..bff2407 100644 return self.__title diff --git a/setup/main.py b/setup/main.py -index 9cdce02..5201139 100644 +index 192fb88..5a0170d 100644 --- a/setup/main.py +++ b/setup/main.py -@@ -226,6 +226,7 @@ class Setup(object): +@@ -227,6 +227,7 @@ class Setup(object): button.connect("toggled", self.__checkbutton_preload_engine_mode_toggled_cb) self.__engines = self.__bus.list_engines() self.__combobox = self.__builder.get_object("combobox_engines") diff --git a/ibus.spec b/ibus.spec index 15a20f6..592d36b 100644 --- a/ibus.spec +++ b/ibus.spec @@ -13,7 +13,7 @@ Name: ibus Version: 1.3.99.20110419 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Intelligent Input Bus for Linux OS License: LGPLv2+ Group: System Environment/Libraries @@ -21,14 +21,16 @@ URL: http://code.google.com/p/ibus/ Source0: http://ibus.googlecode.com/files/%{name}-%{version}.tar.gz Source1: xinput-ibus %if %have_gjsfile -Source2: http://fujiwara.fedorapeople.org/ibus/gnome-shell/gnome-shell-ibus-plugins-20110601.tar.bz2 +Source2: http://fujiwara.fedorapeople.org/ibus/gnome-shell/gnome-shell-ibus-plugins-20110621.tar.bz2 %endif Source3: https://www.transifex.net/projects/p/ibus/resource/master/l/da/download/ibus_master_da.po +Source4: http://ueno.fedorapeople.org/ibus-indicator/ibus-indicator.tar.bz2 Patch0: ibus-HEAD.patch -Patch1: ibus-435880-surrounding-text.patch -Patch2: ibus-541492-xkb.patch -Patch3: ibus-530711-preload-sys.patch -Patch4: ibus-xx-setup-frequent-lang.patch +Patch1: ibus-530711-preload-sys.patch +Patch2: ibus-xx-icon-symbol.patch +Patch3: ibus-541492-xkb.patch +Patch4: ibus-xx-bridge-hotkey.patch +Patch5: ibus-xx-setup-frequent-lang.patch # Workaround for oxygen-gtk icon theme until bug 699103 is fixed. Patch91: ibus-711632-fedora-fallback-icon.patch @@ -121,6 +123,21 @@ Requires(post): glib2 >= %{glib_ver} %description gtk3 This package contains ibus im module for gtk3 +%package gnome3 +Summary: IBus gnome-shell-extension for GNOME3 +Group: System Environment/Libraries +Requires: %{name} = %{version}-%{release} +Requires: %{name}-libs = %{version}-%{release} +Requires: gnome-shell + +%description gnome3 +This is a transitional package which allows users to try out new IBus +GUI for GNOME3 in development. Note that this package will be marked +as obsolete once the integration has completed in the GNOME3 upstream. + +%description gnome3 +This package contains ibus im module for gtk3 + %package devel Summary: Development tools for ibus Group: Development/Libraries @@ -150,18 +167,19 @@ sed -i \ -e "s|Config.IBUS_XKB|'/usr/libexec/ibus-xkb'|" \ -e "s|Config.HAVE_IBUS_XKB|true|" \ js/ui/status/ibus/xkbLayout.js +bzcat %SOURCE4 | tar xf - %endif cp %SOURCE3 po/da.po %patch0 -p1 -# start surrounding patch -%patch1 -p1 -b .surrounding cp client/gtk2/ibusimcontext.c client/gtk3/ibusimcontext.c -# end surrounding patch +%patch1 -p1 -b .preload-sys +%patch2 -p1 -b .icon-symbol %if %have_libxkbfile -%patch2 -p1 -b .xkb +%patch3 -p1 -b .xkb %endif -%patch3 -p1 -b .preload-sys -%patch4 -p1 -b .setup-frequent-lang +mv data/ibus.schemas.in data/ibus.schemas.in.in +%patch4 -p1 -b .bridge-key +%patch5 -p1 -b .setup-frequent-lang %patch91 -p1 -b .fallback-icon @@ -180,6 +198,7 @@ automake -a -c -f --disable-gtk-doc \ --with-no-snooper-apps='gnome-do,Do.*,firefox.*,.*chrome.*,.*chromium.*' \ --enable-surrounding-text \ + --enable-bridge-hotkey \ --enable-introspection # make -C po update-gmo @@ -215,19 +234,11 @@ desktop-file-install --delete-original \ $RPM_BUILD_ROOT%{_datadir}/applications/* %if %have_gjsfile -cp -R js/ui/status/ibus $RPM_BUILD_ROOT%{_datadir}/ibus/ui/gjs-g-s -cat >> $RPM_BUILD_ROOT%{_datadir}/ibus/ui/gjs-g-s/README <<_EOF -IBus Panel for GNOME-Shell --------------------------- - -This is an alpha version of IBus Panel for GNOME-Shell. -These files under this directory are prepared for the test purpose. -It is planned to integrate the files into gnome-shell finally. -Please refer the installation: -https://fedoraproject.org/wiki/I18N/InputMethods#GNOME-Shell -Bug Report: -https://bugzilla.redhat.com/show_bug.cgi?id=657165 -_EOF +# https://bugzilla.redhat.com/show_bug.cgi?id=657165 +install -dm 755 $RPM_BUILD_ROOT%{_datadir}/gnome-shell +cp -R js $RPM_BUILD_ROOT%{_datadir}/gnome-shell +install -dm 755 $RPM_BUILD_ROOT%{_datadir}/gnome-shell/extensions +cp -R ibus-indicator@example.com $RPM_BUILD_ROOT%{_datadir}/gnome-shell/extensions %endif # FIXME: no version number @@ -323,6 +334,11 @@ fi %defattr(-,root,root,-) %{_libdir}/gtk-3.0/%{gtk3_binary_version}/immodules/im-ibus.so +%files gnome3 +%defattr(-,root,root,-) +%{_datadir}/gnome-shell/js/ui/status/ibus +%{_datadir}/gnome-shell/extensions/ibus-indicator@example.com + %files devel %defattr(-,root,root,-) %{_libdir}/lib*.so @@ -337,9 +353,14 @@ fi %{_datadir}/gtk-doc/html/* %changelog -* Wed Jun 08 2011 Takao Fujiwara - 1.3.99.20110419-2 +* Mon Jun 20 2011 Takao Fujiwara - 1.3.99.20110419-3 +- Updated ibus-HEAD.patch for upstream. +- Removed ibus-435880-surrounding-text.patch as upstream. - Added ibus-711632-fedora-fallback-icon.patch Fixed SEGV with no icon in oxygen-gtk icon theme. +- Added ibus-xx-icon-symbol.patch +- Added ibus-xx-bridge-hotkey.patch +- Added transitional ibus-gnome3 package. * Thu May 26 2011 Takao Fujiwara - 1.3.99.20110419-1 - Updated to 1.3.99.20110419 diff --git a/sources b/sources index a92cbb8..0b35584 100644 --- a/sources +++ b/sources @@ -1,3 +1,4 @@ d4f2729fecb92ae6b41f26c770b1a772 ibus-1.3.99.20110419.tar.gz -64e556364ee619d51e80397086b1d244 gnome-shell-ibus-plugins-20110601.tar.bz2 +ecd3a320faca906b1b8edaae1988f512 gnome-shell-ibus-plugins-20110621.tar.bz2 698c90edf0f037488e1aa969804e891f ibus_master_da.po +23756d25109745bdc1c3a54db370d210 ibus-indicator.tar.bz2