~bcurtiswx/ubuntu/precise/empathy/3.4.2.1-0ubuntu1

« back to all changes in this revision

Viewing changes to telepathy-yell/telepathy-yell/call-stream.c

  • Committer: Package Import Robot
  • Author(s): Ken VanDine
  • Date: 2012-03-05 15:14:36 UTC
  • mfrom: (1.1.87)
  • Revision ID: package-import@ubuntu.com-20120305151436-utnrdabb2ppp3kw1
Tags: 3.3.90.2-0ubuntu1
* New upstream release
* debian/control
  - added yelp-tools and libfarstream-0.1-dev build depends
  - bump build depends on libtelepathy-farstream-dev, and 
    libtelepathy-glib-dev
  - bumpded depends for telepathy-mission-control-5
  - removed telepathy-butterfly recommends, mission-control-5 ensures 
    telepathy-haze handles MSN now.
* debian/rules
  - enable empathy-av 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * call-stream.c - Source for TpyCallStream
3
 
 * Copyright © 2009–2011 Collabora Ltd.
4
 
 * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
5
 
 * @author Will Thompson <will.thompson@collabora.co.uk>
6
 
 * @author Emilio Pozuelo Monfort <emilio.pozuelo@collabora.co.uk>
7
 
 *
8
 
 * This library is free software; you can redistribute it and/or
9
 
 * modify it under the terms of the GNU Lesser General Public
10
 
 * License as published by the Free Software Foundation; either
11
 
 * version 2.1 of the License, or (at your option) any later version.
12
 
 *
13
 
 * This library is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
 * Lesser General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Lesser General Public
19
 
 * License along with this library; if not, write to the Free Software
20
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21
 
 */
22
 
 
23
 
#include "call-stream.h"
24
 
 
25
 
#define DEBUG_FLAG TPY_DEBUG_CALL
26
 
#include "debug.h"
27
 
 
28
 
#include <telepathy-yell/interfaces.h>
29
 
#include <telepathy-yell/gtypes.h>
30
 
#include <telepathy-yell/cli-call.h>
31
 
 
32
 
G_DEFINE_TYPE(TpyCallStream, tpy_call_stream, TP_TYPE_PROXY)
33
 
 
34
 
enum
35
 
{
36
 
  PROP_REMOTE_MEMBERS = 1,
37
 
  PROP_LOCAL_SENDING_STATE,
38
 
  PROP_CAN_REQUEST_RECEIVING,
39
 
  PROP_READY,
40
 
};
41
 
 
42
 
struct _TpyCallStreamPrivate
43
 
{
44
 
  GHashTable *remote_members;
45
 
  TpySendingState local_sending_state;
46
 
  gboolean can_request_receiving;
47
 
  gboolean ready;
48
 
 
49
 
  GSimpleAsyncResult *result;
50
 
};
51
 
 
52
 
static void
53
 
on_call_stream_get_all_properties_cb (TpProxy *proxy,
54
 
    GHashTable *properties,
55
 
    const GError *error,
56
 
    gpointer user_data,
57
 
    GObject *weak_object)
58
 
{
59
 
  TpyCallStream *self = TPY_CALL_STREAM (proxy);
60
 
  GHashTable *members;
61
 
 
62
 
  if (error != NULL)
63
 
    {
64
 
      g_warning ("Could not get the stream properties: %s", error->message);
65
 
      return;
66
 
    }
67
 
 
68
 
  self->priv->local_sending_state = tp_asv_get_uint32 (properties,
69
 
      "LocalSendingState", NULL);
70
 
  self->priv->can_request_receiving = tp_asv_get_boolean (properties,
71
 
      "CanRequestReceiving", NULL);
72
 
 
73
 
  tp_clear_pointer (&self->priv->remote_members, g_hash_table_unref);
74
 
  members = tp_asv_get_boxed (properties,
75
 
      "RemoteMembers", TPY_HASH_TYPE_CALL_MEMBER_MAP);
76
 
  if (members != NULL)
77
 
    self->priv->remote_members =
78
 
        g_boxed_copy (TPY_HASH_TYPE_CALL_MEMBER_MAP, members);
79
 
 
80
 
  self->priv->ready = TRUE;
81
 
  g_object_notify (G_OBJECT (self), "ready");
82
 
}
83
 
 
84
 
