X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fibusengine.c;h=1c22d6a5cba3651bc0d29620c31a0d9b8f585f45;hb=e0878144a704e9bfd0f5a60e6894b1de272aaa7b;hp=c367f145f25d8e19738e04994a5481ad7addbeed;hpb=0211cdaa80721aac1aade8c76c90ace9c9ccce3d;p=platform%2Fupstream%2Fibus.git diff --git a/src/ibusengine.c b/src/ibusengine.c index c367f14..1c22d6a 100644 --- a/src/ibusengine.c +++ b/src/ibusengine.c @@ -1,3 +1,4 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ /* vim:set et sts=4: */ /* ibus - The Input Bus * Copyright (C) 2008-2010 Peng Huang @@ -18,9 +19,10 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ - -#include #include "ibusengine.h" +#include +#include +#include "ibusmarshalers.h" #include "ibusinternal.h" #include "ibusshare.h" @@ -44,129 +46,249 @@ enum { PROPERTY_SHOW, PROPERTY_HIDE, CANDIDATE_CLICKED, + SET_SURROUNDING_TEXT, + PROCESS_HAND_WRITING_EVENT, + CANCEL_HAND_WRITING, LAST_SIGNAL, }; enum { PROP_0, - PROP_NAME, - PROP_CONNECTION, + PROP_ENGINE_NAME, }; /* IBusEnginePriv */ struct _IBusEnginePrivate { - gchar *name; - IBusConnection *connection; + gchar *engine_name; + GDBusConnection *connection; + + /* cached surrounding text (see also IBusInputContextPrivate and + BusEngineProxy) */ + IBusText *surrounding_text; + guint surrounding_cursor_pos; + guint selection_anchor_pos; }; -typedef struct _IBusEnginePrivate IBusEnginePrivate; static guint engine_signals[LAST_SIGNAL] = { 0 }; +static IBusText *text_empty = NULL; + /* functions prototype */ -static void ibus_engine_destroy (IBusEngine *engine); -static void ibus_engine_set_property (IBusEngine *engine, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void ibus_engine_get_property (IBusEngine *engine, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static gboolean ibus_engine_ibus_message (IBusEngine *engine, - IBusConnection *connection, - IBusMessage *message); -static gboolean ibus_engine_process_key_event - (IBusEngine *engine, - guint keyval, - guint keycode, - guint state); -static void ibus_engine_focus_in (IBusEngine *engine); -static void ibus_engine_focus_out (IBusEngine *engine); -static void ibus_engine_reset (IBusEngine *engine); -static void ibus_engine_enable (IBusEngine *engine); -static void ibus_engine_disable (IBusEngine *engine); -static void ibus_engine_set_cursor_location - (IBusEngine *engine, - gint x, - gint y, - gint w, - gint h); -static void ibus_engine_set_capabilities - (IBusEngine *engine, - guint caps); -static void ibus_engine_page_up (IBusEngine *engine); -static void ibus_engine_page_down (IBusEngine *engine); -static void ibus_engine_cursor_up (IBusEngine *engine); -static void ibus_engine_cursor_down (IBusEngine *engine); -static void ibus_engine_candidate_clicked +static void ibus_engine_destroy (IBusEngine *engine); +static void ibus_engine_set_property (IBusEngine *engine, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void ibus_engine_get_property (IBusEngine *engine, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void ibus_engine_service_method_call + (IBusService *service, + GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation + *invocation); +static GVariant *ibus_engine_service_get_property + (IBusService *service, + GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error); +static gboolean ibus_engine_service_set_property + (IBusService *service, + GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error); +static gboolean ibus_engine_process_key_event + (IBusEngine *engine, + guint keyval, + guint keycode, + guint state); +static void ibus_engine_focus_in (IBusEngine *engine); +static void ibus_engine_focus_out (IBusEngine *engine); +static void ibus_engine_reset (IBusEngine *engine); +static void ibus_engine_enable (IBusEngine *engine); +static void ibus_engine_disable (IBusEngine *engine); +static void ibus_engine_set_cursor_location + (IBusEngine *engine, + gint x, + gint y, + gint w, + gint h); +static void ibus_engine_set_capabilities + (IBusEngine *engine, + guint caps); +static void ibus_engine_page_up (IBusEngine *engine); +static void ibus_engine_page_down (IBusEngine *engine); +static void ibus_engine_cursor_up (IBusEngine *engine); +static void ibus_engine_cursor_down (IBusEngine *engine); +static void ibus_engine_candidate_clicked + (IBusEngine *engine, + guint index, + guint button, + guint state); +static void ibus_engine_property_activate + (IBusEngine *engine, + const gchar *prop_name, + guint prop_state); +static void ibus_engine_property_show (IBusEngine *engine, + const gchar *prop_name); +static void ibus_engine_property_hide (IBusEngine *engine, + const gchar *prop_name); +static void ibus_engine_set_surrounding_text (IBusEngine *engine, - guint index, - guint button, - guint state); -static void ibus_engine_property_activate - (IBusEngine *engine, - const gchar *prop_name, - guint prop_state); -static void ibus_engine_property_show (IBusEngine *engine, - const gchar *prop_name); -static void ibus_engine_property_hide (IBusEngine *engine, - const gchar *prop_name); + IBusText *text, + guint cursor_pos, + guint anchor_pos); +static void ibus_engine_process_hand_writing_event + (IBusEngine *engine, + const gdouble *coordinates, + guint coordinates_len); +static void ibus_engine_cancel_hand_writing + (IBusEngine *engine, + guint n_strokes); +static void ibus_engine_emit_signal (IBusEngine *engine, + const gchar *signal_name, + GVariant *parameters); G_DEFINE_TYPE (IBusEngine, ibus_engine, IBUS_TYPE_SERVICE) -IBusEngine * -ibus_engine_new (const gchar *name, - const gchar *path, - IBusConnection *connection) -{ - g_assert (path); - g_assert (IBUS_IS_CONNECTION (connection)); - - IBusEngine *engine; - - engine = (IBusEngine *) g_object_new (IBUS_TYPE_ENGINE, - "name", name, - "path", path, - "connection", connection, - NULL); - - return engine; -} +static const gchar introspection_xml[] = + "" + " " + /* FIXME methods */ + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + /* FIXME signals */ + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; static void -ibus_engine_class_init (IBusEngineClass *klass) +ibus_engine_class_init (IBusEngineClass *class) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (IBusEnginePrivate)); + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (class); gobject_class->set_property = (GObjectSetPropertyFunc) ibus_engine_set_property; gobject_class->get_property = (GObjectGetPropertyFunc) ibus_engine_get_property; ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_engine_destroy; - IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) ibus_engine_ibus_message; - - klass->process_key_event = ibus_engine_process_key_event; - klass->focus_in = ibus_engine_focus_in; - klass->focus_out = ibus_engine_focus_out; - klass->reset = ibus_engine_reset; - klass->enable = ibus_engine_enable; - klass->disable = ibus_engine_disable; - klass->page_up = ibus_engine_page_up; - klass->page_down = ibus_engine_page_down; - klass->cursor_up = ibus_engine_cursor_up; - klass->cursor_down = ibus_engine_cursor_down; - klass->candidate_clicked = ibus_engine_candidate_clicked; - klass->property_activate = ibus_engine_property_activate; - klass->property_show = ibus_engine_property_show; - klass->property_hide = ibus_engine_property_hide; - klass->set_cursor_location = ibus_engine_set_cursor_location; - klass->set_capabilities = ibus_engine_set_capabilities; - + IBUS_SERVICE_CLASS (class)->service_method_call = ibus_engine_service_method_call; + IBUS_SERVICE_CLASS (class)->service_get_property = ibus_engine_service_get_property; + IBUS_SERVICE_CLASS (class)->service_set_property = ibus_engine_service_set_property; + + ibus_service_class_add_interfaces (IBUS_SERVICE_CLASS (class), introspection_xml); + + class->process_key_event = ibus_engine_process_key_event; + class->focus_in = ibus_engine_focus_in; + class->focus_out = ibus_engine_focus_out; + class->reset = ibus_engine_reset; + class->enable = ibus_engine_enable; + class->disable = ibus_engine_disable; + class->page_up = ibus_engine_page_up; + class->page_down = ibus_engine_page_down; + class->cursor_up = ibus_engine_cursor_up; + class->cursor_down = ibus_engine_cursor_down; + class->candidate_clicked = ibus_engine_candidate_clicked; + class->property_activate = ibus_engine_property_activate; + class->property_show = ibus_engine_property_show; + class->property_hide = ibus_engine_property_hide; + class->set_cursor_location = ibus_engine_set_cursor_location; + class->set_capabilities = ibus_engine_set_capabilities; + class->set_surrounding_text = ibus_engine_set_surrounding_text; + class->process_hand_writing_event + = ibus_engine_process_hand_writing_event; + class->cancel_hand_writing = ibus_engine_cancel_hand_writing; /* install properties */ /** @@ -175,25 +297,14 @@ ibus_engine_class_init (IBusEngineClass *klass) * Name of this IBusEngine. */ g_object_class_install_property (gobject_class, - PROP_NAME, - g_param_spec_string ("name", - "name", + PROP_ENGINE_NAME, + g_param_spec_string ("engine-name", + "engine name", "engine name", "noname", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /** - * IBusEngine:connection: - * - * Connection of this IBusEngine. - */ - g_object_class_install_property (gobject_class, - PROP_CONNECTION, - g_param_spec_object ("connection", - "connection", - "The connection of engine object", - IBUS_TYPE_CONNECTION, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); /* install signals */ /** @@ -219,8 +330,8 @@ ibus_engine_class_init (IBusEngineClass *klass) G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, process_key_event), - NULL, NULL, - ibus_marshal_BOOL__UINT_UINT_UINT, + g_signal_accumulator_true_handled, NULL, + _ibus_marshal_BOOL__UINT_UINT_UINT, G_TYPE_BOOLEAN, 3, G_TYPE_UINT, @@ -243,7 +354,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, focus_in), NULL, NULL, - ibus_marshal_VOID__VOID, + _ibus_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -263,7 +374,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, focus_out), NULL, NULL, - ibus_marshal_VOID__VOID, + _ibus_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -283,7 +394,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, reset), NULL, NULL, - ibus_marshal_VOID__VOID, + _ibus_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -303,7 +414,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, enable), NULL, NULL, - ibus_marshal_VOID__VOID, + _ibus_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -323,7 +434,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, disable), NULL, NULL, - ibus_marshal_VOID__VOID, + _ibus_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -347,7 +458,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, set_cursor_location), NULL, NULL, - ibus_marshal_VOID__INT_INT_INT_INT, + _ibus_marshal_VOID__INT_INT_INT_INT, G_TYPE_NONE, 4, G_TYPE_INT, @@ -372,7 +483,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, set_capabilities), NULL, NULL, - ibus_marshal_VOID__UINT, + _ibus_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); @@ -392,7 +503,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, page_up), NULL, NULL, - ibus_marshal_VOID__VOID, + _ibus_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -411,7 +522,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, page_down), NULL, NULL, - ibus_marshal_VOID__VOID, + _ibus_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -430,7 +541,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, cursor_up), NULL, NULL, - ibus_marshal_VOID__VOID, + _ibus_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -449,13 +560,16 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, cursor_down), NULL, NULL, - ibus_marshal_VOID__VOID, + _ibus_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * IBusEngine::candidate-clicked: * @engine: An IBusEngine. + * @index: Index of candidate be clicked. + * @button: Mouse button. + * @state: Keyboard state. * * Emitted when candidate on lookup table is clicked. * Implement the member function candidate_clicked() in extended class to receive this signal. @@ -468,7 +582,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, candidate_clicked), NULL, NULL, - ibus_marshal_VOID__UINT_UINT_UINT, + _ibus_marshal_VOID__UINT_UINT_UINT, G_TYPE_NONE, 3, G_TYPE_UINT, @@ -478,6 +592,8 @@ ibus_engine_class_init (IBusEngineClass *klass) /** * IBusEngine::property-activate: * @engine: An IBusEngine. + * @name: Property name. + * @state: Property state. * * Emitted when a property is activated or change changed. * Implement the member function property_activate() in extended class to receive this signal. @@ -490,7 +606,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, property_activate), NULL, NULL, - ibus_marshal_VOID__STRING_UINT, + _ibus_marshal_VOID__STRING_UINT, G_TYPE_NONE, 2, G_TYPE_STRING, @@ -499,6 +615,7 @@ ibus_engine_class_init (IBusEngineClass *klass) /** * IBusEngine::property-show: * @engine: An IBusEngine. + * @name: Property name. * * Emitted when a property is shown. * Implement the member function property_side() in extended class to receive this signal. @@ -511,7 +628,7 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, property_show), NULL, NULL, - ibus_marshal_VOID__STRING, + _ibus_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); @@ -519,6 +636,7 @@ ibus_engine_class_init (IBusEngineClass *klass) /** * IBusEngine::property-hide: * @engine: An IBusEngine. + * @name: Property name. * * Emitted when a property is hidden. * Implement the member function property_hide() in extended class to receive this signal. @@ -531,34 +649,105 @@ ibus_engine_class_init (IBusEngineClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IBusEngineClass, property_hide), NULL, NULL, - ibus_marshal_VOID__STRING, + _ibus_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); + /** + * IBusEngine::process-hand-writing-event: + * @engine: An IBusEngine. + * @coordinates: An array of double (0.0 to 1.0) which represents a stroke (i.e. [x1, y1, x2, y2, x3, y3, ...]). + * @coordinates_len: The number of elements in the array. + * + * Emitted when a hand writing operation is cancelled. + * Implement the member function cancel_hand_writing() in extended class to receive this signal. + * + * Argument @user_data is ignored in this function. + */ + engine_signals[PROCESS_HAND_WRITING_EVENT] = + g_signal_new (I_("process-hand-writing-event"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IBusEngineClass, process_hand_writing_event), + NULL, NULL, + _ibus_marshal_VOID__POINTER_UINT, + G_TYPE_NONE, + 2, + G_TYPE_POINTER, + G_TYPE_UINT); + + /** + * IBusEngine::cancel-hand-writing: + * @engine: An IBusEngine. + * @n_strokes: The number of strokes to be removed. 0 means "remove all". + * + * Emitted when a hand writing operation is cancelled. + * Implement the member function cancel_hand_writing() in extended class to receive this signal. + * + * Argument @user_data is ignored in this function. + */ + engine_signals[CANCEL_HAND_WRITING] = + g_signal_new (I_("cancel-hand-writing"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IBusEngineClass, cancel_hand_writing), + NULL, NULL, + _ibus_marshal_VOID__UINT, + G_TYPE_NONE, + 1, + G_TYPE_UINT); + + g_type_class_add_private (class, sizeof (IBusEnginePrivate)); + + /** + * IBusEngine::set-surrounding-text: + * @engine: An IBusEngine. + * @text: The surrounding text. + * @cursor_pos: The cursor position on surrounding text. + * @anchor_pos: The anchor position on selection area. + * + * Emitted when a surrounding text is set. + * Implement the member function set_surrounding_text() in extended class to receive this signal. + * If anchor_pos equals to cursor_pos, it means "there are no selection" or "does not support + * selection retrival". + * + * Argument @user_data is ignored in this function. + */ + engine_signals[SET_SURROUNDING_TEXT] = + g_signal_new (I_("set-surrounding-text"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IBusEngineClass, set_surrounding_text), + NULL, NULL, + _ibus_marshal_VOID__OBJECT_UINT_UINT, + G_TYPE_NONE, + 3, + G_TYPE_OBJECT, + G_TYPE_UINT, + G_TYPE_UINT); + + text_empty = ibus_text_new_from_static_string (""); + g_object_ref_sink (text_empty); } static void ibus_engine_init (IBusEngine *engine) { - IBusEnginePrivate *priv; - priv = IBUS_ENGINE_GET_PRIVATE (engine); + engine->priv = IBUS_ENGINE_GET_PRIVATE (engine); - priv->name = NULL; - priv->connection = NULL; + engine->priv->surrounding_text = g_object_ref_sink (text_empty); } static void ibus_engine_destroy (IBusEngine *engine) { - IBusEnginePrivate *priv; - priv = IBUS_ENGINE_GET_PRIVATE (engine); - - g_free (priv->name); + g_free (engine->priv->engine_name); + engine->priv->engine_name = NULL; - if (priv->connection) { - g_object_unref (priv->connection); - priv->connection = NULL; + if (engine->priv->surrounding_text) { + g_object_unref (engine->priv->surrounding_text); + engine->priv->surrounding_text = NULL; } IBUS_OBJECT_CLASS(ibus_engine_parent_class)->destroy (IBUS_OBJECT (engine)); @@ -570,21 +759,10 @@ ibus_engine_set_property (IBusEngine *engine, const GValue *value, GParamSpec *pspec) { - IBusEnginePrivate *priv; - priv = IBUS_ENGINE_GET_PRIVATE (engine); - switch (prop_id) { - case PROP_NAME: - priv->name = g_strdup (g_value_dup_string (value)); + case PROP_ENGINE_NAME: + engine->priv->engine_name = g_value_dup_string (value); break; - - case PROP_CONNECTION: - priv->connection = g_value_get_object (value); - g_object_ref_sink (priv->connection); - ibus_service_add_to_connection ((IBusService *) engine, - priv->connection); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID (engine, prop_id, pspec); } @@ -592,18 +770,13 @@ ibus_engine_set_property (IBusEngine *engine, static void ibus_engine_get_property (IBusEngine *engine, - guint prop_id, GValue *value, GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { - IBusEnginePrivate *priv; - priv = IBUS_ENGINE_GET_PRIVATE (engine); - switch (prop_id) { - case PROP_NAME: - g_value_set_string (value, priv->name); - break; - - case PROP_CONNECTION: - g_value_set_object (value, priv->connection); + case PROP_ENGINE_NAME: + g_value_set_string (value, engine->priv->engine_name); break; default: @@ -611,28 +784,45 @@ ibus_engine_get_property (IBusEngine *engine, } } -static gboolean -ibus_engine_ibus_message (IBusEngine *engine, - IBusConnection *connection, - IBusMessage *message) +static void +ibus_engine_service_method_call (IBusService *service, + GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation) { - g_assert (IBUS_IS_ENGINE (engine)); - g_assert (IBUS_IS_CONNECTION (connection)); - g_assert (message != NULL); - g_assert (ibus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL); - - IBusEnginePrivate *priv; - priv = IBUS_ENGINE_GET_PRIVATE (engine); - - g_assert (priv->connection == connection); - - IBusMessage *reply = NULL; - IBusError *error = NULL; - gboolean retval; + IBusEngine *engine = IBUS_ENGINE (service); + + if (g_strcmp0 (interface_name, IBUS_INTERFACE_ENGINE) != 0) { + IBUS_SERVICE_CLASS (ibus_engine_parent_class)-> + service_method_call (service, + connection, + sender, + object_path, + interface_name, + method_name, + parameters, + invocation); + return; + } - gint i; - const gchar *interface; - const gchar *name; + if (g_strcmp0 (method_name, "ProcessKeyEvent") == 0) { + guint keyval, keycode, state; + gboolean retval = FALSE; + g_variant_get (parameters, "(uuu)", &keyval, &keycode, &state); + g_signal_emit (engine, + engine_signals[PROCESS_KEY_EVENT], + 0, + keyval, + keycode, + state, + &retval); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", retval)); + return; + } static const struct { gchar *member; @@ -649,240 +839,180 @@ ibus_engine_ibus_message (IBusEngine *engine, { "CursorDown", CURSOR_DOWN }, }; - interface = ibus_message_get_interface (message); - name = ibus_message_get_member (message); - - if (interface != NULL && g_strcmp0 (interface, IBUS_INTERFACE_ENGINE) != 0) - return IBUS_SERVICE_CLASS (ibus_engine_parent_class)->ibus_message ( - (IBusService *) engine, connection, message); - - do { - if (g_strcmp0 (name, "ProcessKeyEvent") == 0) { - guint keyval, keycode, state; - - retval = ibus_message_get_args (message, - &error, - G_TYPE_UINT, &keyval, - G_TYPE_UINT, &keycode, - G_TYPE_UINT, &state, - G_TYPE_INVALID); - - if (!retval) { - reply = ibus_message_new_error_printf (message, - DBUS_ERROR_INVALID_ARGS, - "%s.%s: Can not match signature (uuu) of method", - IBUS_INTERFACE_ENGINE, "ProcessKeyEvent"); - ibus_error_free (error); - } - else { - retval = FALSE; - g_signal_emit (engine, - engine_signals[PROCESS_KEY_EVENT], - 0, - keyval, - keycode, - state, - &retval); - - reply = ibus_message_new_method_return (message); - ibus_message_append_args (reply, - G_TYPE_BOOLEAN, &retval, - G_TYPE_INVALID); - } - break; + gint i; + for (i = 0; i < G_N_ELEMENTS (no_arg_methods); i++) { + if (g_strcmp0 (method_name, no_arg_methods[i].member) == 0) { + g_signal_emit (engine, engine_signals[no_arg_methods[i].signal_id], 0); + g_dbus_method_invocation_return_value (invocation, NULL); + return; } + } - for (i = 0; - i < G_N_ELEMENTS (no_arg_methods) && g_strcmp0 (name, no_arg_methods[i].member) != 0; - i++); - - if (i < G_N_ELEMENTS (no_arg_methods)) { - IBusMessageIter iter; - ibus_message_iter_init (message, &iter); - if (ibus_message_iter_has_next (&iter)) { - reply = ibus_message_new_error_printf (message, - DBUS_ERROR_INVALID_ARGS, - "%s.%s: Method does not have arguments", - IBUS_INTERFACE_ENGINE, no_arg_methods[i].member); - } - else { - g_signal_emit (engine, engine_signals[no_arg_methods[i].signal_id], 0); - reply = ibus_message_new_method_return (message); - } - break; - } + if (g_strcmp0 (method_name, "CandidateClicked") == 0) { + guint index, button, state; + g_variant_get (parameters, "(uuu)", &index, &button, &state); + g_signal_emit (engine, + engine_signals[CANDIDATE_CLICKED], + 0, + index, + button, + state); + g_dbus_method_invocation_return_value (invocation, NULL); + return; + } - if (g_strcmp0 (name, "CandidateClicked") == 0) { - guint index, button, state; - - retval = ibus_message_get_args (message, - &error, - G_TYPE_UINT, &index, - G_TYPE_UINT, &button, - G_TYPE_UINT, &state, - G_TYPE_INVALID); - - if (!retval) { - reply = ibus_message_new_error_printf (message, - DBUS_ERROR_INVALID_ARGS, - "%s.%s: Can not match signature (uuu) of method", - IBUS_INTERFACE_ENGINE, "CandidateClicked"); - ibus_error_free (error); - } - else { - g_signal_emit (engine, - engine_signals[CANDIDATE_CLICKED], - 0, - index, - button, - state); - reply = ibus_message_new_method_return (message); - } - } - else if (g_strcmp0 (name, "PropertyActivate") == 0) { - gchar *name; - guint state; - - retval = ibus_message_get_args (message, - &error, - G_TYPE_STRING, &name, - G_TYPE_UINT, &state, - G_TYPE_INVALID); - - if (!retval) { - reply = ibus_message_new_error_printf (message, - DBUS_ERROR_INVALID_ARGS, - "%s.%s: Can not match signature (si) of method", - IBUS_INTERFACE_ENGINE, - "PropertyActivate"); - ibus_error_free (error); - } - else { - g_signal_emit (engine, - engine_signals[PROPERTY_ACTIVATE], - 0, - name, - state); - - reply = ibus_message_new_method_return (message); - } - } - else if (g_strcmp0 (name, "PropertyShow") == 0) { - gchar *name; - - retval = ibus_message_get_args (message, - &error, - G_TYPE_STRING, &name, - G_TYPE_INVALID); - - if (!retval) { - reply = ibus_message_new_error_printf (message, - DBUS_ERROR_INVALID_ARGS, - "%s.%s: Can not match signature (s) of method", - IBUS_INTERFACE_ENGINE, - "PropertyShow"); - ibus_error_free (error); - } - else { - g_signal_emit (engine, - engine_signals[PROPERTY_SHOW], - 0, - name); - - reply = ibus_message_new_method_return (message); - } - } - else if (g_strcmp0 (name, "PropertyHide") == 0) { - gchar *name; - - retval = ibus_message_get_args (message, - &error, - G_TYPE_STRING, &name, - G_TYPE_INVALID); - if (!retval) { - reply = ibus_message_new_error_printf (message, - DBUS_ERROR_INVALID_ARGS, - "%s.%s: Can not match signature (s) of method", - IBUS_INTERFACE_ENGINE, "PropertyHide"); - ibus_error_free (error); - } - else { - g_signal_emit (engine, engine_signals[PROPERTY_HIDE], 0, name); - reply = ibus_message_new_method_return (message); - } - } - else if (g_strcmp0 (name, "SetCursorLocation") == 0) { - gint x, y, w, h; - - retval = ibus_message_get_args (message, - &error, - G_TYPE_INT, &x, - G_TYPE_INT, &y, - G_TYPE_INT, &w, - G_TYPE_INT, &h, - G_TYPE_INVALID); - if (!retval) { - reply = ibus_message_new_error_printf (message, - DBUS_ERROR_INVALID_ARGS, - "%s.%s: Can not match signature (iiii) of method", - IBUS_INTERFACE_ENGINE, - "SetCursorLocation"); - ibus_error_free (error); - } - else { - engine->cursor_area.x = x; - engine->cursor_area.y = y; - engine->cursor_area.width = w; - engine->cursor_area.height = h; - - g_signal_emit (engine, - engine_signals[SET_CURSOR_LOCATION], - 0, - x, y, w, h); - - reply = ibus_message_new_method_return (message); - } - } - else if (g_strcmp0 (name, "SetCapabilities") == 0) { - guint caps; - - retval = ibus_message_get_args (message, - &error, - G_TYPE_UINT, &caps, - G_TYPE_INVALID); - - if (!retval) { - reply = ibus_message_new_error_printf (message, - DBUS_ERROR_INVALID_ARGS, - "%s.%s: Can not match signature (u) of method", - IBUS_INTERFACE_ENGINE, "SetCapabilities"); - ibus_error_free (error); - } - else { - engine->client_capabilities = caps; - g_signal_emit (engine, engine_signals[SET_CAPABILITIES], 0, caps); - reply = ibus_message_new_method_return (message); - } - } - else if (g_strcmp0 (name, "Destroy") == 0) { - reply = ibus_message_new_method_return (message); - ibus_connection_send (connection, reply); - ibus_message_unref (reply); - ibus_object_destroy ((IBusObject *) engine); - return TRUE; - } - else { - reply = ibus_message_new_error_printf (message, - DBUS_ERROR_UNKNOWN_METHOD, - "%s.%s", - IBUS_INTERFACE_ENGINE, name); - g_warn_if_reached (); + if (g_strcmp0 (method_name, "PropertyActivate") == 0) { + gchar *name; + guint state; + g_variant_get (parameters, "(&su)", &name, &state); + g_signal_emit (engine, + engine_signals[PROPERTY_ACTIVATE], + 0, + name, + state); + g_dbus_method_invocation_return_value (invocation, NULL); + return; + } + + if (g_strcmp0 (method_name, "PropertyShow") == 0) { + gchar *name; + g_variant_get (parameters, "(&s)", &name); + g_signal_emit (engine, + engine_signals[PROPERTY_SHOW], + 0, + name); + g_dbus_method_invocation_return_value (invocation, NULL); + return; + } + + if (g_strcmp0 (method_name, "PropertyHide") == 0) { + gchar *name; + g_variant_get (parameters, "(&s)", &name); + g_signal_emit (engine, + engine_signals[PROPERTY_HIDE], + 0, + name); + g_dbus_method_invocation_return_value (invocation, NULL); + return; + } + + if (g_strcmp0 (method_name, "SetCursorLocation") == 0) { + gint x, y, w, h; + g_variant_get (parameters, "(iiii)", &x, &y, &w, &h); + engine->cursor_area.x = x; + engine->cursor_area.y = y; + engine->cursor_area.width = w; + engine->cursor_area.height = h; + + g_signal_emit (engine, + engine_signals[SET_CURSOR_LOCATION], + 0, + x, y, w, h); + g_dbus_method_invocation_return_value (invocation, NULL); + return; + } + + if (g_strcmp0 (method_name, "SetCapabilities") == 0) { + guint caps; + g_variant_get (parameters, "(u)", &caps); + engine->client_capabilities = caps; + g_signal_emit (engine, engine_signals[SET_CAPABILITIES], 0, caps); + g_dbus_method_invocation_return_value (invocation, NULL); + return; + } + + if (g_strcmp0 (method_name, "SetSurroundingText") == 0) { + GVariant *variant = NULL; + IBusText *text; + guint cursor_pos; + guint anchor_pos; + + g_variant_get (parameters, + "(vuu)", + &variant, + &cursor_pos, + &anchor_pos); + text = IBUS_TEXT (ibus_serializable_deserialize (variant)); + g_variant_unref (variant); + + g_signal_emit (engine, engine_signals[SET_SURROUNDING_TEXT], + 0, + text, + cursor_pos, + anchor_pos); + if (g_object_is_floating (text)) { + g_object_unref (text); } - } while (0); + g_dbus_method_invocation_return_value (invocation, NULL); + return; + } + + if (g_strcmp0 (method_name, "ProcessHandWritingEvent") == 0) { + const gdouble *coordinates; + gsize coordinates_len = 0; - ibus_connection_send (connection, reply); - ibus_message_unref (reply); - return TRUE; + coordinates = g_variant_get_fixed_array (g_variant_get_child_value (parameters, 0), &coordinates_len, sizeof (gdouble)); + g_return_if_fail (coordinates != NULL); + g_return_if_fail (coordinates_len >= 4); /* The array should contain at least one line. */ + g_return_if_fail (coordinates_len <= G_MAXUINT); /* to prevent overflow in the cast in g_signal_emit */ + g_return_if_fail ((coordinates_len & 1) == 0); + + g_signal_emit (engine, engine_signals[PROCESS_HAND_WRITING_EVENT], 0, + coordinates, (guint) coordinates_len); + g_dbus_method_invocation_return_value (invocation, NULL); + return; + } + + if (g_strcmp0 (method_name, "CancelHandWriting") == 0) { + guint n_strokes = 0; + g_variant_get (parameters, "(u)", &n_strokes); + g_signal_emit (engine, engine_signals[CANCEL_HAND_WRITING], 0, n_strokes); + g_dbus_method_invocation_return_value (invocation, NULL); + return; + } + + /* should not be reached */ + g_return_if_reached (); +} + +static GVariant * +ibus_engine_service_get_property (IBusService *service, + GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error) +{ + return IBUS_SERVICE_CLASS (ibus_engine_parent_class)-> + service_get_property (service, + connection, + sender, + object_path, + interface_name, + property_name, + error); +} + +static gboolean +ibus_engine_service_set_property (IBusService *service, + GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error) +{ + return IBUS_SERVICE_CLASS (ibus_engine_parent_class)-> + service_set_property (service, + connection, + sender, + object_path, + interface_name, + property_name, + value, + error); } static gboolean @@ -995,40 +1125,96 @@ ibus_engine_property_hide (IBusEngine *engine, const gchar *prop_name) } static void -_send_signal (IBusEngine *engine, - const gchar *name, - GType first_arg_type, - ...) +ibus_engine_set_surrounding_text (IBusEngine *engine, + IBusText *text, + guint cursor_pos, + guint anchor_pos) { g_assert (IBUS_IS_ENGINE (engine)); - g_assert (name != NULL); - va_list args; - const gchar *path; - IBusEnginePrivate *priv; + if (engine->priv->surrounding_text) { + g_object_unref (engine->priv->surrounding_text); + } - priv = IBUS_ENGINE_GET_PRIVATE (engine); + engine->priv->surrounding_text = (IBusText *) g_object_ref_sink (text ? text : text_empty); + engine->priv->surrounding_cursor_pos = cursor_pos; + engine->priv->selection_anchor_pos = anchor_pos; + // g_debug ("set-surrounding-text ('%s', %d, %d)", text->text, cursor_pos, anchor_pos); +} + +static void +ibus_engine_process_hand_writing_event (IBusEngine *engine, + const gdouble *coordinates, + guint coordinates_len) +{ + // guint i; + // g_debug ("process-hand-writing-event (%u)", coordinates_len); + // for (i = 0; i < coordinates_len; i++) + // g_debug (" %lf", coordinates[i]); +} - path = ibus_service_get_path ((IBusService *)engine); +static void +ibus_engine_cancel_hand_writing (IBusEngine *engine, + guint n_strokes) +{ + // g_debug ("cancel-hand-writing (%u)", n_strokes); +} - va_start (args, first_arg_type); - ibus_connection_send_signal_valist (priv->connection, - path, - IBUS_INTERFACE_ENGINE, - name, - first_arg_type, - args); - va_end (args); +static void +ibus_engine_emit_signal (IBusEngine *engine, + const gchar *signal_name, + GVariant *parameters) +{ + ibus_service_emit_signal ((IBusService *)engine, + NULL, + IBUS_INTERFACE_ENGINE, + signal_name, + parameters, + NULL); } +IBusEngine * +ibus_engine_new (const gchar *engine_name, + const gchar *object_path, + GDBusConnection *connection) +{ + return ibus_engine_new_with_type (IBUS_TYPE_ENGINE, + engine_name, + object_path, + connection); +} + +IBusEngine * +ibus_engine_new_with_type (GType engine_type, + const gchar *engine_name, + const gchar *object_path, + GDBusConnection *connection) +{ + g_return_val_if_fail (g_type_is_a (engine_type, IBUS_TYPE_ENGINE), NULL); + g_return_val_if_fail (engine_name != NULL, NULL); + g_return_val_if_fail (object_path != NULL, NULL); + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + + GObject *object = g_object_new (engine_type, + "engine-name", engine_name, + "object-path", object_path, + "connection", connection, + NULL); + return IBUS_ENGINE (object); +} + + void ibus_engine_commit_text (IBusEngine *engine, IBusText *text) { - _send_signal (engine, - "CommitText", - IBUS_TYPE_TEXT, &text, - G_TYPE_INVALID); + g_return_if_fail (IBUS_IS_ENGINE (engine)); + g_return_if_fail (IBUS_IS_TEXT (text)); + + GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text); + ibus_engine_emit_signal (engine, + "CommitText", + g_variant_new ("(v)", variant)); if (g_object_is_floating (text)) { g_object_unref (text); @@ -1052,75 +1238,49 @@ ibus_engine_update_preedit_text_with_mode (IBusEngine *engine, gboolean visible, IBusPreeditFocusMode mode) { - _send_signal (engine, - "UpdatePreeditText", - IBUS_TYPE_TEXT, &text, - G_TYPE_UINT, &cursor_pos, - G_TYPE_BOOLEAN, &visible, - G_TYPE_UINT, &mode, - G_TYPE_INVALID); + g_return_if_fail (IBUS_IS_ENGINE (engine)); + g_return_if_fail (IBUS_IS_TEXT (text)); + + GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text); + ibus_engine_emit_signal (engine, + "UpdatePreeditText", + g_variant_new ("(vubu)", variant, cursor_pos, visible, mode)); if (g_object_is_floating (text)) { g_object_unref (text); } } -void -ibus_engine_show_preedit_text (IBusEngine *engine) -{ - _send_signal (engine, - "ShowPreeditText", - G_TYPE_INVALID); -} - -void ibus_engine_hide_preedit_text (IBusEngine *engine) -{ - _send_signal (engine, - "HidePreeditText", - G_TYPE_INVALID); -} - void ibus_engine_update_auxiliary_text (IBusEngine *engine, IBusText *text, gboolean visible) { - _send_signal (engine, - "UpdateAuxiliaryText", - IBUS_TYPE_TEXT, &text, - G_TYPE_BOOLEAN, &visible, - G_TYPE_INVALID); + g_return_if_fail (IBUS_IS_ENGINE (engine)); + g_return_if_fail (IBUS_IS_TEXT (text)); + + GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text); + ibus_engine_emit_signal (engine, + "UpdateAuxiliaryText", + g_variant_new ("(vb)", variant, visible)); if (g_object_is_floating (text)) { g_object_unref (text); } } -void -ibus_engine_show_auxiliary_text (IBusEngine *engine) -{ - _send_signal (engine, - "ShowAuxiliaryText", - G_TYPE_INVALID); -} - -void -ibus_engine_hide_auxiliary_text (IBusEngine *engine) -{ - _send_signal (engine, - "HideAuxiliaryText", - G_TYPE_INVALID); -} void ibus_engine_update_lookup_table (IBusEngine *engine, IBusLookupTable *table, gboolean visible) { - _send_signal (engine, - "UpdateLookupTable", - IBUS_TYPE_LOOKUP_TABLE, &table, - G_TYPE_BOOLEAN, &visible, - G_TYPE_INVALID); + g_return_if_fail (IBUS_IS_ENGINE (engine)); + g_return_if_fail (IBUS_IS_LOOKUP_TABLE (table)); + + GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)table); + ibus_engine_emit_signal (engine, + "UpdateLookupTable", + g_variant_new ("(vb)", variant, visible)); if (g_object_is_floating (table)) { g_object_unref (table); @@ -1132,7 +1292,11 @@ ibus_engine_update_lookup_table_fast (IBusEngine *engine, IBusLookupTable *table, gboolean visible) { + g_return_if_fail (IBUS_IS_ENGINE (engine)); + g_return_if_fail (IBUS_IS_LOOKUP_TABLE (table)); + IBusLookupTable *new_table; + IBusText *text; gint page_begin; gint i; @@ -1149,6 +1313,10 @@ ibus_engine_update_lookup_table_fast (IBusEngine *engine, ibus_lookup_table_append_candidate (new_table, ibus_lookup_table_get_candidate (table, i)); } + for (i = 0; (text = ibus_lookup_table_get_label (table, i)) != NULL; i++) { + ibus_lookup_table_append_label (new_table, text); + } + ibus_lookup_table_set_cursor_pos (new_table, ibus_lookup_table_get_cursor_in_page (table)); ibus_lookup_table_set_orientation (new_table, ibus_lookup_table_get_orientation (table)); @@ -1159,52 +1327,113 @@ ibus_engine_update_lookup_table_fast (IBusEngine *engine, } } -void ibus_engine_show_lookup_table (IBusEngine *engine) -{ - _send_signal (engine, - "ShowLookupTable", - G_TYPE_INVALID); -} - -void ibus_engine_hide_lookup_table (IBusEngine *engine) +void +ibus_engine_forward_key_event (IBusEngine *engine, + guint keyval, + guint keycode, + guint state) { - _send_signal (engine, - "HideLookupTable", - G_TYPE_INVALID); -} + g_return_if_fail (IBUS_IS_ENGINE (engine)); -void ibus_engine_forward_key_event (IBusEngine *engine, - guint keyval, - guint keycode, - guint state) -{ - _send_signal (engine, - "ForwardKeyEvent", - G_TYPE_UINT, &keyval, - G_TYPE_UINT, &keycode, - G_TYPE_UINT, &state, - G_TYPE_INVALID); + ibus_engine_emit_signal (engine, + "ForwardKeyEvent", + g_variant_new ("(uuu)", keyval, keycode, state)); } void ibus_engine_delete_surrounding_text (IBusEngine *engine, gint offset_from_cursor, guint nchars) { - _send_signal (engine, - "DeleteSurroundingText", - G_TYPE_INT, &offset_from_cursor, - G_TYPE_UINT, &nchars, - G_TYPE_INVALID); + IBusEnginePrivate *priv; + + g_return_if_fail (IBUS_IS_ENGINE (engine)); + + priv = IBUS_ENGINE_GET_PRIVATE (engine); + + /* Update surrounding-text cache. This is necessary since some + engines call ibus_engine_get_surrounding_text() immediately + after ibus_engine_delete_surrounding_text(). */ + if (priv->surrounding_text) { + IBusText *text; + glong cursor_pos, len; + + cursor_pos = priv->surrounding_cursor_pos + offset_from_cursor; + len = ibus_text_get_length (priv->surrounding_text); + if (cursor_pos >= 0 && len - cursor_pos >= nchars) { + gunichar *ucs; + + ucs = g_utf8_to_ucs4_fast (priv->surrounding_text->text, + -1, + NULL); + memmove (&ucs[cursor_pos], + &ucs[cursor_pos + nchars], + sizeof(gunichar) * (len - cursor_pos - nchars)); + ucs[len - nchars] = 0; + text = ibus_text_new_from_ucs4 (ucs); + g_free (ucs); + priv->surrounding_cursor_pos = cursor_pos; + } else { + text = text_empty; + priv->surrounding_cursor_pos = 0; + } + + g_object_unref (priv->surrounding_text); + priv->surrounding_text = g_object_ref_sink (text); + } + + ibus_engine_emit_signal (engine, + "DeleteSurroundingText", + g_variant_new ("(iu)", offset_from_cursor, nchars)); +} + +void +ibus_engine_get_surrounding_text (IBusEngine *engine, + IBusText **text, + guint *cursor_pos, + guint *anchor_pos) +{ + IBusEnginePrivate *priv; + + g_return_if_fail (IBUS_IS_ENGINE (engine)); + const gboolean signal_only = (text == NULL); + + g_return_if_fail (( signal_only && (cursor_pos == NULL)) || + (!signal_only && (cursor_pos != NULL))); + + g_return_if_fail (( signal_only && (anchor_pos == NULL)) || + (!signal_only && (anchor_pos != NULL))); + + priv = IBUS_ENGINE_GET_PRIVATE (engine); + + if (!signal_only) { + *text = g_object_ref (priv->surrounding_text); + *cursor_pos = priv->surrounding_cursor_pos; + *anchor_pos = priv->selection_anchor_pos; + } + + /* tell the client that this engine will utilize surrounding-text + * feature, which causes periodical update. Note that the client + * should request the initial surrounding-text when the engine is + * enabled (see ibus_im_context_focus_in() and + * _ibus_context_enabled_cb() in client/gtk2/ibusimcontext.c). */ + ibus_engine_emit_signal (engine, + "RequireSurroundingText", + NULL); + + // g_debug ("get-surrounding-text ('%s', %d, %d)", (*text)->text, *cursor_pos, *anchor_pos); } void ibus_engine_register_properties (IBusEngine *engine, IBusPropList *prop_list) { - _send_signal (engine, - "RegisterProperties", - IBUS_TYPE_PROP_LIST, &prop_list, - G_TYPE_INVALID); + g_return_if_fail (IBUS_IS_ENGINE (engine)); + g_return_if_fail (IBUS_IS_PROP_LIST (prop_list)); + + GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)prop_list); + ibus_engine_emit_signal (engine, + "RegisterProperties", + g_variant_new ("(v)", variant)); if (g_object_is_floating (prop_list)) { g_object_unref (prop_list); @@ -1215,24 +1444,39 @@ void ibus_engine_update_property (IBusEngine *engine, IBusProperty *prop) { - _send_signal (engine, - "UpdateProperty", - IBUS_TYPE_PROPERTY, &prop, - G_TYPE_INVALID); + g_return_if_fail (IBUS_IS_ENGINE (engine)); + g_return_if_fail (IBUS_IS_PROPERTY (prop)); + + GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)prop); + ibus_engine_emit_signal (engine, + "UpdateProperty", + g_variant_new ("(v)", variant)); if (g_object_is_floating (prop)) { g_object_unref (prop); } } +#define DEFINE_FUNC(name, Name) \ + void \ + ibus_engine_##name (IBusEngine *engine) \ + { \ + g_return_if_fail (IBUS_IS_ENGINE (engine)); \ + ibus_engine_emit_signal (engine, \ + #Name, \ + NULL); \ + } +DEFINE_FUNC (show_preedit_text, ShowPreeditText) +DEFINE_FUNC (hide_preedit_text, HidePreeditText) +DEFINE_FUNC (show_auxiliary_text, ShowAuxiliaryText) +DEFINE_FUNC (hide_auxiliary_text, HideAuxiliaryText) +DEFINE_FUNC (show_lookup_table, ShowLookupTable) +DEFINE_FUNC (hide_lookup_table, HideLookupTable) +#undef DEFINE_FUNC + const gchar * ibus_engine_get_name (IBusEngine *engine) { - g_assert (IBUS_IS_ENGINE (engine)); - - IBusEnginePrivate *priv; - priv = IBUS_ENGINE_GET_PRIVATE (engine); - - return priv->name; + g_return_val_if_fail (IBUS_IS_ENGINE (engine), NULL); + return engine->priv->engine_name; } -