gboolean bus_connection_add_match (BusConnection *connection, const gchar *rule) { g_assert (BUS_IS_CONNECTION (connection)); g_assert (rule != NULL); BusMatchRule *p; GList *link; BusConnectionPrivate *priv; priv = BUS_CONNECTION_GET_PRIVATE (connection); p = bus_match_rule_new (rule); if (p == NULL) return FALSE; for (link = priv->rules; link != NULL; link = link->next) { if (bus_match_rule_is_equal (p, (BusMatchRule *)link->data)) { g_object_unref (p); return TRUE; } } priv->rules = g_list_append (priv->rules, p); return TRUE; }
BusEngineProxy * bus_engine_proxy_new (const gchar *path, IBusEngineDesc *desc, BusConnection *connection) { g_assert (path); g_assert (IBUS_IS_ENGINE_DESC (desc)); g_assert (BUS_IS_CONNECTION (connection)); BusEngineProxy *engine; engine = (BusEngineProxy *) g_object_new (BUS_TYPE_ENGINE_PROXY, "name", NULL, "path", path, "connection", connection, NULL); engine->desc = desc; g_object_ref_sink (desc); if (desc->layout != NULL && desc->layout[0] != '\0') { engine->keymap = ibus_keymap_get (desc->layout); } if (engine->keymap == NULL) { engine->keymap = ibus_keymap_get ("us"); } return engine; }
gboolean bus_dbus_impl_new_connection (BusDBusImpl *dbus, BusConnection *connection) { g_assert (BUS_IS_DBUS_IMPL (dbus)); g_assert (BUS_IS_CONNECTION (connection)); g_assert (g_list_find (dbus->connections, connection) == NULL); g_object_ref (connection); dbus->connections = g_list_append (dbus->connections, connection); g_signal_connect (connection, "ibus-message", G_CALLBACK (_connection_ibus_message_cb), dbus); g_signal_connect (connection, "ibus-message-sent", G_CALLBACK (_connection_ibus_message_sent_cb), dbus); g_signal_connect (connection, "destroy", G_CALLBACK (_connection_destroy_cb), dbus); return TRUE; }
BusPanelProxy * bus_panel_proxy_new (BusConnection *connection) { g_assert (BUS_IS_CONNECTION (connection)); GObject *obj; obj = g_object_new (BUS_TYPE_PANEL_PROXY, "name", NULL, "path", IBUS_PATH_PANEL, "connection", connection, NULL); return BUS_PANEL_PROXY (obj); }
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); }
BusPanelProxy * bus_panel_proxy_new (BusConnection *connection) { g_assert (BUS_IS_CONNECTION (connection)); GObject *obj; obj = g_initable_new (BUS_TYPE_PANEL_PROXY, NULL, NULL, "g-object-path", IBUS_PATH_PANEL, "g-interface-name", IBUS_INTERFACE_PANEL, "g-connection", bus_connection_get_dbus_connection (connection), "g-default-timeout", g_gdbus_timeout, "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL); return BUS_PANEL_PROXY (obj); }
static void _connection_destroy_cb (BusConnection *connection, BusDBusImpl *dbus) { g_assert (BUS_IS_CONNECTION (connection)); g_assert (BUS_IS_DBUS_IMPL (dbus)); /* ibus_service_remove_from_connection ( IBUS_SERVICE (dbus), IBUS_CONNECTION (connection)); */ const gchar *unique_name = bus_connection_get_unique_name (connection); if (unique_name != NULL) { g_hash_table_remove (dbus->unique_names, unique_name); g_signal_emit (dbus, dbus_signals[NAME_OWNER_CHANGED], 0, unique_name, unique_name, ""); } const GList *name = bus_connection_get_names (connection); while (name != NULL) { g_hash_table_remove (dbus->names, name->data); g_signal_emit (dbus, dbus_signals[NAME_OWNER_CHANGED], 0, name->data, unique_name, ""); name = name->next; } dbus->connections = g_list_remove (dbus->connections, connection); g_object_unref (connection); }
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; }
static gboolean bus_dbus_impl_ibus_message (BusDBusImpl *dbus, BusConnection *connection, IBusMessage *message) { g_assert (BUS_IS_DBUS_IMPL (dbus)); g_assert (BUS_IS_CONNECTION (connection)); g_assert (message != NULL); gint i; IBusMessage *reply_message = NULL; static const struct { const gchar *interface; const gchar *name; IBusMessage *(* handler) (BusDBusImpl *, IBusMessage *, BusConnection *); } handlers[] = { /* Introspectable interface */ { DBUS_INTERFACE_INTROSPECTABLE, "Introspect", _dbus_introspect }, /* DBus interface */ { DBUS_INTERFACE_DBUS, "Hello", _dbus_hello }, { DBUS_INTERFACE_DBUS, "ListNames", _dbus_list_names }, { DBUS_INTERFACE_DBUS, "ListActivatableNames", _dbus_no_implement }, { DBUS_INTERFACE_DBUS, "NameHasOwner", _dbus_name_has_owner }, { DBUS_INTERFACE_DBUS, "StartServiceByName", _dbus_no_implement }, { DBUS_INTERFACE_DBUS, "GetNameOwner", _dbus_get_name_owner }, { DBUS_INTERFACE_DBUS, "GetConnectionUnixUser", _dbus_no_implement }, { DBUS_INTERFACE_DBUS, "AddMatch", _dbus_add_match }, { DBUS_INTERFACE_DBUS, "RemoveMatch", _dbus_remove_match }, { DBUS_INTERFACE_DBUS, "GetId", _dbus_get_id }, { DBUS_INTERFACE_DBUS, "RequestName", _dbus_request_name }, { DBUS_INTERFACE_DBUS, "ReleaseName", _dbus_release_name }, { NULL, NULL, NULL } }; ibus_message_set_destination (message, DBUS_SERVICE_DBUS); for (i = 0; handlers[i].interface != NULL; i++) { if (ibus_message_is_method_call (message, handlers[i].interface, handlers[i].name)) { reply_message = handlers[i].handler (dbus, message, connection); if (reply_message) { ibus_message_set_sender (reply_message, DBUS_SERVICE_DBUS); ibus_message_set_destination (reply_message, bus_connection_get_unique_name (connection)); ibus_message_set_no_reply (reply_message, TRUE); ibus_connection_send (IBUS_CONNECTION (connection), reply_message); ibus_message_unref (reply_message); } g_signal_stop_emission_by_name (dbus, "ibus-message"); return TRUE; } } return parent_class->ibus_message ((IBusService *) dbus, (IBusConnection *) connection, message); }