gnome-shell-3.6.3.1/src/shell-tp-client.c

No issues found

  1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
  2 
  3 #include "shell-tp-client.h"
  4 
  5 #include <string.h>
  6 
  7 #include <telepathy-glib/telepathy-glib.h>
  8 
  9 G_DEFINE_TYPE(ShellTpClient, shell_tp_client, TP_TYPE_BASE_CLIENT)
 10 
 11 struct _ShellTpClientPrivate
 12 {
 13   ShellTpClientObserveChannelsImpl observe_impl;
 14   gpointer user_data_obs;
 15   GDestroyNotify destroy_obs;
 16 
 17   ShellTpClientApproveChannelsImpl approve_channels_impl;
 18   gpointer user_data_approve_channels;
 19   GDestroyNotify destroy_approve_channels;
 20 
 21   ShellTpClientHandleChannelsImpl handle_channels_impl;
 22   gpointer user_data_handle_channels;
 23   GDestroyNotify destroy_handle_channels;
 24 
 25   ShellTpClientContactListChangedImpl contact_list_changed_impl;
 26   gpointer user_data_contact_list_changed;
 27   GDestroyNotify destroy_contact_list_changed;
 28 };
 29 
 30 /**
 31  * ShellTpClientObserveChannelsImpl:
 32  * @client: a #ShellTpClient instance
 33  * @account: a #TpAccount having %TP_ACCOUNT_FEATURE_CORE prepared if possible
 34  * @connection: a #TpConnection having %TP_CONNECTION_FEATURE_CORE prepared
 35  * if possible
 36  * @channels: (element-type TelepathyGLib.Channel): a #GList of #TpChannel,
 37  *  all having %TP_CHANNEL_FEATURE_CORE prepared if possible
 38  * @dispatch_operation: (allow-none): a #TpChannelDispatchOperation or %NULL;
 39  *  the dispatch_operation is not guaranteed to be prepared
 40  * @requests: (element-type TelepathyGLib.ChannelRequest): a #GList of
 41  *  #TpChannelRequest, all having their object-path defined but are not
 42  *  guaranteed to be prepared.
 43  * @context: a #TpObserveChannelsContext representing the context of this
 44  *  D-Bus call
 45  *
 46  * Signature of the implementation of the ObserveChannels method.
 47  */
 48 
 49 /**
 50  * ShellTpClientApproveChannelsImpl:
 51  * @client: a #ShellTpClient instance
 52  * @account: a #TpAccount having %TP_ACCOUNT_FEATURE_CORE prepared if possible
 53  * @connection: a #TpConnection having %TP_CONNECTION_FEATURE_CORE prepared
 54  * if possible
 55  * @channels: (element-type TelepathyGLib.Channel): a #GList of #TpChannel,
 56  *  all having %TP_CHANNEL_FEATURE_CORE prepared if possible
 57  * @dispatch_operation: (allow-none): a #TpChannelDispatchOperation or %NULL;
 58  *  the dispatch_operation is not guaranteed to be prepared
 59  * @context: a #TpAddDispatchOperationContext representing the context of this
 60  *  D-Bus call
 61  *
 62  * Signature of the implementation of the AddDispatchOperation method.
 63  */
 64 
 65 /**
 66  * ShellTpClientHandleChannelsImpl:
 67  * @client: a #ShellTpClient instance
 68  * @account: a #TpAccount having %TP_ACCOUNT_FEATURE_CORE prepared if possible
 69  * @connection: a #TpConnection having %TP_CONNECTION_FEATURE_CORE prepared
 70  * if possible
 71  * @channels: (element-type TelepathyGLib.Channel): a #GList of #TpChannel,
 72  *  all having %TP_CHANNEL_FEATURE_CORE prepared if possible
 73  * @requests_satisfied: (element-type TelepathyGLib.ChannelRequest): a #GList of
 74  * #TpChannelRequest having their object-path defined but are not guaranteed
 75  * to be prepared.
 76  * @user_action_time: the time at which user action occurred, or one of the
 77  *  special values %TP_USER_ACTION_TIME_NOT_USER_ACTION or
 78  *  %TP_USER_ACTION_TIME_CURRENT_TIME
 79  *  (see #TpAccountChannelRequest:user-action-time for details)
 80  * @context: a #TpHandleChannelsContext representing the context of this
 81  *  D-Bus call
 82  *
 83  * Signature of the implementation of the HandleChannels method.
 84  */
 85 
 86 /**
 87  * ShellTpClientContactListChangedImpl:
 88  * @connection: a #TpConnection having %TP_CONNECTION_FEATURE_CORE prepared
 89  * if possible
 90  * @added: (element-type TelepathyGLib.Contact): a #GPtrArray of added #TpContact
 91  * @removed: (element-type TelepathyGLib.Contact): a #GPtrArray of removed #TpContact
 92  *
 93  * Signature of the implementation of the ContactListChanged method.
 94  */
 95 
 96 static void
 97 shell_tp_client_init (ShellTpClient *self)
 98 {
 99   GHashTable *filter;
100 
101   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, SHELL_TYPE_TP_CLIENT,
102       ShellTpClientPrivate);
103 
104   /* We only care about single-user text-based chats */
105   filter = tp_asv_new (
106       TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
107         TP_IFACE_CHANNEL_TYPE_TEXT,
108       TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
109         TP_HANDLE_TYPE_CONTACT,
110       NULL);
111 
112   /* Observer */
113   tp_base_client_set_observer_recover (TP_BASE_CLIENT (self), TRUE);
114 
115   tp_base_client_add_observer_filter (TP_BASE_CLIENT (self), filter);
116 
117   /* Approver */
118   tp_base_client_add_approver_filter (TP_BASE_CLIENT (self), filter);
119 
120   /* Approve room invitations. We don't handle or observe room channels so
121    * just register this filter for the approver. */
122   tp_base_client_take_approver_filter (TP_BASE_CLIENT (self), tp_asv_new (
123       TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
124         TP_IFACE_CHANNEL_TYPE_TEXT,
125       TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
126         TP_HANDLE_TYPE_ROOM,
127       NULL));
128 
129   /* Approve calls. We let Empathy handle the call itself. */
130   tp_base_client_take_approver_filter (TP_BASE_CLIENT (self),
131       tp_asv_new (
132         TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_CALL,
133         TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
134         NULL));
135 
136   /* Approve file transfers. We let Empathy handle the transfer itself. */
137   tp_base_client_take_approver_filter (TP_BASE_CLIENT (self),
138       tp_asv_new (
139         TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
140           TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER,
141         TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
142         NULL));
143 
144   /* Handler */
145   tp_base_client_add_handler_filter (TP_BASE_CLIENT (self), filter);
146 
147   g_hash_table_unref (filter);
148 }
149 
150 static void
151 observe_channels (TpBaseClient *client,
152                   TpAccount *account,
153                   TpConnection *connection,
154                   GList *channels,
155                   TpChannelDispatchOperation *dispatch_operation,
156                   GList *requests,
157                   TpObserveChannelsContext *context)
158 {
159   ShellTpClient *self = (ShellTpClient *) client;
160 
161   g_assert (self->priv->observe_impl != NULL);
162 
163   self->priv->observe_impl (self, account, connection, channels,
164       dispatch_operation, requests, context, self->priv->user_data_obs);
165 }
166 
167 static void
168 add_dispatch_operation (TpBaseClient *client,
169     TpAccount *account,
170     TpConnection *connection,
171     GList *channels,
172     TpChannelDispatchOperation *dispatch_operation,
173     TpAddDispatchOperationContext *context)
174 {
175   ShellTpClient *self = (ShellTpClient *) client;
176 
177   g_assert (self->priv->approve_channels_impl != NULL);
178 
179   self->priv->approve_channels_impl (self, account, connection, channels,
180       dispatch_operation, context, self->priv->user_data_approve_channels);
181 }
182 
183 static void
184 handle_channels (TpBaseClient *client,
185     TpAccount *account,
186     TpConnection *connection,
187     GList *channels,
188     GList *requests_satisfied,
189     gint64 user_action_time,
190     TpHandleChannelsContext *context)
191 {
192   ShellTpClient *self = (ShellTpClient *) client;
193 
194   g_assert (self->priv->handle_channels_impl != NULL);
195 
196   self->priv->handle_channels_impl (self, account, connection, channels,
197       requests_satisfied, user_action_time, context,
198       self->priv->user_data_handle_channels);
199 }
200 
201 static void
202 shell_tp_client_dispose (GObject *object)
203 {
204   ShellTpClient *self = SHELL_TP_CLIENT (object);
205   void (*dispose) (GObject *) =
206     G_OBJECT_CLASS (shell_tp_client_parent_class)->dispose;
207 
208   if (self->priv->destroy_obs != NULL)
209     {
210       self->priv->destroy_obs (self->priv->user_data_obs);
211       self->priv->destroy_obs = NULL;
212       self->priv->user_data_obs = NULL;
213     }
214 
215   if (self->priv->destroy_approve_channels != NULL)
216     {
217       self->priv->destroy_approve_channels (self->priv->user_data_approve_channels);
218       self->priv->destroy_approve_channels = NULL;
219       self->priv->user_data_approve_channels = NULL;
220     }
221 
222   if (self->priv->destroy_handle_channels != NULL)
223     {
224       self->priv->destroy_handle_channels (self->priv->user_data_handle_channels);
225       self->priv->destroy_handle_channels = NULL;
226       self->priv->user_data_handle_channels = NULL;
227     }
228 
229   if (self->priv->destroy_contact_list_changed != NULL)
230     {
231       self->priv->destroy_contact_list_changed (self->priv->user_data_contact_list_changed);
232       self->priv->destroy_contact_list_changed = NULL;
233       self->priv->user_data_contact_list_changed = NULL;
234     }
235 
236   if (dispose != NULL)
237     dispose (object);
238 }
239 
240 static void
241 shell_tp_client_class_init (ShellTpClientClass *cls)
242 {
243   GObjectClass *object_class = G_OBJECT_CLASS (cls);
244   TpBaseClientClass *base_clt_cls = TP_BASE_CLIENT_CLASS (cls);
245 
246   g_type_class_add_private (cls, sizeof (ShellTpClientPrivate));
247 
248   object_class->dispose = shell_tp_client_dispose;
249 
250   base_clt_cls->observe_channels = observe_channels;
251   base_clt_cls->add_dispatch_operation = add_dispatch_operation;
252   base_clt_cls->handle_channels = handle_channels;
253 }
254 
255 void
256 shell_tp_client_set_observe_channels_func (ShellTpClient *self,
257                                            ShellTpClientObserveChannelsImpl observe_impl,
258                                            gpointer user_data,
259                                            GDestroyNotify destroy)
260 {
261   g_assert (self->priv->observe_impl == NULL);
262 
263   self->priv->observe_impl = observe_impl;
264   self->priv->user_data_obs = user_data;
265   self->priv->destroy_obs = destroy;
266 }
267 
268 void
269 shell_tp_client_set_approve_channels_func (ShellTpClient *self,
270     ShellTpClientApproveChannelsImpl approve_channels_impl,
271     gpointer user_data,
272     GDestroyNotify destroy)
273 {
274   g_assert (self->priv->approve_channels_impl == NULL);
275 
276   self->priv->approve_channels_impl = approve_channels_impl;
277   self->priv->user_data_approve_channels = user_data;
278   self->priv->destroy_approve_channels = destroy;
279 }
280 
281 void
282 shell_tp_client_set_handle_channels_func (ShellTpClient *self,
283     ShellTpClientHandleChannelsImpl handle_channels_impl,
284     gpointer user_data,
285     GDestroyNotify destroy)
286 {
287   g_assert (self->priv->handle_channels_impl == NULL);
288 
289   self->priv->handle_channels_impl = handle_channels_impl;
290   self->priv->user_data_handle_channels = user_data;
291   self->priv->destroy_handle_channels = destroy;
292 }
293 
294 void
295 shell_tp_client_set_contact_list_changed_func (ShellTpClient *self,
296     ShellTpClientContactListChangedImpl contact_list_changed_impl,
297     gpointer user_data,
298     GDestroyNotify destroy)
299 {
300   g_assert (self->priv->contact_list_changed_impl == NULL);
301 
302   self->priv->contact_list_changed_impl = contact_list_changed_impl;
303   self->priv->user_data_handle_channels = user_data;
304   self->priv->destroy_handle_channels = destroy;
305 }
306 
307 static void
308 on_contact_list_changed (TpConnection *conn,
309                          GPtrArray *added,
310                          GPtrArray *removed,
311                          gpointer user_data)
312 {
313   ShellTpClient *self = (ShellTpClient *) user_data;
314 
315   g_assert (self->priv->contact_list_changed_impl != NULL);
316 
317   self->priv->contact_list_changed_impl (conn,
318       added, removed,
319       self->priv->user_data_contact_list_changed);
320 }
321 
322 void
323 shell_tp_client_grab_contact_list_changed (ShellTpClient *self,
324                                            TpConnection *conn)
325 {
326   g_signal_connect (conn, "contact-list-changed",
327                     G_CALLBACK (on_contact_list_changed),
328                     self);
329 }