static void
85
 
on_remote_members_changed_cb (TpProxy *proxy,
86
 
    GHashTable *updates,
87
 
    const GArray *removed,
88
 
    gpointer user_data,
89
 
    GObject *weak_object)
90
 
{
91
 
  TpyCallStream *self = TPY_CALL_STREAM (proxy);
92
 
  GHashTableIter iter;
93
 
  gpointer key, value;
94
 
  guint i;
95
 
 
96
 
  for (i = 0; i < removed->len; i++)
97
 
    g_hash_table_remove (self->priv->remote_members,
98
 
        GUINT_TO_POINTER (g_array_index (removed, TpHandle, i)));
99
 
 
100
 
  g_hash_table_iter_init (&iter, updates);
101
 
  while (g_hash_table_iter_next (&iter, &key, &value))
102
 
    g_hash_table_insert (self->priv->remote_members, key, value);
103
 
 
104
 
  g_object_notify (G_OBJECT (self), "remote-members");
105
 
}
106
 
 
107
 
static void
108
 
on_local_sending_state_changed_cb (TpProxy *proxy,
109
 
    guint state,
110
 
    gpointer user_data,
111
 
    GObject *weak_object)
112
 
{
113
 
  TpyCallStream *self = TPY_CALL_STREAM (proxy);
114
 
 
115
 
  if (self->priv->local_sending_state == state)
116
 
    return;
117
 
 
118
 
  self->priv->local_sending_state = state;
119
 
  g_object_notify (G_OBJECT (self), "local-sending-state");
120
 
}
121
 
 
122
 
static void
123
 
tpy_call_stream_constructed (GObject *obj)
124
 
{
125
 
  TpyCallStream *self = (TpyCallStream *) obj;
126
 
  GError *err = NULL;
127
 
 
128
 
  ((GObjectClass *) tpy_call_stream_parent_class)->constructed (obj);
129
 
 
130
 
  tpy_cli_call_stream_connect_to_remote_members_changed (TP_PROXY (self),
131
 
      on_remote_members_changed_cb, NULL, NULL, G_OBJECT (self), &err);
132
 
 
133
 
  if (err != NULL)
134
 
    {
135
 
      g_critical ("Failed to connect to RemoteMembersChanged signal: %s",
136
 
          err->message);
137
 
 
138
 
      g_error_free (err);
139
 
      return;
140
 
    }
141
 
 
142
 
  tpy_cli_call_stream_connect_to_local_sending_state_changed (TP_PROXY (self),
143
 
      on_local_sending_state_changed_cb, NULL, NULL, G_OBJECT (self), &err);
144
 
 
145
 
  if (err != NULL)
146
 
    {
147
 
      g_critical ("Failed to connect to LocalSendingStateChanged signal: %s",
148
 
          err->message);
149
 
 
150
 
      g_error_free (err);
151
 
      return;
152
 
    }
153
 
 
154
 
  tp_cli_dbus_properties_call_get_all (self, -1,
155
 
      TPY_IFACE_CALL_STREAM,
156
 
      on_call_stream_get_all_properties_cb, NULL, NULL, G_OBJECT (self));
157
 
}
158
 
 
159
 
static void
160
 
tpy_call_stream_init (TpyCallStream *self)
161
 
{
162
 
  TpyCallStreamPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
163
 
      TPY_TYPE_CALL_STREAM, TpyCallStreamPrivate);
164
 
 
165
 
  self->priv = priv;
166
 
  priv->remote_members = g_hash_table_new (g_direct_hash, g_direct_equal);
167
 
}
168
 
 
169
 
static void
170
 
tpy_call_stream_dispose (GObject *object)
171
 
{
172
 
  TpyCallStream *self = TPY_CALL_STREAM (object);
173
 
 
174
 
  tp_clear_object (&self->priv->result);
175
 
  tp_clear_pointer (&self->priv->remote_members, g_hash_table_unref);
176
 
 
177
 
  G_OBJECT_CLASS (tpy_call_stream_parent_class)->dispose (object);
178
 
}
179
 
 
180
 
static void
181
 
tpy_call_stream_get_property (
182
 
    GObject *object,
183
 
    guint property_id,
184
 
    GValue *value,
185
 
    GParamSpec *pspec)
186
 
