Example #1
0
gchar *
ibus_message_to_string (IBusMessage *message)
{
    g_assert (message != NULL);

    GString *string = g_string_new ("");

    IBusMessageIter iter;
    GType type;
    gint i = 0;

    g_string_append_printf (string,
                            "message: %d\n"
                            "\tdestination = %s\n"
                            "\tpath = %s\n"
                            "\tinterface = %s\n"
                            "\tmember = %s\n",
                            ibus_message_get_type (message),
                            ibus_message_get_destination (message),
                            ibus_message_get_path (message),
                            ibus_message_get_interface (message),
                            ibus_message_get_member (message));

    ibus_message_iter_init (message, &iter);
    while ((type = ibus_message_iter_get_arg_type (&iter)) != G_TYPE_INVALID) {
        g_string_append_printf (string, "\t\targ%d is %s\n", i++, g_type_name (type));
        ibus_message_iter_next (&iter);
    }

    return g_string_free (string, FALSE);
}
Example #2
0
/* dbus interface */
static IBusMessage *
_dbus_no_implement (BusDBusImpl     *dbus,
                    IBusMessage     *message,
                    BusConnection   *connection)
{
    IBusMessage *reply_message;
    reply_message = ibus_message_new_error_printf (message,
                                                   DBUS_ERROR_UNKNOWN_METHOD,
                                                   "IBus does not support %s.",
                                                   ibus_message_get_member (message));
    return reply_message;
}
Example #3
0
void
bus_dbus_impl_dispatch_message_by_rule (BusDBusImpl     *dbus,
                                        IBusMessage     *message,
                                        BusConnection   *skip_connection)
{
    g_assert (BUS_IS_DBUS_IMPL (dbus));
    g_assert (message != NULL);
    g_assert (BUS_IS_CONNECTION (skip_connection) || skip_connection == NULL);

    GList *recipients = NULL;
    GList *link = NULL;

    static gint32 data_slot = -1;

    if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) {
        return;
    }

    if (data_slot == -1) {
        dbus_message_allocate_data_slot (&data_slot);
    }

    /* If this message has been dispatched by rule, it will be ignored. */
    if (dbus_message_get_data (message, data_slot) != NULL)
        return;

    dbus_message_set_data (message, data_slot, (gpointer) TRUE, NULL);

#if 0
    if (g_strcmp0 (ibus_message_get_member (message), "ValueChanged") == 0) {
        g_debug ("Dispatch ValueChanged");
    }
