summaryrefslogtreecommitdiff
path: root/telepathy-glib
diff options
context:
space:
mode:
Diffstat (limited to 'telepathy-glib')
-rw-r--r--telepathy-glib/Makefile.am1
-rw-r--r--telepathy-glib/abi.am1
-rw-r--r--telepathy-glib/account-manager.c71
-rw-r--r--telepathy-glib/account.c96
-rw-r--r--telepathy-glib/base-connection.c60
-rw-r--r--telepathy-glib/base-protocol.c6
-rw-r--r--telepathy-glib/call-stream-endpoint.c2
-rw-r--r--telepathy-glib/channel-dispatch-operation.c9
-rw-r--r--telepathy-glib/channel-group.c2
-rw-r--r--telepathy-glib/channel-request.c15
-rw-r--r--telepathy-glib/codegen.am2
-rw-r--r--telepathy-glib/connection-manager.c101
-rw-r--r--telepathy-glib/connection.c29
-rw-r--r--telepathy-glib/contact.c180
-rw-r--r--telepathy-glib/dbus-properties-mixin-internal.h34
-rw-r--r--telepathy-glib/dbus-properties-mixin.c10
-rw-r--r--telepathy-glib/dbus-properties-mixin.h4
-rw-r--r--telepathy-glib/defs.h15
-rw-r--r--telepathy-glib/extra-gtkdoc.h7
-rw-r--r--telepathy-glib/group-mixin.c12
-rw-r--r--telepathy-glib/introspection.am6
-rw-r--r--telepathy-glib/properties-mixin.c25
-rw-r--r--telepathy-glib/protocol.c27
-rw-r--r--telepathy-glib/simple-client-factory.c32
-rw-r--r--telepathy-glib/stream-tube-channel.c10
-rw-r--r--telepathy-glib/telepathy-glib-uninstalled.pc.in1
-rw-r--r--telepathy-glib/telepathy-glib.pc.in1
-rw-r--r--telepathy-glib/text-channel.c12
-rw-r--r--telepathy-glib/util-internal.h2
-rw-r--r--telepathy-glib/util.c79
-rw-r--r--telepathy-glib/util.h12
-rw-r--r--telepathy-glib/versions/0.21.2.abi7
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