{
187
 
  TpyCallStream *self = TPY_CALL_STREAM (object);
188
 
  TpyCallStreamPrivate *priv = self->priv;
189
 
 
190
 
  switch (property_id)
191
 
    {
192
 
      case PROP_REMOTE_MEMBERS:
193
 
        g_value_set_boxed (value, priv->remote_members);
194
 
        break;
195
 
      case PROP_LOCAL_SENDING_STATE:
196
 
        g_value_set_uint (value, priv->local_sending_state);
197
 
        break;
198
 
      case PROP_CAN_REQUEST_RECEIVING:
199
 
        g_value_set_boolean (value, priv->can_request_receiving);
200
 
        break;
201
 
      case PROP_READY:
202
 
        g_value_set_boolean (value, priv->ready);
203
 
        break;
204
 
      default:
205
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
206
 
        break;
207
 
    }
208
 
}
209
 
 
210
 
static void
211
 
tpy_call_stream_set_property (
212
 
    GObject *object,
213
 
    guint property_id,
214
 
    const GValue *value,
215
 
    GParamSpec *pspec)
216
 
{
217
 
  TpyCallStream *self = TPY_CALL_STREAM (object);
218
 
 
219
 
  switch (property_id)
220
 
    {
221
 
      case PROP_LOCAL_SENDING_STATE:
222
 
        self->priv->local_sending_state = g_value_get_uint (value);
223
 
        break;
224
 
      default:
225
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
226
 
        break;
227
 
    }
228
 
}
229
 
 
230
 
static void
231
 
tpy_call_stream_class_init (TpyCallStreamClass *bsc_class)
232
 