#endif

    for (link = dbus->rules; link != NULL; link = link->next) {
        GList *list = bus_match_rule_get_recipients (BUS_MATCH_RULE (link->data),
                                                     message);
        recipients = g_list_concat (recipients, list);
    }

    for (link = recipients; link != NULL; link = link->next) {
        BusConnection *connection = BUS_CONNECTION (link->data);
        if (connection != skip_connection) {
            ibus_connection_send (IBUS_CONNECTION (connection), message);
        }
        g_object_unref (connection);
    }
    g_list_free (recipients);
}
Example #4
0
static gboolean
bus_engine_proxy_ibus_signal (IBusProxy     *proxy,
                              IBusMessage   *message)
{
    g_assert (BUS_IS_ENGINE_PROXY (proxy));
    g_assert (message != NULL);
    g_assert (ibus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL);

    const gchar *interface;
    const gchar *name;
    BusEngineProxy *engine;
    IBusError *error;
    gint i;

    static const struct {
        const gchar *member;
        const guint signal_id;
    } signals [] = {
        { "ShowPreeditText",        SHOW_PREEDIT_TEXT },
        { "HidePreeditText",        HIDE_PREEDIT_TEXT },
        { "ShowAuxiliaryText",      SHOW_AUXILIARY_TEXT },
        { "HideAuxiliaryText",      HIDE_AUXILIARY_TEXT },
        { "ShowLookupTable",        SHOW_LOOKUP_TABLE },
        { "HideLookupTable",        HIDE_LOOKUP_TABLE },
        { "PageUpLookupTable",      PAGE_UP_LOOKUP_TABLE },
        { "PageDownLookupTable",    PAGE_DOWN_LOOKUP_TABLE },
        { "CursorUpLookupTable",    CURSOR_UP_LOOKUP_TABLE },
        { "CursorDownLookupTable",  CURSOR_DOWN_LOOKUP_TABLE },
    };

    engine = BUS_ENGINE_PROXY (proxy);
    interface = ibus_message_get_interface (message);
    name = ibus_message_get_member (message);

    if (interface != NULL && g_strcmp0 (interface, IBUS_INTERFACE_ENGINE) != 0)
        return FALSE;

    for (i = 0; i < G_N_ELEMENTS (signals); i++) {
        if (g_strcmp0 (name, signals[i].member) == 0) {
            g_signal_emit (engine, engine_signals[signals[i].signal_id], 0);
            goto handled;
        }
    }

    if (g_strcmp0 (name, "CommitText") == 0) {
        IBusText *text;
        gboolean retval;

        retval = ibus_message_get_args (message,
                                        &error,
                                        IBUS_TYPE_TEXT, &text,
                                        G_TYPE_INVALID);
        if (!retval)
            goto failed;
        g_signal_emit (engine, engine_signals[COMMIT_TEXT], 0, text);
        g_object_unref (text);
    }
    else if (g_strcmp0 (name, "ForwardKeyEvent") == 0) {
        guint32 keyval;
        guint32 keycode;
        guint32 states;
        gboolean retval;

        retval = ibus_message_get_args (message,
                                        &error,
                                        G_TYPE_UINT, &keyval,
                                        G_TYPE_UINT, &keycode,
                                        G_TYPE_UINT, &states,
                                        G_TYPE_INVALID);

        if (!retval)
            goto failed;
        g_signal_emit (engine,
                       engine_signals[FORWARD_KEY_EVENT],
                       0,
                       keyval,
                       keycode,
                       states);
    }
    else if (g_strcmp0 (name, "DeleteSurroundingText") == 0) {
        gint  offset_from_cursor;
        guint nchars;
        gboolean retval;

        retval = ibus_message_get_args (message,
                                        &error,
                                        G_TYPE_INT,  &offset_from_cursor,
                                        G_TYPE_UINT, &nchars,
                                        G_TYPE_INVALID);

        if (!retval)
            goto failed;
        g_signal_emit (engine, engine_signals[DELETE_SURROUNDING_TEXT], 0, offset_from_cursor, nchars);
    }
    else if (g_strcmp0 (name, "UpdatePreeditText") == 0) {
        IBusText *text;
        gint cursor_pos;
        gboolean visible;
        gboolean retval;
        guint mode;

        retval = ibus_message_get_args (message,
                                        &error,
                                        IBUS_TYPE_TEXT, &text,
                                        G_TYPE_UINT, &cursor_pos,
                                        G_TYPE_BOOLEAN, &visible,
                                        G_TYPE_UINT, &mode,
                                        G_TYPE_INVALID);

        if (!retval)
            goto failed;

        g_signal_emit (engine, engine_signals[UPDATE_PREEDIT_TEXT], 0,
                        text, cursor_pos, visible, mode);
        if (g_object_is_floating (text))
            g_object_unref (text);
    }
    else if (g_strcmp0 (name, "UpdateAuxiliaryText") == 0) {
        IBusText *text;
        gboolean visible;
        gboolean retval;

        retval = ibus_message_get_args (message,
                                        &error,
                                        IBUS_TYPE_TEXT, &text,
                                        G_TYPE_BOOLEAN, &visible,
                                        G_TYPE_INVALID);

        if (!retval)
            goto failed;

        g_signal_emit (engine, engine_signals[UPDATE_AUXILIARY_TEXT], 0, text, visible);
        if (g_object_is_floating (text))
            g_object_unref (text);
    }
    else if (g_strcmp0 (name, "UpdateLookupTable") == 0) {
        IBusLookupTable *table;
        gboolean visible;
        gboolean retval;

        retval = ibus_message_get_args (message,
                                        &error,
                                        IBUS_TYPE_LOOKUP_TABLE, &table,
                                        G_TYPE_BOOLEAN, &visible,
                                        G_TYPE_INVALID);

        if (!retval)
            goto failed;

        g_signal_emit (engine, engine_signals[UPDATE_LOOKUP_TABLE], 0, table, visible);
        if (g_object_is_floating (table))
            g_object_unref (table);
    }
    else if (g_strcmp0 (name, "RegisterProperties") == 0) {
        gboolean retval;
        IBusPropList *prop_list;

        retval = ibus_message_get_args (message,
                                        &error,
                                        IBUS_TYPE_PROP_LIST, &prop_list,
                                        G_TYPE_INVALID);
        if (!retval) {
            goto failed;
        }
        g_signal_emit (engine, engine_signals[REGISTER_PROPERTIES], 0, prop_list);

        if (g_object_is_floating (prop_list))
            g_object_unref (prop_list);

    }
    else if (g_strcmp0 (name, "UpdateProperty") == 0) {
        IBusProperty *prop;
        gboolean retval;

        retval = ibus_message_get_args (message,
                                        &error,
                                        IBUS_TYPE_PROPERTY, &prop,
                                        G_TYPE_INVALID);

        if (!retval)
            goto failed;

        g_signal_emit (engine, engine_signals[UPDATE_PROPERTY], 0, prop);
        if (g_object_is_floating (prop))
            g_object_unref (prop);
    }
    else
        return FALSE;

handled:
    g_signal_stop_emission_by_name (engine, "ibus-signal");
    return TRUE;

failed:
    g_warning ("%s: %s", error->name, error->message);
    ibus_error_free (error);
    return FALSE;
}
Example #5
0
static gboolean
_connection_ibus_message_cb (BusConnection  *connection,
                             IBusMessage    *message,
                             BusDBusImpl    *dbus)
{
    g_assert (BUS_IS_CONNECTION (connection));
    g_assert (message != NULL);
    g_assert (BUS_IS_DBUS_IMPL (dbus));

    const gchar *dest;

    if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) {
        return;
    }
    
    if (ibus_message_is_signal (message,
                                DBUS_INTERFACE_LOCAL,
                                "Disconnected")) {
        /* ignore signal from local interface */
        return FALSE;
    }

    ibus_message_set_sender (message, bus_connection_get_unique_name (connection));

    switch (ibus_message_get_type (message)) {
#if 1
    case DBUS_MESSAGE_TYPE_ERROR:
        g_debug ("From :%s to %s, Error: %s : %s",
                 ibus_message_get_sender (message),
                 ibus_message_get_destination (message),
                 ibus_message_get_error_name (message),
                 ibus_message_get_error_message (message));
        break;
#endif
#if 0
    case DBUS_MESSAGE_TYPE_SIGNAL:
        g_debug ("From :%s to %s, Signal: %s @ %s",
                 ibus_message_get_sender (message),
                 ibus_message_get_destination (message),
                 ibus_message_get_member (message),
                 ibus_message_get_path (message)
                 );
        break;
#endif
#if 0
    case DBUS_MESSAGE_TYPE_METHOD_CALL:
        g_debug("From %s to %s, Method %s on %s",
                ibus_message_get_sender (message),
                ibus_message_get_destination (message),
                ibus_message_get_path (message),
                ibus_message_get_member (message));
        break;
#endif
    }

    dest = ibus_message_get_destination (message);

    if (dest == NULL ||
        strcmp ((gchar *)dest, IBUS_SERVICE_IBUS) == 0 ||
        strcmp ((gchar *)dest, DBUS_SERVICE_DBUS) == 0) {
        /* this message is sent to ibus-daemon */

        switch (ibus_message_get_type (message)) {
        case DBUS_MESSAGE_TYPE_SIGNAL:
        case DBUS_MESSAGE_TYPE_METHOD_RETURN:
        case DBUS_MESSAGE_TYPE_ERROR:
            bus_dbus_impl_dispatch_message_by_rule (dbus, message, NULL);
            return FALSE;
        case DBUS_MESSAGE_TYPE_METHOD_CALL:
            {
                const gchar *path;
                IBusService *object;

                path = ibus_message_get_path (message);

                object = g_hash_table_lookup (dbus->objects, path);

                if (object == NULL ||
                    ibus_service_handle_message (object,
                                                 (IBusConnection *) connection,
                                                 message) == FALSE) {
                    IBusMessage *error;
                    error = ibus_message_new_error_printf (message,
                                                           DBUS_ERROR_UNKNOWN_METHOD,
                                                           "Unknown method %s on %s",
                                                           ibus_message_get_member (message),
                                                           path);
                    ibus_connection_send ((IBusConnection *) connection, error);
                    ibus_message_unref (error);
                }

                /* dispatch message */
                bus_dbus_impl_dispatch_message_by_rule (dbus, message, NULL);
            }
            break;
        default:
            g_assert (FALSE);
        }
    }
    else {
        /* If the destination is not IBus or DBus, the message will be forwanded. */
        bus_dbus_impl_dispatch_message (dbus, message);
    }

    g_signal_stop_emission_by_name (connection, "ibus-message");
    return TRUE;
}
Example #6
0
static gboolean
ibus_engine_ibus_message (IBusEngine     *engine,
                          IBusConnection *connection,
                          IBusMessage    *message)
{
    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;

    gint i;
    const gchar *interface;
    const gchar *name;

    static const struct {
        gchar *member;
        guint  signal_id;
    } no_arg_methods[] = {
        { "FocusIn",     FOCUS_IN },
        { "FocusOut",    FOCUS_OUT },
        { "Reset",       RESET },
        { "Enable",      ENABLE },
        { "Disable",     DISABLE },
        { "PageUp",      PAGE_UP },
        { "PageDown",    PAGE_DOWN },
        { "CursorUp",    CURSOR_UP },
        { "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;
        }

        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 (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 ();
        }
    } while (0);

    ibus_connection_send (connection, reply);
    ibus_message_unref (reply);
    return TRUE;
}
Example #7
0
static gboolean
ibus_input_context_ibus_signal (IBusProxy           *proxy,
                                IBusMessage         *message)
{
    g_assert (IBUS_IS_INPUT_CONTEXT (proxy));
    g_assert (message != NULL);
    g_assert (ibus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL);

    IBusInputContext *context;
    IBusError *error = NULL;
    gint i;
    const gchar *interface;
    const gchar *name;

    context = IBUS_INPUT_CONTEXT (proxy);

    static const struct {
        const gchar *member;
        guint signal_id;
    } signals [] = {
        { "Enabled",                ENABLED                  },
        { "Disabled",               DISABLED                 },
        { "ShowPreeditText",        SHOW_PREEDIT_TEXT        },
        { "HidePreeditText",        HIDE_PREEDIT_TEXT        },
        { "ShowAuxiliaryText",      SHOW_AUXILIARY_TEXT      },
        { "HideAuxiliaryText",      HIDE_AUXILIARY_TEXT      },
        { "ShowLookupTable",        SHOW_LOOKUP_TABLE        },
        { "HideLookupTable",        HIDE_LOOKUP_TABLE        },
        { "PageUpLookupTable",      PAGE_UP_LOOKUP_TABLE     },
        { "PageDownLookupTable",    PAGE_DOWN_LOOKUP_TABLE   },
        { "CursorUpLookupTable",    CURSOR_UP_LOOKUP_TABLE   },
        { "CursorDownLookupTable",  CURSOR_DOWN_LOOKUP_TABLE },
    };

    do {
        interface = ibus_message_get_interface (message);
        name = ibus_message_get_member (message);

        if (interface != NULL && g_strcmp0 (interface, IBUS_INTERFACE_INPUT_CONTEXT) != 0) {
            error = ibus_error_new_from_printf (DBUS_ERROR_FAILED,
                                                "Signal %s.%s is not handled", interface, name);
            break;
        }

        if (g_strcmp0 (name, "CommitText") == 0) {
            IBusText *text;
            gboolean retval;

            retval = ibus_message_get_args (message,
                                            &error,
                                            IBUS_TYPE_TEXT, &text,
                                            G_TYPE_INVALID);
            if (retval) {
                g_signal_emit (context, context_signals[COMMIT_TEXT], 0, text);
                if (g_object_is_floating (text))
                    g_object_unref (text);
            }
            break;
        }
        if (g_strcmp0 (name, "UpdatePreeditText") == 0) {
            IBusText *text;
            gint32 cursor_pos;
            gboolean visible;
            gboolean retval;

            retval = ibus_message_get_args (message,
                                            &error,
                                            IBUS_TYPE_TEXT, &text,
                                            G_TYPE_UINT, &cursor_pos,
                                            G_TYPE_BOOLEAN, &visible,
                                            G_TYPE_INVALID);

            if (retval) {
                g_signal_emit (context,
                               context_signals[UPDATE_PREEDIT_TEXT],
                               0,
                               text,
                               cursor_pos,
                               visible);
                if (g_object_is_floating (text))
                    g_object_unref (text);
            }
            break;
        }

        for (i = 0;
             i < G_N_ELEMENTS (signals) && g_strcmp0 (name, signals[i].member) != 0;
             i++);

        if (i < G_N_ELEMENTS (signals)) {
            g_signal_emit (context, context_signals[signals[i].signal_id], 0);
            break;
        }

        if (g_strcmp0 (name, "UpdateAuxiliaryText") == 0) {
            IBusText *text;
            gboolean visible;
            gboolean retval;

            retval = ibus_message_get_args (message,
                                            &error,
                                            IBUS_TYPE_TEXT, &text,
                                            G_TYPE_BOOLEAN, &visible,
                                            G_TYPE_INVALID);

            if (retval) {
                g_signal_emit (context,
                               context_signals[UPDATE_AUXILIARY_TEXT],
                               0,
                               text,
                               visible);
                if (g_object_is_floating (text))
                    g_object_unref (text);
            }
        }
        else if (g_strcmp0 (name, "UpdateLookupTable") == 0) {
            IBusLookupTable *table;
            gboolean visible;
            gboolean retval;

            retval = ibus_message_get_args (message,
                                            &error,
                                            IBUS_TYPE_LOOKUP_TABLE, &table,
                                            G_TYPE_BOOLEAN, &visible,
                                            G_TYPE_INVALID);

            if (retval) {
                g_signal_emit (context,
                               context_signals[UPDATE_LOOKUP_TABLE],
                               0,
                               table,
                               visible);
                if (g_object_is_floating (table))
                    g_object_unref (table);
            }
        }
        else if (g_strcmp0 (name, "RegisterProperties") == 0) {
            IBusPropList *prop_list;
            gboolean retval;

            retval = ibus_message_get_args (message,
                                            &error,
                                            IBUS_TYPE_PROP_LIST, &prop_list,
                                            G_TYPE_INVALID);

            if (retval) {
                g_signal_emit (context,
                               context_signals[REGISTER_PROPERTIES],
                               0,
                               prop_list);
                if (g_object_is_floating (prop_list))
                    g_object_unref (prop_list);
            }
        }
        else if (g_strcmp0 (name, "UpdateProperty") == 0) {
            IBusProperty *prop;
            gboolean retval;

            retval = ibus_message_get_args (message,
                                            &error,
                                            IBUS_TYPE_PROPERTY, &prop,
                                            G_TYPE_INVALID);
            if (retval) {
                g_signal_emit (context, context_signals[UPDATE_PROPERTY], 0, prop);
                if (g_object_is_floating (prop))
                    g_object_unref (prop);
            }
        }
        else if (g_strcmp0 (name, "ForwardKeyEvent") == 0) {
            guint32 keyval;
            guint32 keycode;
            guint32 state;
            gboolean retval;


            retval = ibus_message_get_args (message,
                                            &error,
                                            G_TYPE_UINT, &keyval,
                                            G_TYPE_UINT, &keycode,
                                            G_TYPE_UINT, &state,
                                            G_TYPE_INVALID);

            if (retval) {
                g_signal_emit (context,
                               context_signals[FORWARD_KEY_EVENT],
                               0,
                               keyval,
                               keycode,
                               state | IBUS_FORWARD_MASK);
            }
        }
        else if (g_strcmp0 (name, "DeleteSurroundingText") == 0) {
            gint offset_from_cursor;
            guint nchars;
            gboolean retval;
            retval = ibus_message_get_args (message,
                                            &error,
                                            G_TYPE_INT, &offset_from_cursor,
                                            G_TYPE_UINT, &nchars,
                                            G_TYPE_INVALID);


            if (retval) {
                g_signal_emit (context,
                               context_signals[DELETE_SURROUNDING_TEXT],
                               0,
                               offset_from_cursor,
                               nchars);
            }
        }
        else {
            error = ibus_error_new_from_printf (DBUS_ERROR_FAILED,
                                                "Signal %s.%s is not handled", interface, name);
            break;
        }
    } while (0);

    if (error == NULL) {
        g_signal_stop_emission_by_name (context, "ibus-signal");
        return TRUE;
    }

    /* some error happens */
    g_warning ("%s: %s", error->name, error->message);
    ibus_error_free (error);
    return FALSE;
}