diff options
Diffstat (limited to 'telepathy-glib')
32 files changed, 629 insertions, 242 deletions
diff --git a/telepathy-glib/Makefile.am b/telepathy-glib/Makefile.am index aece7bc8c..ce60d7d0b 100644 --- a/telepathy-glib/Makefile.am +++ b/telepathy-glib/Makefile.am @@ -247,7 +247,6 @@ libtelepathy_glib_internal_la_SOURCES = \ dbus-daemon.c \ dbus-internal.h \ dbus-properties-mixin.c \ - dbus-properties-mixin-internal.h \ dbus-tube-channel.c \ debug.c \ debug-client.c \ diff --git a/telepathy-glib/abi.am b/telepathy-glib/abi.am index a8471798d..c0ae10f40 100644 --- a/telepathy-glib/abi.am +++ b/telepathy-glib/abi.am @@ -95,6 +95,7 @@ ABI_LISTS = \ versions/0.19.8.abi \ versions/0.19.9.abi \ versions/0.19.10.abi \ + versions/0.21.2.abi \ $(NULL) # The quoting here is unnecessary but harmless, and has the useful side-effect diff --git a/telepathy-glib/account-manager.c b/telepathy-glib/account-manager.c index 679000d06..8a121a42b 100644 --- a/telepathy-glib/account-manager.c +++ b/telepathy-glib/account-manager.c @@ -80,10 +80,13 @@ * their configuration, places accounts online on request, and manipulates * accounts' presence, nicknames and avatars. * - * #TpAccountManager is the "top level" object, its #TpProxy:factory will be + * #TpAccountManager is the "top level" object. Since 0.16 it always has a + * non-%NULL #TpProxy:factory, and its #TpProxy:factory will be * propagated to all other objects like #TpAccountManager -> #TpAccount -> * #TpConnection -> #TpContact and #TpChannel. This means that desired features * set on that factory will be prepared on all those objects. + * If a #TpProxy:factory is not specified when the #TpAccountManager is + * constructed, it will use a #TpAutomaticClientFactory. * * <example id="account-manager"><title>TpAccountManager example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../examples/client/contact-list.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example> * @@ -151,15 +154,10 @@ G_DEFINE_TYPE (TpAccountManager, tp_account_manager, TP_TYPE_PROXY) * * When this feature is prepared, the list of accounts have been retrieved and * are available for use, and change-notification has been set up. - * Additionally, the #TpAccount objects for accounts which existed at the time - * this feature was prepared will have #TP_ACCOUNT_FEATURE_CORE prepared, but - * #TpAccount objects subsequently announced by - * #TpAccountManager::account-validity-changed are <emphasis>not</emphasis> - * guaranteed to have this feature prepared. In practice, this means that - * the accounts returned by calling tp_account_manager_dup_valid_accounts() - * immediately after successfully calling tp_proxy_prepare_finish() on the - * #TpAccountManager will have #TP_ACCOUNT_FEATURE_CORE prepared, but later - * calls to that function do not have the same guarantee. + * Additionally, since 0.16 the #TpAccount objects returned by + * tp_account_manager_dup_valid_accounts() have their + * features prepared as configured by the #TpProxy:factory; in particular, + * they will all have %TP_ACCOUNT_FEATURE_CORE. * * One can ask for a feature to be prepared using the * tp_proxy_prepare_async() function, and waiting for it to callback. @@ -612,8 +610,9 @@ tp_account_manager_class_init (TpAccountManagerClass *klass) * This signal is also used to indicate a new account that did not * previously exist has been added (with @valid set to %TRUE). * + * If @valid is %TRUE, * @account is guaranteed to have %TP_ACCOUNT_FEATURE_CORE prepared, along - * with all features previously passed to + * with all the features previously passed to the #TpProxy:factory<!-- -->'s * tp_simple_client_factory_add_account_features(). * * Since: 0.9.0 @@ -651,7 +650,7 @@ tp_account_manager_class_init (TpAccountManagerClass *klass) * Emitted when an account from @manager is enabled. * * @account is guaranteed to have %TP_ACCOUNT_FEATURE_CORE prepared, along - * with all features previously passed to + * with all the features previously passed to the #TpProxy:factory<!-- -->'s * tp_simple_client_factory_add_account_features(). * * Since: 0.9.0 @@ -753,7 +752,9 @@ _tp_account_manager_new_internal (TpSimpleClientFactory *factory, * @bus_daemon: Proxy for the D-Bus daemon * * Convenience function to create a new account manager proxy. The returned - * #TpAccountManager is not guaranteed to be ready on return. + * #TpAccountManager is not guaranteed to be prepared on return. + * Its #TpProxy:factory will be a new #TpAutomaticClientFactory for + * @bus_daemon. * * Use tp_account_manager_dup() instead if you want an account manager proxy * on the starter or session bus (which is almost always the right thing for @@ -859,13 +860,19 @@ tp_account_manager_can_set_default (void) * * Returns an account manager proxy on the D-Bus daemon on which this * process was activated (if it was launched by D-Bus service activation), or - * the session bus (otherwise). + * the session bus (otherwise). This account manager will always have + * the result of tp_dbus_daemon_dup() as its #TpProxy:dbus-daemon. * * The returned #TpAccountManager is cached; the same #TpAccountManager object * will be returned by this function repeatedly, as long as at least one * reference exists. Note that the returned #TpAccountManager is not guaranteed * to be ready on return. * + * If tp_account_manager_set_default() has been called successfully, + * that #TpAccountManager will be returned. Otherwise, a new #TpAccountManager + * will be created the first time this function is called, using a new + * #TpAutomaticClientFactory as its #TpProxy:factory. + * * Returns: (transfer full): an account manager proxy on the starter or session * bus, or %NULL if it wasn't possible to get a dbus daemon proxy for * the appropriate bus @@ -1038,8 +1045,15 @@ insert_account (TpAccountManager *self, * has already been ensured then the same object will be returned, otherwise * it will create a new #TpAccount and add it to @manager. As a result, if * @manager thinks that the account doesn't exist, this will still add it to - * @manager to avoid races. Note that the returned #TpAccount is not guaranteed - * to be ready on return. + * @manager to avoid races. + * + * The account will be constructed via this account manager's #TpProxy:factory + * (so it will be of an appropriate #TpAccount subclass if the factory + * returns one), but does not necessarily have any features prepared yet. + * Use tp_proxy_prepare_async() to prepare features, using + * the contents of tp_simple_client_factory_dup_account_features() as a + * parameter if you want to prepare the same features that would + * normally be used. * * The caller must keep a ref to the returned object using g_object_ref() if * it is to be kept. @@ -1048,8 +1062,9 @@ insert_account (TpAccountManager *self, * not a valid account path. * * Since: 0.9.0 - * Deprecated: New code should use tp_simple_client_factory_ensure_account() - * instead. + * Deprecated: New code should call tp_simple_client_factory_ensure_account() + * on this object's #TpProxy:factory instead, which ensures that a new + * reference is returned. */ TpAccount * tp_account_manager_ensure_account (TpAccountManager *self, @@ -1106,7 +1121,8 @@ tp_account_manager_ensure_account (TpAccountManager *self, * * The returned #TpAccount<!-- -->s are guaranteed to have * %TP_ACCOUNT_FEATURE_CORE prepared, along with all features previously passed - * to tp_simple_client_factory_add_account_features(). + * to tp_simple_client_factory_add_account_features() for the account + * manager's #TpProxy:factory. * * The list of valid accounts returned is not guaranteed to have been retrieved * until %TP_ACCOUNT_MANAGER_FEATURE_CORE is prepared @@ -1137,7 +1153,8 @@ tp_account_manager_get_valid_accounts (TpAccountManager *manager) * * The returned #TpAccount<!-- -->s are guaranteed to have * %TP_ACCOUNT_FEATURE_CORE prepared, along with all features previously passed - * to tp_simple_client_factory_add_account_features(). + * to tp_simple_client_factory_add_account_features() for the account + * manager's #TpProxy:factory. * * The list of valid accounts returned is not guaranteed to have been retrieved * until %TP_ACCOUNT_MANAGER_FEATURE_CORE is prepared @@ -1367,10 +1384,11 @@ _tp_account_manager_created_cb (TpAccountManager *proxy, * then call tp_account_manager_create_account_finish() to get the result of * the operation. * - * @callback will only be called when the newly created #TpAccount has the - * %TP_ACCOUNT_FEATURE_CORE feature ready on it, so when calling - * tp_account_manager_create_account_finish(), one can guarantee this feature - * will be ready. + * The #TpAccount returned by tp_account_manager_create_account_finish() + * will already have %TP_ACCOUNT_FEATURE_CORE prepared, along with all + * features previously passed to + * tp_simple_client_factory_add_account_features() for the account + * manager's #TpProxy:factory. * * It is usually better to use #TpAccountRequest instead, particularly when * using high-level language bindings. @@ -1413,7 +1431,10 @@ tp_account_manager_create_account_async (TpAccountManager *manager, * @error: a #GError to be filled * * Finishes an async create account operation, and returns a new #TpAccount - * object, with the %TP_ACCOUNT_FEATURE_CORE feature ready on it. + * object. It has %TP_ACCOUNT_FEATURE_CORE prepared, along with all + * features previously passed to + * tp_simple_client_factory_add_account_features() for the account + * manager's #TpProxy:factory. * * The caller must keep a ref to the returned object using g_object_ref() if * it is to be kept beyond the lifetime of @result. diff --git a/telepathy-glib/account.c b/telepathy-glib/account.c index 9aac94a7b..24dbd001a 100644 --- a/telepathy-glib/account.c +++ b/telepathy-glib/account.c @@ -73,6 +73,14 @@ * for many of the properties on this object. Refer to each property's * documentation for whether it can be used in this way. * + * #TpAccount objects should normally be obtained from the #TpAccountManager. + * + * Since 0.16, #TpAccount always has a non-%NULL #TpProxy:factory, and its + * #TpProxy:factory will be propagated to its #TpConnection + * (if any). If a #TpAccount is created without going via the + * #TpAccountManager or specifying a #TpProxy:factory, the default + * is to use a new #TpAutomaticClientFactory. + * * Since: 0.7.32 */ @@ -181,6 +189,7 @@ enum { PROP_STORAGE_IDENTIFIER_VARIANT, PROP_STORAGE_RESTRICTIONS, PROP_SUPERSEDES, + PROP_URI_SCHEMES, N_PROPS }; @@ -231,9 +240,9 @@ connection_is_internal (TpAccount *self) * feature on a #TpAccount. * * When this feature is prepared, it is guaranteed that #TpAccount:connection - * will always be either %NULL or prepared. If the account was created using a - * #TpSimpleClientFactory, the same factory will be used to create #TpConnection - * object and to determine desired connection features. Change notification of + * will always be either %NULL or prepared. The account's #TpProxy:factory + * will be used to create the #TpConnection object and to determine its + * desired connection features. Change notification of the * #TpAccount:connection property will be delayed until all features (at least * %TP_CONNECTION_FEATURE_CORE) are prepared. See * tp_simple_client_factory_add_account_features() to define which features @@ -1019,6 +1028,42 @@ _tp_account_got_all_cb (TpProxy *proxy, } static void +addressing_props_changed (TpAccount *self, + GHashTable *changed_properties) +{ + const gchar * const * v; + + if (self->priv->uri_schemes == NULL) + /* We did not fetch the initial value yet, ignoring */ + return; + + v = tp_asv_get_strv (changed_properties, "URISchemes"); + if (v == NULL) + return; + + g_strfreev (self->priv->uri_schemes); + self->priv->uri_schemes = g_strdupv ((GStrv) v); + + g_object_notify (G_OBJECT (self), "uri-schemes"); +} + +static void +dbus_properties_changed_cb (TpProxy *proxy, + const gchar *interface_name, + GHashTable *changed_properties, + const gchar **invalidated_properties, + gpointer user_data, + GObject *weak_object) +{ + TpAccount *self = TP_ACCOUNT (weak_object); + + if (!tp_strdiff (interface_name, TP_IFACE_ACCOUNT_INTERFACE_ADDRESSING)) + { + addressing_props_changed (self, changed_properties); + } +} + +static void _tp_account_constructed (GObject *object) { TpAccount *self = TP_ACCOUNT (object); @@ -1058,6 +1103,9 @@ _tp_account_constructed (GObject *object) tp_cli_account_connect_to_account_property_changed (self, _tp_account_properties_changed, NULL, NULL, object, NULL); + tp_cli_dbus_properties_connect_to_properties_changed (self, + dbus_properties_changed_cb, NULL, NULL, object, NULL); + tp_cli_dbus_properties_call_get_all (self, -1, TP_IFACE_ACCOUNT, _tp_account_got_all_cb, NULL, NULL, G_OBJECT (self)); } @@ -1149,6 +1197,9 @@ _tp_account_get_property (GObject *object, case PROP_SUPERSEDES: g_value_set_boxed (value, self->priv->supersedes); break; + case PROP_URI_SCHEMES: + g_value_set_boxed (value, self->priv->uri_schemes); + break; case PROP_AUTOMATIC_PRESENCE_TYPE: g_value_set_uint (value, self->priv->auto_presence); break; @@ -2030,6 +2081,32 @@ tp_account_class_init (TpAccountClass *klass) G_PARAM_STATIC_STRINGS | G_PARAM_READABLE)); /** + * TpAccount:uri-schemes: + * + * If the %TP_ACCOUNT_FEATURE_ADDRESSING feature has been prepared + * successfully, a list of additional URI schemes for which this + * account should be used if possible. Otherwise %NULL. + * + * For instance, a SIP or Skype account might have "tel" in this list if the + * user would like to use that account to call phone numbers. + * + * This list should not contain the primary URI scheme(s) for the account's + * protocol (for instance, "xmpp" for XMPP, or "sip" or "sips" for SIP), + * since it should be assumed to be useful for those schemes in any case. + * + * The notify::uri-schemes signal cannot be relied on if the Account Manager + * is Mission Control version 5.14.0 or older. + * + * Since: 0.21.0 + */ + g_object_class_install_property (object_class, PROP_URI_SCHEMES, + g_param_spec_boxed ("uri-schemes", + "URISchemes", + "URISchemes", + G_TYPE_STRV, + G_PARAM_STATIC_STRINGS | G_PARAM_READABLE)); + + /** * TpAccount::status-changed: * @account: the #TpAccount * @old_status: old #TpAccount:connection-status @@ -4231,18 +4308,9 @@ tp_account_prepare_addressing_async (TpProxy *proxy, * tp_account_get_uri_schemes: * @self: a #TpAccount * - * If the %TP_ACCOUNT_FEATURE_ADDRESSING feature has been prepared - * successfully, return a list of additional URI schemes for which this - * account should be used if possible. Otherwise return %NULL. - * - * For instance, a SIP or Skype account might have "tel" in this list if the - * user would like to use that account to call phone numbers. - * - * This list should not contain the primary URI scheme(s) for the account's - * protocol (for instance, "xmpp" for XMPP, or "sip" or "sips" for SIP), - * since it should be assumed to be useful for those schemes in any case. + * Return the #TpAccount:uri-schemes property * - * Returns: (transfer none): a list of URI schemes, or %NULL + * Returns: (transfer none): the value of #TpAccount:uri_schemes property * * Since: 0.13.8 */ diff --git a/telepathy-glib/base-connection.c b/telepathy-glib/base-connection.c index 22167dc20..20a79b8c0 100644 --- a/telepathy-glib/base-connection.c +++ b/telepathy-glib/base-connection.c @@ -286,6 +286,7 @@ enum { PROP_PROTOCOL = 1, PROP_SELF_HANDLE, + PROP_SELF_ID, PROP_INTERFACES, PROP_DBUS_STATUS, PROP_DBUS_DAEMON, @@ -390,6 +391,8 @@ channel_request_cancel (gpointer data, gpointer user_data) struct _TpBaseConnectionPrivate { + const gchar *self_id; + /* Telepathy properties */ gchar *protocol; @@ -477,6 +480,10 @@ tp_base_connection_get_property (GObject *object, g_value_set_uint (value, self->self_handle); break; + case PROP_SELF_ID: + g_value_set_string (value, self->priv->self_id); + break; + case PROP_INTERFACES: g_value_set_boxed (value, tp_base_connection_get_interfaces (self)); break; @@ -516,19 +523,7 @@ tp_base_connection_set_property (GObject *object, break; case PROP_SELF_HANDLE: - { - TpHandle new_self_handle = g_value_get_uint (value); - - if (self->status == TP_CONNECTION_STATUS_CONNECTED) - g_return_if_fail (new_self_handle != 0); - - if (self->self_handle == new_self_handle) - return; - - self->self_handle = new_self_handle; - - tp_svc_connection_emit_self_handle_changed (self, self->self_handle); - } + tp_base_connection_set_self_handle (self, g_value_get_uint (value)); break; case PROP_DBUS_DAEMON: @@ -1549,6 +1544,7 @@ tp_base_connection_class_init (TpBaseConnectionClass *klass) { static TpDBusPropertiesMixinPropImpl connection_properties[] = { { "SelfHandle", "self-handle", NULL }, + { "SelfID", "self-id", NULL }, { "Status", "dbus-status", NULL }, { "Interfaces", "interfaces", NULL }, { "HasImmortalHandles", "has-immortal-handles", NULL }, @@ -1601,6 +1597,21 @@ tp_base_connection_class_init (TpBaseConnectionClass *klass) g_object_class_install_property (object_class, PROP_SELF_HANDLE, param_spec); /** + * TpBaseConnection:self-id: (skip) + * + * The identifier representing the local user. This is the result of + * inspecting #TpBaseConnection:self-handle. + * + * Since: 0.21.2 + */ + param_spec = g_param_spec_string ("self-id", + "Connection.SelfID", + "The identifier representing the local user.", + "", + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_SELF_ID, param_spec); + + /** * TpBaseConnection:interfaces: (skip) * * The set of D-Bus interfaces available on this Connection, other than @@ -2830,7 +2841,28 @@ void tp_base_connection_set_self_handle (TpBaseConnection *self, TpHandle self_handle) { - g_object_set (self, "self-handle", self_handle, NULL); + if (self->status == TP_CONNECTION_STATUS_CONNECTED) + g_return_if_fail (self_handle != 0); + + if (self->self_handle == self_handle) + return; + + self->self_handle = self_handle; + self->priv->self_id = NULL; + + if (self_handle != 0) + { + self->priv->self_id = tp_handle_inspect ( + self->priv->handles[TP_HANDLE_TYPE_CONTACT], self_handle); + } + + tp_svc_connection_emit_self_handle_changed (self, self->self_handle); + + tp_svc_connection_emit_self_contact_changed (self, + self->self_handle, self->priv->self_id); + + g_object_notify ((GObject *) self, "self-handle"); + g_object_notify ((GObject *) self, "self-id"); } diff --git a/telepathy-glib/base-protocol.c b/telepathy-glib/base-protocol.c index 44a5acc24..926cdcdb9 100644 --- a/telepathy-glib/base-protocol.c +++ b/telepathy-glib/base-protocol.c @@ -832,7 +832,11 @@ tp_base_protocol_get_immutable_properties (TpBaseProtocol *self) TP_IFACE_PROTOCOL_INTERFACE_ADDRESSING, "AddressableURISchemes", NULL); - /* FIXME: we should add Presence properties as well */ + if (tp_strv_contains ((const gchar * const *) self->priv->interfaces, + TP_IFACE_PROTOCOL_INTERFACE_PRESENCE)) + tp_dbus_properties_mixin_fill_properties_hash ((GObject *) self, table, + TP_IFACE_PROTOCOL_INTERFACE_PRESENCE, "Statuses", + NULL); return table; } diff --git a/telepathy-glib/call-stream-endpoint.c b/telepathy-glib/call-stream-endpoint.c index 698c473c1..2f87d2d3f 100644 --- a/telepathy-glib/call-stream-endpoint.c +++ b/telepathy-glib/call-stream-endpoint.c @@ -549,7 +549,7 @@ tp_call_stream_endpoint_get_state (TpCallStreamEndpoint *self, TpStreamComponent component) { g_return_val_if_fail (TP_IS_CALL_STREAM_ENDPOINT (self), - TP_MEDIA_STREAM_STATE_DISCONNECTED); + TP_STREAM_ENDPOINT_STATE_FAILED); return GPOINTER_TO_UINT (g_hash_table_lookup (self->priv->endpoint_state, GUINT_TO_POINTER (component))); diff --git a/telepathy-glib/channel-dispatch-operation.c b/telepathy-glib/channel-dispatch-operation.c index 92e29408c..8f20fa9ba 100644 --- a/telepathy-glib/channel-dispatch-operation.c +++ b/telepathy-glib/channel-dispatch-operation.c @@ -99,9 +99,12 @@ * channel dispatch operations for any undispatched channels, and the approver * will be notified again. * - * This proxy is usable but incomplete: accessors for the D-Bus properties will - * be added in a later version of telepathy-glib, along with a mechanism - * similar to tp_connection_call_when_ready(). + * Creating a #TpChannelDispatchOperation directly is deprecated: it + * should only be created via a #TpBaseClient. + * + * Since 0.16, #TpChannelDispatchOperation always has a non-%NULL + * #TpProxy:factory, which will be propagated to the #TpAccount, + * #TpConnection and #TpChannel. * * Since: 0.7.32 */ diff --git a/telepathy-glib/channel-group.c b/telepathy-glib/channel-group.c index c7f2b07cf..204e39830 100644 --- a/telepathy-glib/channel-group.c +++ b/telepathy-glib/channel-group.c @@ -1096,7 +1096,7 @@ handle_members_changed (TpChannel *self, const gchar *debug_message = tp_asv_get_string (details, "debug-message"); - if (debug_message == NULL && message[0] != '\0') + if (debug_message == NULL && !tp_str_empty (message)) debug_message = message; if (debug_message == NULL && error_detail != NULL) diff --git a/telepathy-glib/channel-request.c b/telepathy-glib/channel-request.c index c0b0c4b1b..4c5099995 100644 --- a/telepathy-glib/channel-request.c +++ b/telepathy-glib/channel-request.c @@ -79,14 +79,13 @@ * signal will be emitted with the domain %TP_DBUS_ERRORS and the error code * %TP_DBUS_ERROR_NAME_OWNER_LOST. * - * This proxy is usable but incomplete: accessors for the Account, - * UserActionTime, PreferredHandler, Requests and Interfaces properties will - * be added in a later version of telepathy-glib, along with a mechanism - * similar to tp_connection_call_when_ready(). - * - * Until suitable convenience methods are implemented, the generic - * tp_cli_dbus_properties_call_get_all() method can be used to get those - * properties. + * Creating a #TpChannelRequest directly is deprecated: it + * should only be created via a #TpAccountChannelRequest + * or a #TpBaseClient. + * + * Since 0.16, #TpChannelRequest always has a non-%NULL #TpProxy:factory, + * and its #TpProxy:factory will be propagated to the #TpAccount, + * #TpConnection and #TpChannel. * * Since: 0.7.32 */ diff --git a/telepathy-glib/codegen.am b/telepathy-glib/codegen.am index 8bc0032a0..a564a2a90 100644 --- a/telepathy-glib/codegen.am +++ b/telepathy-glib/codegen.am @@ -136,7 +136,7 @@ tools_dir = $(top_srcdir)/tools # Bootstrapping _gen/spec-stamp: $(wildcard $(top_srcdir)/spec/*.xml) - $(mkdir_p) _gen + $(MKDIR_P) _gen touch $@ _gen/stable-stamp: $(wildcard $(abs_srcdir)/*.xml) _gen/spec-stamp diff --git a/telepathy-glib/connection-manager.c b/telepathy-glib/connection-manager.c index c816bfcbb..2dd1c4ec8 100644 --- a/telepathy-glib/connection-manager.c +++ b/telepathy-glib/connection-manager.c @@ -600,10 +600,16 @@ tp_connection_manager_got_parameters (TpConnectionManager *self, if (error != NULL) { - DEBUG ("Error getting params for %s, skipping it", protocol); + DEBUG ("%s/%s: error from legacy GetParameters, skipping protocol: " + "%s #%d: %s", + self->name, protocol, + g_quark_to_string (error->domain), error->code, error->message); goto out; } + DEBUG ("%s/%s: legacy GetParameters() returned %d parameters", + self->name, protocol, parameters->len); + immutables = tp_asv_new ( TP_PROP_PROTOCOL_PARAMETERS, TP_ARRAY_TYPE_PARAM_SPEC_LIST, parameters, NULL); @@ -661,7 +667,10 @@ tp_connection_manager_end_introspection (TpConnectionManager *self, { tp_connection_manager_reset_introspection (self); - DEBUG ("End of introspection, info source %u", self->info_source); + DEBUG ("%s: end of introspection, info source %s (%d)", + self->name, + _tp_enum_to_nick_nonnull (TP_TYPE_CM_INFO_SOURCE, self->info_source), + self->info_source); g_signal_emit (self, signals[SIGNAL_GOT_INFO], 0, self->info_source); tp_connection_manager_ready_or_failed (self, error); } @@ -722,7 +731,8 @@ tp_connection_manager_get_all_cb (TpProxy *proxy, GHashTableIter iter; gpointer k, v; - DEBUG ("%u Protocols from D-Bus", g_hash_table_size (protocols)); + DEBUG ("%s: %u Protocols from GetAll()", + self->name, g_hash_table_size (protocols)); g_assert (self->priv->found_protocols == NULL); self->priv->found_protocols = g_hash_table_new_full (g_str_hash, @@ -755,10 +765,17 @@ tp_connection_manager_get_all_cb (TpProxy *proxy, } } } + else + { + DEBUG ("%s: no Protocols property in GetAll() (old CM?)", + self->name); + } } else { - DEBUG ("Ignoring error getting ConnectionManager properties: %s %d: %s", + DEBUG ("%s: ignoring error getting CM properties (old CM?): " + "%s %d: %s", + self->name, g_quark_to_string (error->domain), error->code, error->message); } @@ -776,9 +793,11 @@ tp_connection_manager_continue_introspection (TpConnectionManager *self) { gchar *next_protocol; + DEBUG ("%s", self->name); + if (self->priv->introspection_step == INTROSPECT_IDLE) { - DEBUG ("calling GetAll on CM"); + DEBUG ("%s: calling GetAll on CM", self->name); self->priv->introspection_step = INTROSPECT_GETTING_PROPERTIES; self->priv->introspection_call = tp_cli_dbus_properties_call_get_all ( self, -1, TP_IFACE_CONNECTION_MANAGER, @@ -792,7 +811,7 @@ tp_connection_manager_continue_introspection (TpConnectionManager *self) if (self->priv->found_protocols == NULL) { - DEBUG ("calling ListProtocols on CM"); + DEBUG ("%s: calling legacy ListProtocols on CM", self->name); self->priv->introspection_step = INTROSPECT_LISTING_PROTOCOLS; self->priv->introspection_call = tp_cli_connection_manager_call_list_protocols (self, -1, @@ -832,6 +851,8 @@ tp_connection_manager_continue_introspection (TpConnectionManager *self) next_protocol = g_ptr_array_remove_index_fast ( self->priv->pending_protocols, 0); self->priv->introspection_step = INTROSPECT_GETTING_PARAMETERS; + DEBUG ("%s/%s: calling legacy ListProtocols", + self->name, next_protocol); self->priv->introspection_call = tp_cli_connection_manager_call_get_parameters (self, -1, next_protocol, tp_connection_manager_got_parameters, @@ -854,12 +875,16 @@ tp_connection_manager_got_protocols (TpConnectionManager *self, if (error != NULL) { - DEBUG ("Failed: %s", error->message); + DEBUG ("%s: legacy GetProtocols() failed: %s #%d: %s", + self->name, + g_quark_to_string (error->domain), error->code, error->message); if (!self->running) { /* ListProtocols failed to start it - we assume this is because * activation failed */ + DEBUG ("%s: ListProtocols didn't start it: activation failure?", + self->name); g_signal_emit (self, signals[SIGNAL_EXITED], 0); } @@ -870,7 +895,7 @@ tp_connection_manager_got_protocols (TpConnectionManager *self, for (iter = protocols; *iter != NULL; iter++) i++; - DEBUG ("Succeeded with %u protocols", i); + DEBUG ("%s: legacy GetProtocols() returned %u protocols", self->name, i); g_assert (self->priv->found_protocols == NULL); self->priv->found_protocols = g_hash_table_new_full (g_str_hash, @@ -883,7 +908,7 @@ tp_connection_manager_got_protocols (TpConnectionManager *self, { if (!tp_connection_manager_check_valid_protocol_name (*iter, NULL)) { - DEBUG ("Protocol %s has an invalid name", *iter); + DEBUG ("%s: protocol %s has an invalid name", self->name, *iter); continue; } @@ -943,13 +968,14 @@ tp_connection_manager_name_owner_changed_cb (TpDBusDaemon *bus, { if (self->priv->retried_introspection) { - DEBUG ("%s, twice: assuming fatal and not retrying", e.message); + DEBUG ("%s: %s, twice: assuming fatal and not retrying", + self->name, e.message); tp_connection_manager_end_introspection (self, &e); } else { self->priv->retried_introspection = TRUE; - DEBUG ("%s: retrying", e.message); + DEBUG ("%s: %s: retrying", self->name, e.message); tp_connection_manager_reset_introspection (self); tp_connection_manager_continue_introspection (self); } @@ -959,6 +985,7 @@ tp_connection_manager_name_owner_changed_cb (TpDBusDaemon *bus, * state, so we didn't *exit* as such. */ if (self->priv->name_known) { + DEBUG ("%s: exited", self->name); g_signal_emit (self, signals[SIGNAL_EXITED], 0); } } @@ -967,8 +994,14 @@ tp_connection_manager_name_owner_changed_cb (TpDBusDaemon *bus, /* represent an atomic change of ownership as if it was an exit and * restart */ if (self->running) - tp_connection_manager_name_owner_changed_cb (bus, name, "", self); + { + DEBUG ("%s: atomic name owner change, behaving as if it exited", + self->name); + tp_connection_manager_name_owner_changed_cb (bus, name, "", self); + DEBUG ("%s: back to normal handling", self->name); + } + DEBUG ("%s: is now running", self->name); self->running = TRUE; g_signal_emit (self, signals[SIGNAL_ACTIVATED], 0); @@ -980,6 +1013,9 @@ tp_connection_manager_name_owner_changed_cb (TpDBusDaemon *bus, /* if we haven't started introspecting yet, now would be a good time */ if (!self->priv->name_known) { + DEBUG ("%s: starting introspection now we know the name owner", + self->name); + g_assert (self->priv->manager_file_read_idle_id == 0); /* now we know whether we're running or not, we can try reading the @@ -989,6 +1025,9 @@ tp_connection_manager_name_owner_changed_cb (TpDBusDaemon *bus, if (self->priv->want_activation && self->priv->introspect_idle_id == 0) { + DEBUG ("%s: forcing introspection for its side-effect of " + "activation", + self->name); /* ... but if activation was requested, we should also do that */ self->priv->introspect_idle_id = g_idle_add ( tp_connection_manager_idle_introspect, self); @@ -1087,14 +1126,16 @@ tp_connection_manager_idle_read_manager_file (gpointer data) GHashTable *protocols; GStrv interfaces = NULL; - DEBUG ("Reading %s", self->priv->manager_file); + DEBUG ("%s: reading %s", self->name, self->priv->manager_file); if (!tp_connection_manager_read_file ( tp_proxy_get_dbus_daemon (self), self->name, self->priv->manager_file, &protocols, &interfaces, &error)) { - DEBUG ("Failed to load %s: %s", self->priv->manager_file, + DEBUG ("%s: failed to load %s: %s #%d: %s", + self->name, self->priv->manager_file, + g_quark_to_string (error->domain), error->code, error->message); g_error_free (error); error = NULL; @@ -1108,7 +1149,7 @@ tp_connection_manager_idle_read_manager_file (gpointer data) self->priv->protocol_objects = protocols; tp_connection_manager_update_protocol_structs (self); - DEBUG ("Got info from file"); + DEBUG ("%s: got info from file", self->name); /* previously it must have been NONE */ self->info_source = TP_CM_INFO_SOURCE_FILE; @@ -1126,15 +1167,21 @@ tp_connection_manager_idle_read_manager_file (gpointer data) if (self->priv->introspect_idle_id == 0) { - DEBUG ("no .manager file or failed to parse it, trying to activate " - "CM instead"); + DEBUG ("%s: no .manager file or failed to parse it, trying to " + "activate CM instead", + self->name); tp_connection_manager_idle_introspect (self); } else { - DEBUG ("no .manager file, but will activate CM soon anyway"); + DEBUG ("%s: no .manager file, but will activate CM soon anyway", + self->name); } - /* else we're going to introspect soon anyway */ + } + else + { + DEBUG ("%s: not reading manager file, %u protocols already discovered", + self->name, g_hash_table_size (self->priv->protocol_objects)); } out: @@ -1653,18 +1700,26 @@ tp_connection_manager_activate (TpConnectionManager *self) { if (self->running) { - DEBUG ("already running"); + DEBUG ("%s: already running", self->name); return FALSE; } if (self->priv->introspect_idle_id == 0) - self->priv->introspect_idle_id = g_idle_add ( - tp_connection_manager_idle_introspect, self); + { + DEBUG ("%s: adding idle introspection", self->name); + self->priv->introspect_idle_id = g_idle_add ( + tp_connection_manager_idle_introspect, self); + } + else + { + DEBUG ("%s: idle introspection already added", self->name); + } } else { /* we'll activate later, when we know properly whether we're running */ - DEBUG ("queueing activation for when we know what's going on"); + DEBUG ("%s: queueing activation for when we know what's going on", + self->name); self->priv->want_activation = TRUE; } diff --git a/telepathy-glib/connection.c b/telepathy-glib/connection.c index b02d7e248..cc648add1 100644 --- a/telepathy-glib/connection.c +++ b/telepathy-glib/connection.c @@ -61,13 +61,17 @@ * #TpConnection objects represent Telepathy instant messaging connections * accessed via D-Bus. * - * Compared with a simple proxy for method calls, they add the following - * features: - * - * <itemizedlist> - * <listitem>connection status tracking</listitem> - * <listitem>calling GetInterfaces() automatically</listitem> - * </itemizedlist> + * #TpConnection objects should be obtained from a #TpAccount, unless you + * are implementing a lower-level Telepathy component (such as the account + * manager service itself). + * + * Since 0.16, #TpConnection always has a non-%NULL #TpProxy:factory, and its + * #TpProxy:factory will be propagated to its #TpChannel objects + * (if any). Similarly, the #TpProxy:factory<!-- -->'s features + * will be used for #TpContact objects. + * If a #TpConnection is created without going via the + * #TpAccount or specifying a #TpProxy:factory, the default + * is to use a new #TpAutomaticClientFactory. * * Since: 0.7.1 */ @@ -140,8 +144,12 @@ tp_connection_get_feature_quark_core (void) * <title>Someone still has to call Connect()</title> * <para>Requesting this feature via tp_proxy_prepare_async() means that * you want to wait for the connection to connect, but it doesn't actually - * start the process of connecting: to do that, call - * tp_cli_connection_call_connect() separately.</para> + * start the process of connecting. For connections associated with + * a #TpAccount, the account manager service is responsible for + * doing that, but if you are constructing connections directly + * (e.g. if you are implementing an account manager), you must + * tp_cli_connection_call_connect() separately. + * </para> * </note> * * One can ask for a feature to be prepared using the @@ -1310,6 +1318,8 @@ tp_connection_invalidated (TpConnection *self) * refcycle completely. */ if (self->priv->roster != NULL) g_hash_table_remove_all (self->priv->roster); + g_clear_object (&self->priv->self_contact); + tp_clear_pointer (&self->priv->blocked_contacts, g_ptr_array_unref); } static gboolean @@ -1631,6 +1641,7 @@ tp_connection_dispose (GObject *object) } tp_clear_pointer (&self->priv->blocked_contacts, g_ptr_array_unref); + g_clear_object (&self->priv->self_contact); ((GObjectClass *) tp_connection_parent_class)->dispose (object); } diff --git a/telepathy-glib/contact.c b/telepathy-glib/contact.c index c505bc846..4a77f1137 100644 --- a/telepathy-glib/contact.c +++ b/telepathy-glib/contact.c @@ -40,6 +40,15 @@ #include "telepathy-glib/util-internal.h" #include "telepathy-glib/variant-util-internal.h" +static const gchar * +nonnull (const gchar *s) +{ + if (s == NULL) + return "(null)"; + + return s; +} + /** * SECTION:contact * @title: TpContact @@ -2755,6 +2764,119 @@ out: static void contact_set_avatar_token (TpContact *self, const gchar *new_token, gboolean request); +typedef struct { + GWeakRef contact; + TpConnection *connection; + gchar *token; + GFile *file; + GBytes *data; + GFile *mime_file; + gchar *mime_type; +} WriteAvatarData; + +static void +write_avatar_data_free (WriteAvatarData *avatar_data) +{ + g_weak_ref_clear (&avatar_data->contact); + g_clear_object (&avatar_data->connection); + tp_clear_pointer (&avatar_data->token, g_free); + g_clear_object (&avatar_data->file); + tp_clear_pointer (&avatar_data->data, g_bytes_unref); + g_clear_object (&avatar_data->mime_file); + tp_clear_pointer (&avatar_data->mime_type, g_free); + + g_slice_free (WriteAvatarData, avatar_data); +} + +static void +mime_file_written (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + WriteAvatarData *avatar_data = user_data; + GFile *file = G_FILE (source_object); + TpContact *self; + + g_assert (file == avatar_data->mime_file); + + if (!g_file_replace_contents_finish (file, res, NULL, &error)) + { + DEBUG ("Failed to store MIME type in cache (%s): %s", + g_file_get_path (file), error->message); + g_clear_error (&error); + } + else + { + DEBUG ("Contact avatar MIME type stored in cache: %s", + g_file_get_path (file)); + } + + self = g_weak_ref_get (&avatar_data->contact); + + if (self == NULL) + { + DEBUG ("No relevant TpContact"); + } + else if (tp_strdiff (avatar_data->token, self->priv->avatar_token)) + { + DEBUG ("Contact's avatar token has changed from %s to %s, " + "this avatar is no longer relevant", + avatar_data->token, nonnull (self->priv->avatar_token)); + } + else + { + DEBUG ("Saved avatar '%s' of MIME type '%s' still used by '%s' to '%s'", + avatar_data->token, avatar_data->mime_type, + self->priv->identifier, + g_file_get_path (avatar_data->file)); + g_clear_object (&self->priv->avatar_file); + self->priv->avatar_file = g_object_ref (avatar_data->file); + + g_free (self->priv->avatar_mime_type); + self->priv->avatar_mime_type = g_strdup (avatar_data->mime_type); + + /* Notify both property changes together once both files have been + * written */ + g_object_notify ((GObject *) self, "avatar-mime-type"); + g_object_notify ((GObject *) self, "avatar-file"); + + g_object_unref (self); + } + + write_avatar_data_free (avatar_data); +} + +static void +avatar_file_written (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + WriteAvatarData *avatar_data = user_data; + GFile *file = G_FILE (source_object); + + g_assert (file == avatar_data->file); + + if (!g_file_replace_contents_finish (file, res, NULL, &error)) + { + DEBUG ("Failed to store avatar in cache (%s): %s", + g_file_get_path (file), error->message); + DEBUG ("Storing the MIME type anyway"); + g_clear_error (&error); + } + else + { + DEBUG ("Contact avatar stored in cache: %s", + g_file_get_path (file)); + } + + g_file_replace_contents_async (avatar_data->mime_file, + avatar_data->mime_type, strlen (avatar_data->mime_type), + NULL, FALSE, G_FILE_CREATE_PRIVATE|G_FILE_CREATE_REPLACE_DESTINATION, + NULL, mime_file_written, avatar_data); +} + static void contact_avatar_retrieved (TpConnection *connection, guint handle, @@ -2767,7 +2889,14 @@ contact_avatar_retrieved (TpConnection *connection, TpContact *self = _tp_connection_lookup_contact (connection, handle); gchar *filename; gchar *mime_filename; - GError *error = NULL; + WriteAvatarData *avatar_data; + + if (self != NULL) + { + /* Update the avatar token if a newer one is given + * (this emits notify::avatar-token if needed) */ + contact_set_avatar_token (self, token, FALSE); + } if (!build_avatar_filename (connection, token, TRUE, &filename, &mime_filename)) @@ -2775,40 +2904,23 @@ contact_avatar_retrieved (TpConnection *connection, /* Save avatar in cache, even if the contact is unknown, to avoid as much as * possible future avatar requests */ - if (!g_file_set_contents (filename, avatar->data, avatar->len, &error)) - { - DEBUG ("Failed to store avatar in cache (%s): %s", filename, - error ? error->message : "No error message"); - g_clear_error (&error); - goto out; - } - if (!g_file_set_contents (mime_filename, mime_type, -1, &error)) - { - DEBUG ("Failed to store MIME type in cache (%s): %s", mime_filename, - error ? error->message : "No error message"); - g_clear_error (&error); - goto out; - } + avatar_data = g_slice_new0 (WriteAvatarData); + avatar_data->connection = g_object_ref (connection); + g_weak_ref_set (&avatar_data->contact, self); + avatar_data->token = g_strdup (token); + avatar_data->file = g_file_new_for_path (filename); + /* g_file_replace_contents_async() doesn't copy its argument, see + * <https://bugzilla.gnome.org/show_bug.cgi?id=690525>, so we have + * to keep a copy around */ + avatar_data->data = g_bytes_new (avatar->data, avatar->len); + avatar_data->mime_file = g_file_new_for_path (mime_filename); + avatar_data->mime_type = g_strdup (mime_type); + + g_file_replace_contents_async (avatar_data->file, + g_bytes_get_data (avatar_data->data, NULL), avatar->len, + NULL, FALSE, G_FILE_CREATE_PRIVATE|G_FILE_CREATE_REPLACE_DESTINATION, + NULL, avatar_file_written, avatar_data); - DEBUG ("Contact#%u avatar stored in cache: %s, %s", handle, filename, - mime_type); - - if (self == NULL) - goto out; - - /* Update the avatar token if a newer one is given */ - contact_set_avatar_token (self, token, FALSE); - - tp_clear_object (&self->priv->avatar_file); - self->priv->avatar_file = g_file_new_for_path (filename); - - g_free (self->priv->avatar_mime_type); - self->priv->avatar_mime_type = g_strdup (mime_type); - - g_object_notify ((GObject *) self, "avatar-file"); - g_object_notify ((GObject *) self, "avatar-mime-type"); - -out: g_free (filename); g_free (mime_filename); } diff --git a/telepathy-glib/dbus-properties-mixin-internal.h b/telepathy-glib/dbus-properties-mixin-internal.h deleted file mode 100644 index 344d15174..000000000 --- a/telepathy-glib/dbus-properties-mixin-internal.h +++ /dev/null @@ -1,34 +0,0 @@ -/*<private_header>*/ -/* - * dbus-properties-mixin-internal.h - D-Bus core Properties - internal API - * Copyright (C) 2008-2012 Collabora Ltd. - * Copyright (C) 2008 Nokia Corporation - * - * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __TP_DBUS_PROPERTIES_MIXIN_INTERNAL_H__ -#define __TP_DBUS_PROPERTIES_MIXIN_INTERNAL_H__ - -#include <telepathy-glib/dbus-properties-mixin.h> - -G_BEGIN_DECLS - -GHashTable *_tp_dbus_properties_mixin_get_all (GObject *self, - const gchar *interface_name); - -G_END_DECLS - -#endif /* #ifndef __TP_DBUS_PROPERTIES_MIXIN_H__ */ diff --git a/telepathy-glib/dbus-properties-mixin.c b/telepathy-glib/dbus-properties-mixin.c index 6e26ab23d..fb9f7c858 100644 --- a/telepathy-glib/dbus-properties-mixin.c +++ b/telepathy-glib/dbus-properties-mixin.c @@ -21,7 +21,6 @@ #include "config.h" #include <telepathy-glib/dbus-properties-mixin.h> -#include "telepathy-glib/dbus-properties-mixin-internal.h" #include <telepathy-glib/errors.h> #include <telepathy-glib/svc-generic.h> @@ -1148,8 +1147,8 @@ _tp_dbus_properties_mixin_get (TpSvcDBusProperties *iface, } } -/* - * _tp_dbus_properties_mixin_get_all: +/** + * tp_dbus_properties_mixin_dup_all: * @self: an object with this mixin * @interface_name: a D-Bus interface name * @@ -1159,9 +1158,10 @@ _tp_dbus_properties_mixin_get (TpSvcDBusProperties *iface, * * Returns: (transfer container) (element-type utf8 GObject.Value): a map * from property name (without the interface name) to value + * Since: 0.21.2 */ GHashTable * -_tp_dbus_properties_mixin_get_all (GObject *self, +tp_dbus_properties_mixin_dup_all (GObject *self, const gchar *interface_name) { TpDBusPropertiesMixinIfaceImpl *iface_impl; @@ -1203,7 +1203,7 @@ _tp_dbus_properties_mixin_get_all_dbus (TpSvcDBusProperties *iface, const gchar *interface_name, DBusGMethodInvocation *context) { - GHashTable *values = _tp_dbus_properties_mixin_get_all (G_OBJECT (iface), + GHashTable *values = tp_dbus_properties_mixin_dup_all (G_OBJECT (iface), interface_name); tp_svc_dbus_properties_return_from_get_all (context, values); diff --git a/telepathy-glib/dbus-properties-mixin.h b/telepathy-glib/dbus-properties-mixin.h index dff7271f5..1151cb519 100644 --- a/telepathy-glib/dbus-properties-mixin.h +++ b/telepathy-glib/dbus-properties-mixin.h @@ -138,6 +138,10 @@ gboolean tp_dbus_properties_mixin_set ( const GValue *value, GError **error); +_TP_AVAILABLE_IN_0_22 +GHashTable *tp_dbus_properties_mixin_dup_all (GObject *self, + const gchar *interface_name); + GHashTable *tp_dbus_properties_mixin_make_properties_hash ( GObject *object, const gchar *first_interface, const gchar *first_property, ...) diff --git a/telepathy-glib/defs.h b/telepathy-glib/defs.h index d7a36c66a..80d24c113 100644 --- a/telepathy-glib/defs.h +++ b/telepathy-glib/defs.h @@ -159,6 +159,7 @@ G_BEGIN_DECLS #define TP_VERSION_0_16 (_TP_ENCODE_VERSION (0, 16)) #define TP_VERSION_0_18 (_TP_ENCODE_VERSION (0, 18)) #define TP_VERSION_0_20 (_TP_ENCODE_VERSION (0, 20)) +#define TP_VERSION_0_22 (_TP_ENCODE_VERSION (0, 22)) #define TP_VERSION_1_0 (_TP_ENCODE_VERSION (1, 0)) #if (TP_MINOR_VERSION == 99) @@ -220,6 +221,14 @@ G_BEGIN_DECLS # define _TP_DEPRECATED_IN_0_20_FOR(f) /* nothing */ #endif +#if TP_VERSION_MIN_REQUIRED >= TP_VERSION_0_22 +# define _TP_DEPRECATED_IN_0_22 _TP_DEPRECATED +# define _TP_DEPRECATED_IN_0_22_FOR(f) _TP_DEPRECATED_FOR(f) +#else +# define _TP_DEPRECATED_IN_0_22 /* nothing */ +# define _TP_DEPRECATED_IN_0_22_FOR(f) /* nothing */ +#endif + #if TP_VERSION_MIN_REQUIRED >= TP_VERSION_1_0 # define _TP_DEPRECATED_IN_1_0 _TP_DEPRECATED # define _TP_DEPRECATED_IN_1_0_FOR(f) _TP_DEPRECATED_FOR(f) @@ -254,6 +263,12 @@ G_BEGIN_DECLS # define _TP_AVAILABLE_IN_0_20 /* nothing */ #endif +#if TP_VERSION_MAX_ALLOWED < TP_VERSION_0_22 +# define _TP_AVAILABLE_IN_0_22 _TP_UNAVAILABLE(0, 22) +#else +# define _TP_AVAILABLE_IN_0_22 /* nothing */ +#endif + #if TP_VERSION_MAX_ALLOWED < TP_VERSION_1_0 # define _TP_AVAILABLE_IN_1_0 _TP_UNAVAILABLE(1, 0) #else diff --git a/telepathy-glib/extra-gtkdoc.h b/telepathy-glib/extra-gtkdoc.h index 6492ecdfa..6731a95e5 100644 --- a/telepathy-glib/extra-gtkdoc.h +++ b/telepathy-glib/extra-gtkdoc.h @@ -464,6 +464,13 @@ */ /** + * TP_VERSION_0_22: (skip) + * + * A constant representing the telepathy-glib 0.22 stable branch, + * and the 0.21 development branch that led to it. + */ + +/** * TP_VERSION_1_0: (skip) * * A constant representing the telepathy-glib 1.0 stable branch, diff --git a/telepathy-glib/group-mixin.c b/telepathy-glib/group-mixin.c index 56873420b..5907d74b7 100644 --- a/telepathy-glib/group-mixin.c +++ b/telepathy-glib/group-mixin.c @@ -1247,13 +1247,11 @@ tp_group_mixin_change_flags (GObject *obj, str_removed = group_flags_to_string (removed); str_flags = group_flags_to_string (mixin->group_flags); - printf ("%s: emitting group flags changed\n" + DEBUG ("emitting group flags changed\n" " added : %s\n" " removed : %s\n" " flags now: %s\n", - G_STRFUNC, str_added, str_removed, str_flags); - - fflush (stdout); + str_added, str_removed, str_flags); g_free (str_added); g_free (str_removed); @@ -1454,7 +1452,7 @@ emit_members_changed_signals (GObject *channel, local_str = member_array_to_string (mixin->handle_repo, local_pending); remote_str = member_array_to_string (mixin->handle_repo, remote_pending); - printf ("%s: emitting members changed\n" + DEBUG ("emitting members changed\n" " message : \"%s\"\n" " added : %s\n" " removed : %s\n" @@ -1462,11 +1460,9 @@ emit_members_changed_signals (GObject *channel, " remote_pending: %s\n" " actor : %u\n" " reason : %u: %s\n", - G_STRFUNC, message, add_str, rem_str, local_str, remote_str, + message, add_str, rem_str, local_str, remote_str, actor, reason, group_change_reason_str (reason)); - fflush (stdout); - g_free (add_str); g_free (rem_str); g_free (local_str); diff --git a/telepathy-glib/introspection.am b/telepathy-glib/introspection.am index 4789942ec..ad23841f8 100644 --- a/telepathy-glib/introspection.am +++ b/telepathy-glib/introspection.am @@ -87,7 +87,9 @@ TelepathyGLib_0_12_gir_FILES = \ TelepathyGLib_0_12_gir_NAMESPACE = TelepathyGLib TelepathyGLib_0_12_gir_VERSION = 0.12 TelepathyGLib_0_12_gir_LIBS = libtelepathy-glib.la -TelepathyGLib_0_12_gir_CFLAGS = -D_TP_COMPILATION +# g-ir-scanner picks up CFLAGS from the environment, but not CPPFLAGS. +# We don't want to give it our AM_CFLAGS, which include extra warnings. +TelepathyGLib_0_12_gir_CFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) TelepathyGLib_0_12_gir_EXPORT_PACKAGES = telepathy-glib TelepathyGLib_0_12_gir_SCANNERFLAGS = \ @@ -110,7 +112,7 @@ TelepathyGLib_0_12_gir_PACKAGES = \ $(NULL) _gen/proxy-introspectable.h: proxy.h introspection.am - @$(mkdir_p) _gen + @$(MKDIR_P) _gen $(AM_V_GEN)sed -e 's/gpointer self/TpProxy *self/' < $< > $@ girdir = $(datadir)/gir-1.0 diff --git a/telepathy-glib/properties-mixin.c b/telepathy-glib/properties-mixin.c index 16160067b..c3dbc189f 100644 --- a/telepathy-glib/properties-mixin.c +++ b/telepathy-glib/properties-mixin.c @@ -891,9 +891,8 @@ tp_properties_mixin_emit_changed (GObject *obj, const TpIntset *props) prop_arr = g_ptr_array_sized_new (len); - if (DEBUGGING) - printf ("%s: emitting properties changed for propert%s:\n", - G_STRFUNC, (len > 1) ? "ies" : "y"); + DEBUG ("emitting properties changed for propert%s:\n", + (len > 1) ? "ies" : "y"); tp_intset_fast_iter_init (&iter, props); @@ -912,13 +911,7 @@ tp_properties_mixin_emit_changed (GObject *obj, const TpIntset *props) g_ptr_array_add (prop_arr, g_value_get_boxed (&prop_val)); - if (DEBUGGING) - printf (" %s\n", mixin_cls->signatures[prop_id].name); - } - - if (DEBUGGING) - { - fflush (stdout); + DEBUG (" %s\n", mixin_cls->signatures[prop_id].name); } tp_svc_properties_interface_emit_properties_changed ( @@ -958,9 +951,8 @@ tp_properties_mixin_emit_flags (GObject *obj, const TpIntset *props) prop_arr = g_ptr_array_sized_new (len); - if (DEBUGGING) - printf ("%s: emitting properties flags changed for propert%s:\n", - G_STRFUNC, (len > 1) ? "ies" : "y"); + DEBUG ("emitting properties flags changed for propert%s:\n", + (len > 1) ? "ies" : "y"); tp_intset_fast_iter_init (&iter, props); @@ -987,18 +979,13 @@ tp_properties_mixin_emit_flags (GObject *obj, const TpIntset *props) { gchar *str_flags = property_flags_to_string (prop_flags); - printf (" %s's flags now: %s\n", + DEBUG (" %s's flags now: %s\n", mixin_cls->signatures[prop_id].name, str_flags); g_free (str_flags); } } - if (DEBUGGING) - { - fflush (stdout); - } - tp_svc_properties_interface_emit_property_flags_changed ( (TpSvcPropertiesInterface *) obj, prop_arr); diff --git a/telepathy-glib/protocol.c b/telepathy-glib/protocol.c index 919b4a6b5..b2935c042 100644 --- a/telepathy-glib/protocol.c +++ b/telepathy-glib/protocol.c @@ -411,15 +411,22 @@ tp_protocol_check_for_core (TpProtocol *self) value = tp_asv_lookup (props, TP_PROP_PROTOCOL_CONNECTION_INTERFACES); if (value == NULL || !G_VALUE_HOLDS (value, G_TYPE_STRV)) - return FALSE; + { + DEBUG ("Interfaces not found"); + return FALSE; + } if (tp_asv_get_boxed (props, TP_PROP_PROTOCOL_REQUESTABLE_CHANNEL_CLASSES, TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST) == NULL) - return FALSE; + { + DEBUG ("Requestable channel classes not found"); + return FALSE; + } /* Interfaces has a sensible default, the empty list. * VCardField, EnglishName and Icon have a sensible default, "". */ + DEBUG ("Core feature ready"); return TRUE; } @@ -464,12 +471,20 @@ tp_protocol_constructed (GObject *object) g_assert (self->priv->protocol_struct.name != NULL); + DEBUG ("%s/%s: new Protocol", self->priv->cm_name, + self->priv->protocol_struct.name); + if (self->priv->protocol_properties == NULL) { + DEBUG ("immutable properties not supplied"); had_immutables = FALSE; self->priv->protocol_properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) tp_g_value_slice_free); } + else + { + DEBUG ("immutable properties already supplied"); + } self->priv->protocol_struct.params = tp_protocol_params_from_param_specs ( tp_asv_get_boxed (self->priv->protocol_properties, @@ -1267,7 +1282,7 @@ parse_default_value (GValue *value, case 'u': case 't': { - guint64 v = tp_g_key_file_get_uint64 (file, group, key, &error); + guint64 v = g_key_file_get_uint64 (file, group, key, &error); if (error != NULL) { @@ -1308,7 +1323,7 @@ parse_default_value (GValue *value, } else { - gint64 v = tp_g_key_file_get_int64 (file, group, key, &error); + gint64 v = g_key_file_get_int64 (file, group, key, &error); if (error != NULL) { @@ -1529,10 +1544,12 @@ _tp_protocol_parse_manager_file (GKeyFile *file, if (!tp_connection_manager_check_valid_protocol_name (name, NULL)) { - DEBUG ("Protocol '%s' has an invalid name", name); + DEBUG ("%s: protocol '%s' has an invalid name", cm_debug_name, name); return NULL; } + DEBUG ("%s: reading protocol '%s' from manager file", cm_debug_name, name); + keys = g_key_file_get_keys (file, group, NULL, NULL); i = 0; diff --git a/telepathy-glib/simple-client-factory.c b/telepathy-glib/simple-client-factory.c index 34ad54c44..c096ea040 100644 --- a/telepathy-glib/simple-client-factory.c +++ b/telepathy-glib/simple-client-factory.c @@ -36,7 +36,8 @@ * * Currently supported classes are #TpAccount, #TpConnection, * #TpChannel and #TpContact. Those objects should always be acquired through a - * factory, rather than being constructed directly. + * factory or a "larger" object (e.g. getting the #TpConnection from + * a #TpAccount), rather than being constructed directly. * * One can subclass #TpSimpleClientFactory and override some of its virtual * methods to construct more specialized objects. See #TpAutomaticClientFactory @@ -451,6 +452,10 @@ tp_simple_client_factory_get_dbus_daemon (TpSimpleClientFactory *self) * is responsible for calling tp_proxy_prepare_async() with the desired * features (as given by tp_simple_client_factory_dup_account_features()). * + * This function is rather low-level. tp_account_manager_dup_valid_accounts() + * and #TpAccountManager::validity-changed are more appropriate for most + * applications. + * * Returns: (transfer full): a reference to a #TpAccount; * see tp_account_new(). * @@ -576,6 +581,9 @@ tp_simple_client_factory_add_account_features_varargs ( * caller is responsible for calling tp_proxy_prepare_async() with the desired * features (as given by tp_simple_client_factory_dup_connection_features()). * + * This function is rather low-level. #TpAccount:connection is more + * appropriate for most applications. + * * Returns: (transfer full): a reference to a #TpConnection; * see tp_connection_new(). * @@ -687,7 +695,7 @@ tp_simple_client_factory_add_connection_features_varargs ( /** * tp_simple_client_factory_ensure_channel: * @self: a #TpSimpleClientFactory object - * @connection: a #TpConnection + * @connection: a #TpConnection whose #TpProxy:factory is this object * @object_path: the object path of a channel on @connection * @immutable_properties: (transfer none) (element-type utf8 GObject.Value): * the immutable properties of the channel @@ -702,6 +710,10 @@ tp_simple_client_factory_add_connection_features_varargs ( * caller is responsible for calling tp_proxy_prepare_async() with the desired * features (as given by tp_simple_client_factory_dup_channel_features()). * + * This function is rather low-level. + * #TpAccountChannelRequest and #TpBaseClient are more appropriate ways + * to obtain channels for most applications. + * * Returns: (transfer full): a reference to a #TpChannel; * see tp_channel_new_from_properties(). * @@ -816,7 +828,7 @@ tp_simple_client_factory_add_channel_features_varargs ( /** * tp_simple_client_factory_ensure_contact: * @self: a #TpSimpleClientFactory object - * @connection: a #TpConnection + * @connection: a #TpConnection whose #TpProxy:factory is this object * @handle: a #TpHandle * @identifier: a string representing the contact's identifier * @@ -892,7 +904,7 @@ upgrade_contacts_cb (GObject *source, /** * tp_simple_client_factory_upgrade_contacts_async: * @self: a #TpSimpleClientFactory object - * @connection: a #TpConnection + * @connection: a #TpConnection whose #TpProxy:factory is this object * @n_contacts: The number of contacts in @contacts (must be at least 1) * @contacts: (array length=n_contacts): An array of #TpContact objects * associated with @self @@ -917,6 +929,10 @@ tp_simple_client_factory_upgrade_contacts_async ( GSimpleAsyncResult *result; GArray *features; + /* no real reason this shouldn't work, but it's really confusing + * and probably indicates an error */ + g_warn_if_fail (tp_proxy_get_factory (connection) == self); + result = g_simple_async_result_new ((GObject *) self, callback, user_data, tp_simple_client_factory_upgrade_contacts_async); @@ -1142,8 +1158,8 @@ tp_simple_client_factory_add_contact_features_varargs ( va_end (var_args); } -/** - * tp_simple_client_factory_ensure_channel_request: +/* + * _tp_simple_client_factory_ensure_channel_request: * @self: a #TpSimpleClientFactory object * @object_path: the object path of a channel request * @immutable_properties: (transfer none) (element-type utf8 GObject.Value): @@ -1194,8 +1210,8 @@ _tp_simple_client_factory_ensure_channel_request (TpSimpleClientFactory *self, return request; } -/** - * tp_simple_client_factory_ensure_channel_dispatch_operation: +/* + * _tp_simple_client_factory_ensure_channel_dispatch_operation: * @self: a #TpSimpleClientFactory object * @object_path: the object path of a channel dispatch operation * @immutable_properties: (transfer none) (element-type utf8 GObject.Value): diff --git a/telepathy-glib/stream-tube-channel.c b/telepathy-glib/stream-tube-channel.c index 607abad54..8a110d756 100644 --- a/telepathy-glib/stream-tube-channel.c +++ b/telepathy-glib/stream-tube-channel.c @@ -145,6 +145,7 @@ struct _TpStreamTubeChannelPrivate /* Offering side */ GSocketService *service; GSocketAddress *address; + gchar *unix_tmpdir; /* GSocketConnection we have accepted but are still waiting a * NewRemoteConnection to identify them. Owned ConnWaitingSig. */ GSList *conn_waiting_sig; @@ -266,6 +267,13 @@ tp_stream_tube_channel_dispose (GObject *obj) self->priv->address = NULL; } + if (self->priv->unix_tmpdir != NULL) + { + g_rmdir (self->priv->unix_tmpdir); + g_free (self->priv->unix_tmpdir); + self->priv->unix_tmpdir = NULL; + } + tp_clear_pointer (&self->priv->access_control_param, tp_g_value_slice_free); tp_clear_object (&self->priv->local_conn_waiting_id); tp_clear_object (&self->priv->client_socket); @@ -1466,7 +1474,7 @@ tp_stream_tube_channel_offer_async (TpStreamTubeChannel *self, case TP_SOCKET_ADDRESS_TYPE_UNIX: { self->priv->address = _tp_create_temp_unix_socket ( - self->priv->service, &error); + self->priv->service, &self->priv->unix_tmpdir, &error); /* check there wasn't an error on the final attempt */ if (self->priv->address == NULL) diff --git a/telepathy-glib/telepathy-glib-uninstalled.pc.in b/telepathy-glib/telepathy-glib-uninstalled.pc.in index 932983c77..3dbefb29b 100644 --- a/telepathy-glib/telepathy-glib-uninstalled.pc.in +++ b/telepathy-glib/telepathy-glib-uninstalled.pc.in @@ -6,7 +6,6 @@ abs_top_builddir=@abs_top_builddir@ Name: Telepathy-GLib (uninstalled copy) Description: GLib utility library for the Telepathy framework Version: @VERSION@ -Requires: pkg-config >= 0.21 Requires.private: dbus-1 >= 0.95, dbus-glib-1 >= 0.90, glib-2.0 >= 2.30, gobject-2.0 >= 2.30, gio-2.0 >= 2.30 Libs: ${abs_top_builddir}/telepathy-glib/libtelepathy-glib.la Cflags: -I${abs_top_srcdir} -I${abs_top_builddir} diff --git a/telepathy-glib/telepathy-glib.pc.in b/telepathy-glib/telepathy-glib.pc.in index 1c5f4b637..75ac275b6 100644 --- a/telepathy-glib/telepathy-glib.pc.in +++ b/telepathy-glib/telepathy-glib.pc.in @@ -6,7 +6,6 @@ includedir=@includedir@ Name: Telepathy-GLib Description: GLib utility library for the Telepathy framework Version: @VERSION@ -Requires: pkg-config >= 0.21 Requires.private: dbus-1 >= 0.95, dbus-glib-1 >= 0.90, glib-2.0 >= 2.30, gobject-2.0 >= 2.30, gio-2.0 >= 2.30 Libs: -L${libdir} -ltelepathy-glib Cflags: -I${includedir}/telepathy-1.0 diff --git a/telepathy-glib/text-channel.c b/telepathy-glib/text-channel.c index 683f80260..87890a746 100644 --- a/telepathy-glib/text-channel.c +++ b/telepathy-glib/text-channel.c @@ -720,7 +720,7 @@ get_pending_messages_cb (TpProxy *proxy, } static void -tp_text_channel_prepare_pending_messages_async (TpProxy *proxy, +tp_text_channel_prepare_incoming_messages_async (TpProxy *proxy, const TpProxyFeature *feature, GAsyncReadyCallback callback, gpointer user_data) @@ -751,7 +751,7 @@ tp_text_channel_prepare_pending_messages_async (TpProxy *proxy, g_assert (self->priv->pending_messages_result == NULL); self->priv->pending_messages_result = g_simple_async_result_new ( (GObject *) proxy, callback, user_data, - tp_text_channel_prepare_pending_messages_async); + tp_text_channel_prepare_incoming_messages_async); tp_cli_dbus_properties_call_get (proxy, -1, @@ -842,7 +842,7 @@ tp_text_channel_prepare_sms_async (TpProxy *proxy, } enum { - FEAT_PENDING_MESSAGES, + FEAT_INCOMING_MESSAGES, FEAT_SMS, FEAT_CHAT_STATES, N_FEAT @@ -858,10 +858,10 @@ tp_text_channel_list_features (TpProxyClass *cls G_GNUC_UNUSED) if (G_LIKELY (features[0].name != 0)) return features; - features[FEAT_PENDING_MESSAGES].name = + features[FEAT_INCOMING_MESSAGES].name = TP_TEXT_CHANNEL_FEATURE_INCOMING_MESSAGES; - features[FEAT_PENDING_MESSAGES].prepare_async = - tp_text_channel_prepare_pending_messages_async; + features[FEAT_INCOMING_MESSAGES].prepare_async = + tp_text_channel_prepare_incoming_messages_async; features[FEAT_SMS].name = TP_TEXT_CHANNEL_FEATURE_SMS; diff --git a/telepathy-glib/util-internal.h b/telepathy-glib/util-internal.h index 941064832..bf15a0a9a 100644 --- a/telepathy-glib/util-internal.h +++ b/telepathy-glib/util-internal.h @@ -39,6 +39,7 @@ void _tp_quark_array_merge_valist (GArray *array, #ifdef HAVE_GIO_UNIX GSocketAddress * _tp_create_temp_unix_socket (GSocketService *service, + gchar **tmpdir, GError **error); #endif /* HAVE_GIO_UNIX */ @@ -49,6 +50,7 @@ GList * _tp_create_channel_request_list (TpSimpleClientFactory *factory, gboolean _tp_enum_from_nick (GType enum_type, const gchar *nick, gint *value); const gchar *_tp_enum_to_nick (GType enum_type, gint value); +const gchar *_tp_enum_to_nick_nonnull (GType enum_type, gint value); #define _tp_implement_finish_void(source, tag) \ if (g_simple_async_result_propagate_error (\ diff --git a/telepathy-glib/util.c b/telepathy-glib/util.c index 4d606d158..e01dd2291 100644 --- a/telepathy-glib/util.c +++ b/telepathy-glib/util.c @@ -31,6 +31,7 @@ #include "config.h" +#include <glib/gstdio.h> #include <gobject/gvaluecollector.h> #ifdef HAVE_GIO_UNIX @@ -43,6 +44,7 @@ #include <telepathy-glib/util-internal.h> #include <telepathy-glib/util.h> +#include <errno.h> #include <stdio.h> #include <string.h> @@ -829,6 +831,7 @@ tp_strv_contains (const gchar * const *strv, * 0 if the key was not found or could not be parsed. * * Since: 0.7.31 + * Deprecated: Since 0.21.0. Use g_key_file_get_int64() instead. */ gint64 tp_g_key_file_get_int64 (GKeyFile *key_file, @@ -877,6 +880,7 @@ tp_g_key_file_get_int64 (GKeyFile *key_file, * or 0 if the key was not found or could not be parsed. * * Since: 0.7.31 + * Deprecated: Since 0.21.0. Use g_key_file_get_uint64() instead. */ guint64 tp_g_key_file_get_uint64 (GKeyFile *key_file, @@ -1561,32 +1565,47 @@ _tp_quark_array_merge_valist (GArray *array, #ifdef HAVE_GIO_UNIX GSocketAddress * _tp_create_temp_unix_socket (GSocketService *service, + gchar **tmpdir, GError **error) { - guint i; GSocketAddress *address; + gchar *dir = g_dir_make_tmp ("tp-glib-socket.XXXXXX", error); + gchar *name; + + if (dir == NULL) + return NULL; - /* why doesn't GIO provide a method to create a socket we don't - * care about? Iterate until we find a valid temporary name. - * - * Try a maximum of 10 times to get a socket */ - for (i = 0; i < 10; i++) + if (g_chmod (dir, 0700) != 0) { - address = g_unix_socket_address_new (tmpnam (NULL)); + int e = errno; + + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (e), + "unable to set permissions of %s to 0700: %s", dir, + g_strerror (e)); + g_free (dir); + return NULL; + } - g_clear_error (error); + name = g_build_filename (dir, "s", NULL); + address = g_unix_socket_address_new (name); + g_free (name); - if (g_socket_listener_add_address ( - G_SOCKET_LISTENER (service), - address, G_SOCKET_TYPE_STREAM, - G_SOCKET_PROTOCOL_DEFAULT, - NULL, NULL, error)) - return address; - else - g_object_unref (address); + if (!g_socket_listener_add_address (G_SOCKET_LISTENER (service), + address, G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + NULL, NULL, error)) + { + g_object_unref (address); + g_free (dir); + return NULL; } - return NULL; + if (tmpdir != NULL) + *tmpdir = dir; + else + g_free (dir); + + return address; } #endif /* HAVE_GIO_UNIX */ @@ -1745,6 +1764,32 @@ _tp_enum_to_nick ( return NULL; } +/* + * _tp_enum_to_nick_nonnull: + * + * The same as _tp_enum_to_nick, but always returns non-NULL. + */ +const gchar * +_tp_enum_to_nick_nonnull ( + GType enum_type, + gint value) +{ + GEnumClass *klass = g_type_class_ref (enum_type); + GEnumValue *enum_value; + + g_return_val_if_fail (klass != NULL, "(incorrect class)"); + + enum_value = g_enum_get_value (klass, value); + g_type_class_unref (klass); + + if (enum_value == NULL) + return "(out-of-range value)"; + else if (enum_value->value_nick == NULL) + return "(value with no nickname)"; + else + return enum_value->value_nick; +} + gboolean _tp_bind_connection_status_to_boolean (GBinding *binding, const GValue *src_value, diff --git a/telepathy-glib/util.h b/telepathy-glib/util.h index 3dcf35c7f..5c5b9a036 100644 --- a/telepathy-glib/util.h +++ b/telepathy-glib/util.h @@ -29,6 +29,7 @@ #include <gio/gio.h> +#include <telepathy-glib/defs.h> #include <telepathy-glib/verify.h> #define tp_verify_statement(R) ((void) tp_verify_true (R)) @@ -75,12 +76,14 @@ GValue *tp_g_value_slice_dup (const GValue *value) G_GNUC_WARN_UNUSED_RESULT; void tp_g_hash_table_update (GHashTable *target, GHashTable *source, GBoxedCopyFunc key_dup, GBoxedCopyFunc value_dup); +/* See https://bugzilla.gnome.org/show_bug.cgi?id=399880 for glib inclusion */ static inline gboolean tp_str_empty (const gchar *s) { return (s == NULL || s[0] == '\0'); } +/* See https://bugzilla.gnome.org/show_bug.cgi?id=685878 for glib inclusion */ gboolean tp_strdiff (const gchar *left, const gchar *right); gpointer tp_mixin_offset_cast (gpointer instance, guint offset); @@ -89,13 +92,20 @@ guint tp_mixin_class_get_offset (gpointer klass, GQuark quark); gchar *tp_escape_as_identifier (const gchar *name) G_GNUC_WARN_UNUSED_RESULT; +/* See https://bugzilla.gnome.org/show_bug.cgi?id=685880 for glib inclusion */ gboolean tp_strv_contains (const gchar * const *strv, const gchar *str); +#ifndef TP_DISABLE_DEPRECATED +_TP_DEPRECATED_IN_0_22_FOR(g_key_file_get_int64) gint64 tp_g_key_file_get_int64 (GKeyFile *key_file, const gchar *group_name, const gchar *key, GError **error); +_TP_DEPRECATED_IN_0_22_FOR(g_key_file_get_uint64) guint64 tp_g_key_file_get_uint64 (GKeyFile *key_file, const gchar *group_name, const gchar *key, GError **error); +#endif +/* g_signal_connect_object() has been fixed in GLib 2.36, we can deprecate this + * once we depend on that version. */ gulong tp_g_signal_connect_object (gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer gobject, GConnectFlags connect_flags); @@ -107,6 +117,7 @@ void tp_value_array_unpack (GValueArray *array, gsize len, ...); +/* See https://bugzilla.gnome.org/show_bug.cgi?id=680813 for glib inclusion */ typedef struct _TpWeakRef TpWeakRef; TpWeakRef *tp_weak_ref_new (gpointer object, gpointer user_data, @@ -150,6 +161,7 @@ gint64 tp_user_action_time_from_x11 (guint32 x11_time); gboolean tp_user_action_time_should_present (gint64 user_action_time, guint32 *x11_time); +/* See https://bugzilla.gnome.org/show_bug.cgi?id=610969 for glib inclusion */ gchar *tp_utf8_make_valid (const gchar *name); G_END_DECLS diff --git a/telepathy-glib/versions/0.21.2.abi b/telepathy-glib/versions/0.21.2.abi new file mode 100644 index 000000000..708802727 --- /dev/null +++ b/telepathy-glib/versions/0.21.2.abi @@ -0,0 +1,7 @@ +Version: TELEPATHY_GLIB_0.21.2 +Extends: TELEPATHY_GLIB_0.19.10 +Release: 0.21.2 + +tp_cli_connection_connect_to_self_contact_changed +tp_dbus_properties_mixin_dup_all +tp_svc_connection_emit_self_contact_changed |