{
233
 
  GObjectClass *object_class = G_OBJECT_CLASS (bsc_class);
234
 
  TpProxyClass *proxy_class = (TpProxyClass *) bsc_class;
235
 
  GParamSpec *param_spec;
236
 
 
237
 
  g_type_class_add_private (bsc_class, sizeof (TpyCallStreamPrivate));
238
 
 
239
 
  object_class->dispose = tpy_call_stream_dispose;
240
 
  object_class->constructed = tpy_call_stream_constructed;
241
 
  object_class->set_property = tpy_call_stream_set_property;
242
 
  object_class->get_property = tpy_call_stream_get_property;
243
 
 
244
 
  proxy_class->interface = TPY_IFACE_QUARK_CALL_STREAM;
245
 
 
246
 
  param_spec = g_param_spec_boxed ("remote-members", "Remote members",
247
 
      "Remote member map",
248
 
      TPY_HASH_TYPE_CONTACT_SENDING_STATE_MAP,
249
 
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
250
 
  g_object_class_install_property (object_class, PROP_REMOTE_MEMBERS,
251
 
      param_spec);
252
 
 
253
 
  param_spec = g_param_spec_uint ("local-sending-state", "LocalSendingState",
254
 
      "Local sending state",
255
 
      0, NUM_TPY_SENDING_STATES, 0,
256
 
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
257
 
  g_object_class_install_property (object_class, PROP_LOCAL_SENDING_STATE,
258
 
      param_spec);
259
 
 
260
 
  param_spec = g_param_spec_boolean ("can-request-receiving",
261
 
      "CanRequestReceiving",
262
 
      "If true, the user can request that a remote contact starts sending on"
263
 
      "this stream.",
264
 
      FALSE,
265
 
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
266
 
  g_object_class_install_property (object_class, PROP_CAN_REQUEST_RECEIVING,
267
 
      param_spec);
268
 
 
269
 
  param_spec = g_param_spec_boolean ("ready",
270
 
      "Ready",
271
 
      "If true the stream has retrieved all async information from the CM",
272
 
      FALSE,
273
 
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
274
 
  g_object_class_install_property (object_class, PROP_READY,
275
 
      param_spec);
276
 
}
277
 
 
278
 
TpySendingState
279
 
tpy_call_stream_get_local_sending_state (
280
 
  TpyCallStream *self)
281
 
{
282
 
  return self->priv->local_sending_state;
283
 
}
284
 
 
285
 
static void
286
 
on_set_sending_cb (TpProxy *proxy,
287
 
    const GError *error,
288
 
    gpointer user_data,
289
 
    GObject *weak_object)
290
 
{
291
 
  TpyCallStream *self = TPY_CALL_STREAM (proxy);
292
 
 
293
 
  if (error != NULL)
294
 
    {
295
 
      DEBUG ("Failed to set sending: %s", error->message);
296
 
 
297
 
      g_simple_async_result_set_from_error (self->priv->result, error);
298
 
    }
299
 
 
300
 
  g_simple_async_result_set_op_res_gboolean (self->priv->result, TRUE);
301
 
  g_simple_async_result_complete (self->priv->result);
302
 
  tp_clear_object (&self->priv->result);
303
 
}
304
 
 
305
 
void
306
 
tpy_call_stream_set_sending_async (TpyCallStream *self,
307
 
    gboolean send,
308
 
    GAsyncReadyCallback callback,
309
 
    gpointer user_data)
310
 
{
311
 
  g_return_if_fail (TPY_IS_CALL_STREAM (self));
312
 
  g_return_if_fail (self->priv->result == NULL);
313
 
 
314
 
  self->priv->result = g_simple_async_result_new (G_OBJECT (self), callback,
315
 
      user_data, tpy_call_stream_set_sending_async);
316
 
 
317
 
  tpy_cli_call_stream_call_set_sending (TP_PROXY (self), -1,
318
 
      send,
319
 
      on_set_sending_cb, NULL, NULL, G_OBJECT (self));
320
 
}
321
 
 
322
 
gboolean
323
 
tpy_call_stream_set_sending_finish (TpyCallStream *self,
324
 
    GAsyncResult *result,
325
 
    GError **error)
326
 
{
327
 
  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
328
 
      error))
329
 
    return FALSE;
330
 
 
331
 
  g_return_val_if_fail (g_simple_async_result_is_valid (result,
332
 
    G_OBJECT (self), tpy_call_stream_set_sending_async),
333
 
    FALSE);
334
 
 
335
 
  return g_simple_async_result_get_op_res_gboolean (
336
 
    G_SIMPLE_ASYNC_RESULT (result));
337
 
}
338
 
 
339
 
static void
340
 
on_request_receiving_cb (TpProxy *proxy,
341
 
    const GError *error,
342
 
    gpointer user_data,
343
 
    GObject *weak_object)
344
 
{
345
 
  TpyCallStream *self = TPY_CALL_STREAM (proxy);
346
 
 
347
 
  if (error != NULL)
348
 
    {
349
 
      DEBUG ("Failed to request receiving: %s", error->message);
350
 
 
351
 
      g_simple_async_result_set_from_error (self->priv->result, error);
352
 
    }
353
 
 
354
 
  g_simple_async_result_set_op_res_gboolean (self->priv->result, TRUE);
355
 
  g_simple_async_result_complete (self->priv->result);
356
 
  tp_clear_object (&self->priv->result);
357
 
}
358
 
 
359
 
void
360
 
tpy_call_stream_request_receiving_async (TpyCallStream *self,
361
 
    TpHandle handle,
362
 
    gboolean receiving,
363
 
    GAsyncReadyCallback callback,
364
 
    gpointer user_data)
365
 
{
366
 
  g_return_if_fail (TPY_IS_CALL_STREAM (self));
367
 
  g_return_if_fail (self->priv->result == NULL);
368
 
 
369
 
  self->priv->result = g_simple_async_result_new (G_OBJECT (self), callback,
370
 
      user_data, tpy_call_stream_request_receiving_async);
371
 
 
372
 
  tpy_cli_call_stream_call_request_receiving (TP_PROXY (self), -1,
373
 
      handle, receiving,
374
 
      on_request_receiving_cb, NULL, NULL, G_OBJECT (self));
375
 
}
376
 
 
377
 
gboolean
378
 
tpy_call_stream_request_receiving_finish (TpyCallStream *self,
379
 
    GAsyncResult *result,
380
 
    GError **error)
381
 
{
382
 
  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
383
 
      error))
384
 
    return FALSE;
385
 
 
386
 
  g_return_val_if_fail (g_simple_async_result_is_valid (result,
387
 
    G_OBJECT (self), tpy_call_stream_request_receiving_async),
388
 
    FALSE);
389
 
 
390
 
  return g_simple_async_result_get_op_res_gboolean (
391
 
    G_SIMPLE_ASYNC_RESULT (result));
392
 
}