~ubuntu-branches/ubuntu/precise/empathy/precise-proposed-201205180810

« back to all changes in this revision

Viewing changes to telepathy-yell/telepathy-yell/base-call-content.c

  • Committer: Bazaar Package Importer
  • Author(s): Brian Curtis, Brian Curtis, Ken VanDine
  • Date: 2011-06-01 10:35:24 UTC
  • mfrom: (1.1.70 upstream) (6.3.44 experimental)
  • Revision ID: james.westby@ubuntu.com-20110601103524-wx3wgp71394730jt
Tags: 3.1.1-1ubuntu1
[ Brian Curtis ]
* Merge with Debian experimental, remaining Ubuntu changes:
* debian/control:
  - Drop geoclue/mapping build-depends (they are in Universe)
  - Add Vcz-Bzr link
  - Add Suggests on telepathy-idle
  - Bump telepathy-butterfly, telepathy-haze to recommends
  - Don't recommend the freedesktop sound theme we have an ubuntu one
  - Add build depend for libunity-dev
* debian/rules:
  - Use autoreconf.mk
  - Disable map and location
* debian/empathy.install:
  - Install message indicator configuration
* debian/indicators/empathy:
  - Message indicator configuration
* debian/patches/01_lpi.patch:
  - Add Launchpad integration
* debian/patches/10_use_notify_osd_icons.patch:
  - Use the notify-osd image for new messages
* debian/patches/34_start_raised_execpt_in_session.patch
  - If not started with the session, we should always raise
* debian/patches/36_chat_window_default_size.patch:
  - Make the default chat window size larger
* debian/patches/37_facebook_default.patch:
  - Make facebook the default chat account type
* debian/patches/38_lp_569289.patch
  - Set freenode as default IRC network for new IRC accounts 
* debian/patches/41_unity_launcher_progress.patch
  - Display file transfer progress in the unity launcher

[ Ken VanDine ]
* debian/control
  - build depend on libgcr-3-dev instead of libgcr-dev
  - dropped build depends for libindicate, we will use telepathy-indicator
  - Depend on dconf-gsettings-backend | gsettings-backend
  - Added a Recommends for telepathy-indicator
* +debian/empathy.gsettings-override
  - Added an override for notifications-focus
* debian/patches/series
  - commented out 23_idomessagedialog_for_voip_and_ft.patch, until ido has 
    been ported to gtk3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * base-call-content.c - Source for TpyBaseCallContent
3
 
 * Copyright © 2009–2010 Collabora Ltd.
4
 
 * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
5
 
 * @author Will Thompson <will.thompson@collabora.co.uk>
6
 
 *
7
 
 * This library is free software; you can redistribute it and/or
8
 
 * modify it under the terms of the GNU Lesser General Public
9
 
 * License as published by the Free Software Foundation; either
10
 
 * version 2.1 of the License, or (at your option) any later version.
11
 
 *
12
 
 * This library is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 
 * Lesser General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU Lesser General Public
18
 
 * License along with this library; if not, write to the Free Software
19
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
 
 */
21
 
 
22
 
#include "base-call-content.h"
23
 
 
24
 
#include "base-call-stream.h"
25
 
 
26
 
#define DEBUG_FLAG TPY_DEBUG_CALL
27
 
#include "debug.h"
28
 
 
29
 
#include <telepathy-yell/interfaces.h>
30
 
#include <telepathy-yell/gtypes.h>
31
 
#include <telepathy-yell/enums.h>
32
 
#include <telepathy-yell/svc-call.h>
33
 
 
34
 
static void call_content_iface_init (gpointer g_iface, gpointer iface_data);
35
 
 
36
 
G_DEFINE_TYPE_WITH_CODE(TpyBaseCallContent, tpy_base_call_content,
37
 
    G_TYPE_OBJECT,
38
 
    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
39
 
        tp_dbus_properties_mixin_iface_init);
40
 
    G_IMPLEMENT_INTERFACE (TPY_TYPE_SVC_CALL_CONTENT,
41
 
        call_content_iface_init);
42
 
    );
43
 
 
44
 
struct _TpyBaseCallContentPrivate
45
 
{
46
 
  TpBaseConnection *conn;
47
 
  TpDBusDaemon *dbus_daemon;
48
 
 
49
 
  gchar *object_path;
50
 
 
51
 
  gchar *name;
52
 
  TpMediaStreamType media_type;
53
 
  TpHandle creator;
54
 
  TpyCallContentDisposition disposition;
55
 
 
56
 
  GList *streams;
57
 
 
58
 
  gboolean dispose_has_run;
59
 
  gboolean deinit_has_run;
60
 
};
61
 
 
62
 
enum
63
 
{
64
 
  PROP_OBJECT_PATH = 1,
65
 
  PROP_CONNECTION,
66
 
 
67
 
  PROP_INTERFACES,
68
 
  PROP_NAME,
69
 
  PROP_MEDIA_TYPE,
70
 
  PROP_CREATOR,
71
 
  PROP_DISPOSITION,
72
 
  PROP_STREAMS
73
 
};
74
 
 
75
 
static void base_call_content_deinit_real (TpyBaseCallContent *self);
76
 
 
77
 
static void
78
 
tpy_base_call_content_init (TpyBaseCallContent *self)
79
 
{
80
 
  TpyBaseCallContentPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
81
 
      TPY_TYPE_BASE_CALL_CONTENT, TpyBaseCallContentPrivate);
82
 
 
83
 
  self->priv = priv;
84
 
}
85
 
 
86
 
static void
87
 
tpy_base_call_content_constructed (GObject *obj)
88
 
{
89
 
  TpyBaseCallContent *self = TPY_BASE_CALL_CONTENT (obj);
90
 
  TpyBaseCallContentPrivate *priv = self->priv;
91
 
 
92
 
  if (G_OBJECT_CLASS (tpy_base_call_content_parent_class)->constructed != NULL)
93
 
    G_OBJECT_CLASS (tpy_base_call_content_parent_class)->constructed (obj);
94
 
 
95
 
  DEBUG ("Registering %s", priv->object_path);
96
 
  priv->dbus_daemon = g_object_ref (
97
 
      tp_base_connection_get_dbus_daemon ((TpBaseConnection *) priv->conn));
98
 
  tp_dbus_daemon_register_object (priv->dbus_daemon, priv->object_path, obj);
99
 
}
100
 
 
101
 
static void
102
 
tpy_base_call_content_dispose (GObject *object)
103
 
{
104
 
  TpyBaseCallContent *self = TPY_BASE_CALL_CONTENT (object);
105
 
  TpyBaseCallContentPrivate *priv = self->priv;
106
 
  GList *l;
107
 
 
108
 
  if (priv->dispose_has_run)
109
 
    return;
110
 
 
111
 
  priv->dispose_has_run = TRUE;
112
 
 
113
 
  for (l = priv->streams; l != NULL; l = g_list_next (l))
114
 
    g_object_unref (l->data);
115
 
 
116
 
  tp_clear_pointer (&priv->streams, g_list_free);
117
 
  tp_clear_object (&priv->conn);
118
 
 
119
 
  if (G_OBJECT_CLASS (tpy_base_call_content_parent_class)->dispose != NULL)
120
 
    G_OBJECT_CLASS (tpy_base_call_content_parent_class)->dispose (object);
121
 
}
122
 
 
123
 
static void
124
 
tpy_base_call_content_finalize (GObject *object)
125
 
{
126
 
  TpyBaseCallContent *self = TPY_BASE_CALL_CONTENT (object);
127
 
  TpyBaseCallContentPrivate *priv = self->priv;
128
 
 
129
 
  /* free any data held directly by the object here */
130
 
  g_free (priv->object_path);
131
 
  g_free (priv->name);
132
 
 
133
 
  G_OBJECT_CLASS (tpy_base_call_content_parent_class)->finalize (object);
134
 
}
135
 
 
136
 
static void
137
 
tpy_base_call_content_get_property (
138
 
    GObject *object,
139
 
    guint property_id,
140
 
    GValue *value,
141
 
    GParamSpec *pspec)
142
 
{
143
 
  TpyBaseCallContent *content = TPY_BASE_CALL_CONTENT (object);
144
 
  TpyBaseCallContentPrivate *priv = content->priv;
145
 
 
146
 
  switch (property_id)
147
 
    {
148
 
      case PROP_OBJECT_PATH:
149
 
        g_value_set_string (value, priv->object_path);
150
 
        break;
151
 
      case PROP_CONNECTION:
152
 
        g_value_set_object (value, priv->conn);
153
 
        break;
154
 
      case PROP_INTERFACES:
155
 
        {
156
 
          TpyBaseCallContentClass *klass =
157
 
              TPY_BASE_CALL_CONTENT_GET_CLASS (content);
158
 
 
159
 
          if (klass->extra_interfaces != NULL)
160
 
            {
161
 
              g_value_set_boxed (value, klass->extra_interfaces);
162
 
            }
163
 
          else
164
 
            {
165
 
              static gchar *empty[] = { NULL };
166
 
 
167
 
              g_value_set_boxed (value, empty);
168
 
            }
169
 
          break;
170
 
        }
171
 
      case PROP_NAME:
172
 
        g_value_set_string (value, priv->name);
173
 
        break;
174
 
      case PROP_MEDIA_TYPE:
175
 
        g_value_set_uint (value, priv->media_type);
176
 
        break;
177
 
      case PROP_CREATOR:
178
 
        g_value_set_uint (value, priv->creator);
179
 
        break;
180
 
      case PROP_DISPOSITION:
181
 
        g_value_set_uint (value, priv->disposition);
182
 
        break;
183
 
      case PROP_STREAMS:
184
 
        {
185
 
          GPtrArray *arr = g_ptr_array_sized_new (2);
186
 
          GList *l;
187
 
 
188
 
          for (l = priv->streams; l != NULL; l = g_list_next (l))
189
 
            {
190
 
              TpyBaseCallStream *s = TPY_BASE_CALL_STREAM (l->data);
191
 
              g_ptr_array_add (arr,
192
 
                  g_strdup (tpy_base_call_stream_get_object_path (s)));
193
 
            }
194
 
 
195
 
          g_value_take_boxed (value, arr);
196
 
          break;
197
 
        }
198
 
      default:
199
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
200
 
        break;
201
 
    }
202
 
}
203
 
 
204
 
static void
205
 
tpy_base_call_content_set_property (
206
 
    GObject *object,
207
 
    guint property_id,
208
 
    const GValue *value,
209
 
    GParamSpec *pspec)
210
 
{
211
 
  TpyBaseCallContent *content = TPY_BASE_CALL_CONTENT (object);
212
 
  TpyBaseCallContentPrivate *priv = content->priv;
213
 
 
214
 
  switch (property_id)
215
 
    {
216
 
      case PROP_OBJECT_PATH:
217
 
        priv->object_path = g_value_dup_string (value);
218
 
        g_assert (priv->object_path != NULL);
219
 
        break;
220
 
      case PROP_CONNECTION:
221
 
        priv->conn = g_value_dup_object (value);
222
 
        break;
223
 
      case PROP_NAME:
224
 
        priv->name = g_value_dup_string (value);
225
 
        break;
226
 
      case PROP_MEDIA_TYPE:
227
 
        priv->media_type = g_value_get_uint (value);
228
 
        break;
229
 
      case PROP_CREATOR:
230
 
        priv->creator = g_value_get_uint (value);
231
 
        break;
232
 
      case PROP_DISPOSITION:
233
 
        priv->disposition = g_value_get_uint (value);
234
 
        break;
235
 
      default:
236
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
237
 
        break;
238
 
    }
239
 
}
240
 
 
241
 
static void
242
 
tpy_base_call_content_class_init (
243
 
    TpyBaseCallContentClass *bcc_class)
244
 
{
245
 
  GObjectClass *object_class = G_OBJECT_CLASS (bcc_class);
246
 
  GParamSpec *param_spec;
247
 
  static TpDBusPropertiesMixinPropImpl content_props[] = {
248
 
    { "Interfaces", "interfaces", NULL },
249
 
    { "Name", "name", NULL },
250
 
    { "Type", "media-type", NULL },
251
 
    { "Disposition", "disposition", NULL },
252
 
    { "Streams", "streams", NULL },
253
 
    { NULL }
254
 
  };
255
 
  static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
256
 
      { TPY_IFACE_CALL_CONTENT,
257
 
        tp_dbus_properties_mixin_getter_gobject_properties,
258
 
        NULL,
259
 
        content_props,
260
 
      },
261
 
      { NULL }
262
 
  };
263
 
 
264
 
  g_type_class_add_private (bcc_class, sizeof (TpyBaseCallContentPrivate));
265
 
 
266
 
  object_class->constructed = tpy_base_call_content_constructed;
267
 
  object_class->dispose = tpy_base_call_content_dispose;
268
 
  object_class->finalize = tpy_base_call_content_finalize;
269
 
  object_class->get_property = tpy_base_call_content_get_property;
270
 
  object_class->set_property = tpy_base_call_content_set_property;
271
 
 
272
 
  param_spec = g_param_spec_string ("object-path", "D-Bus object path",
273
 
      "The D-Bus object path used for this object on the bus.",
274
 
      NULL,
275
 
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
276
 
  g_object_class_install_property (object_class, PROP_OBJECT_PATH, param_spec);
277
 
 
278
 
  param_spec = g_param_spec_object ("connection", "TpBaseConnection object",
279
 
      "Tp base connection object that owns this call content",
280
 
      TP_TYPE_BASE_CONNECTION,
281
 
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
282
 
  g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
283
 
 
284
 
  param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
285
 
      "Additional interfaces implemented by this content",
286
 
      G_TYPE_STRV,
287
 
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
288
 
  g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
289
 
 
290
 
  param_spec = g_param_spec_string ("name", "Name",
291
 
      "The name of this content, if any",
292
 
      "",
293
 
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
294
 
  g_object_class_install_property (object_class, PROP_NAME, param_spec);
295
 
 
296
 
  param_spec = g_param_spec_uint ("media-type", "Media Type",
297
 
      "The media type of this content",
298
 
      0, G_MAXUINT, 0,
299
 
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
300
 
  g_object_class_install_property (object_class, PROP_MEDIA_TYPE, param_spec);
301
 
 
302
 
  param_spec = g_param_spec_uint ("creator", "Creator",
303
 
      "The creator of this content",
304
 
      0, G_MAXUINT, 0,
305
 
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
306
 
  g_object_class_install_property (object_class, PROP_CREATOR, param_spec);
307
 
 
308
 
  param_spec = g_param_spec_uint ("disposition", "Disposition",
309
 
      "The disposition of this content",
310
 
      0, G_MAXUINT, 0,
311
 
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
312
 
  g_object_class_install_property (object_class, PROP_DISPOSITION, param_spec);
313
 
 
314
 
  param_spec = g_param_spec_boxed ("streams", "Stream",
315
 
      "The streams of this content",
316
 
      TP_ARRAY_TYPE_OBJECT_PATH_LIST,
317
 
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
318
 
  g_object_class_install_property (object_class, PROP_STREAMS,
319
 
      param_spec);
320
 
 
321
 
  bcc_class->dbus_props_class.interfaces = prop_interfaces;
322
 
  tp_dbus_properties_mixin_class_init (object_class,
323
 
      G_STRUCT_OFFSET (TpyBaseCallContentClass, dbus_props_class));
324
 
 
325
 
  bcc_class->deinit = base_call_content_deinit_real;
326
 
}
327
 
 
328
 
TpBaseConnection *
329
 
tpy_base_call_content_get_connection (TpyBaseCallContent *self)
330
 
{
331
 
  g_return_val_if_fail (TPY_IS_BASE_CALL_CONTENT (self), NULL);
332
 
 
333
 
  return self->priv->conn;
334
 
}
335
 
 
336
 
const gchar *
337
 
tpy_base_call_content_get_object_path (TpyBaseCallContent *self)
338
 
{
339
 
  g_return_val_if_fail (TPY_IS_BASE_CALL_CONTENT (self), NULL);
340
 
 
341
 
  return self->priv->object_path;
342
 
}
343
 
 
344
 
const gchar *
345
 
tpy_base_call_content_get_name (TpyBaseCallContent *self)
346
 
{
347
 
  g_return_val_if_fail (TPY_IS_BASE_CALL_CONTENT (self), NULL);
348
 
 
349
 
  return self->priv->name;
350
 
}
351
 
 
352
 
TpMediaStreamType
353
 
tpy_base_call_content_get_media_type (TpyBaseCallContent *self)
354
 
{
355
 
  g_return_val_if_fail (TPY_IS_BASE_CALL_CONTENT (self),
356
 
      TP_MEDIA_STREAM_TYPE_AUDIO);
357
 
 
358
 
  return self->priv->media_type;
359
 
}
360
 
 
361
 
TpyCallContentDisposition
362
 
tpy_base_call_content_get_disposition (TpyBaseCallContent *self)
363
 
{
364
 
  g_return_val_if_fail (TPY_IS_BASE_CALL_CONTENT (self),
365
 
      TPY_CALL_CONTENT_DISPOSITION_NONE);
366
 
 
367
 
  return self->priv->disposition;
368
 
}
369
 
 
370
 
GList *
371
 
tpy_base_call_content_get_streams (TpyBaseCallContent *self)
372
 
{
373
 
  g_return_val_if_fail (TPY_IS_BASE_CALL_CONTENT (self), NULL);
374
 
 
375
 
  return self->priv->streams;
376
 
}
377
 
 
378
 
void
379
 
tpy_base_call_content_add_stream (TpyBaseCallContent *self,
380
 
    TpyBaseCallStream *stream)
381
 
{
382
 
  GPtrArray *paths;
383
 
 
384
 
  g_return_if_fail (TPY_IS_BASE_CALL_CONTENT (self));
385
 
 
386
 
  self->priv->streams = g_list_prepend (self->priv->streams,
387
 
      g_object_ref (stream));
388
 
 
389
 
  paths = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
390
 
 
391
 
  g_ptr_array_add (paths, g_strdup (
392
 
     tpy_base_call_stream_get_object_path (
393
 
         TPY_BASE_CALL_STREAM (stream))));
394
 
  tpy_svc_call_content_emit_streams_added (self, paths);
395
 
  g_ptr_array_unref (paths);
396
 
}
397
 
 
398
 
void
399
 
tpy_base_call_content_remove_stream (TpyBaseCallContent *self,
400
 
    TpyBaseCallStream *stream)
401
 
{
402
 
  TpyBaseCallContentPrivate *priv;
403
 
  GList *l;
404
 
  GPtrArray *paths;
405
 
 
406
 
  g_return_if_fail (TPY_IS_BASE_CALL_CONTENT (self));
407
 
 
408
 
  priv = self->priv;
409
 
 
410
 
  l = g_list_find (priv->streams, stream);
411
 
  g_return_if_fail (l != NULL);
412
 
 
413
 
  priv->streams = g_list_remove_link (priv->streams, l);
414
 
  paths = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
415
 
  g_ptr_array_add (paths, g_strdup (
416
 
     tpy_base_call_stream_get_object_path (
417
 
         TPY_BASE_CALL_STREAM (stream))));
418
 
  tpy_svc_call_content_emit_streams_removed (self, paths);
419
 
  g_ptr_array_unref (paths);
420
 
  g_object_unref (stream);
421
 
}
422
 
 
423
 
static void
424
 
base_call_content_deinit_real (TpyBaseCallContent *self)
425
 
{
426
 
  TpyBaseCallContentPrivate *priv = self->priv;
427
 
 
428
 
  if (priv->deinit_has_run)
429
 
    return;
430
 
 
431
 
  priv->deinit_has_run = TRUE;
432
 
 
433
 
  tp_dbus_daemon_unregister_object (priv->dbus_daemon, G_OBJECT (self));
434
 
  tp_clear_object (&priv->dbus_daemon);
435
 
 
436
 
  g_list_foreach (priv->streams, (GFunc) g_object_unref, NULL);
437
 
  tp_clear_pointer (&priv->streams, g_list_free);
438
 
}
439
 
 
440
 
void
441
 
tpy_base_call_content_deinit (TpyBaseCallContent *self)
442
 
{
443
 
  TpyBaseCallContentClass *klass;
444
 
 
445
 
  g_return_if_fail (TPY_IS_BASE_CALL_CONTENT (self));
446
 
 
447
 
  klass = TPY_BASE_CALL_CONTENT_GET_CLASS (self);
448
 
  g_return_if_fail (klass->deinit != NULL);
449
 
  klass->deinit (self);
450
 
}
451
 
 
452
 
void
453
 
tpy_base_call_content_accepted (TpyBaseCallContent *self)
454
 
{
455
 
  TpyBaseCallContentPrivate *priv = self->priv;
456
 
  GList *l;
457
 
 
458
 
  if (priv->disposition != TPY_CALL_CONTENT_DISPOSITION_INITIAL)
459
 
    return;
460
 
 
461
 
  for (l = priv->streams ; l != NULL; l = g_list_next (l))
462
 
    {
463
 
      TpyBaseCallStream *s = TPY_BASE_CALL_STREAM (l->data);
464
 
 
465
 
      if (tpy_base_call_stream_get_local_sending_state (s) ==
466
 
          TPY_SENDING_STATE_PENDING_SEND)
467
 
        tpy_base_call_stream_set_sending (s, TRUE, NULL);
468
 
    }
469
 
}
470
 
 
471
 
static void
472
 
tpy_call_content_remove (TpySvcCallContent *content,
473
 
    TpyContentRemovalReason reason,
474
 
    const gchar *detailed_removal_reason,
475
 
    const gchar *message,
476
 
    DBusGMethodInvocation *context)
477
 
{
478
 
  /* TODO: actually do something with this reason and message. */
479
 
  DEBUG ("removing content for reason %u, dbus error: %s, message: %s",
480
 
      reason, detailed_removal_reason, message);
481
 
 
482
 
  tpy_svc_call_content_emit_removed (content);
483
 
  /* it doesn't matter if a ::removed signal handler calls deinit as
484
 
   * there are guards around it being called again and breaking, so
485
 
   * let's just call it be sure it's done. */
486
 
  tpy_base_call_content_deinit (TPY_BASE_CALL_CONTENT (content));
487
 
  tpy_svc_call_content_return_from_remove (context);
488
 
}
489
 
 
490
 
static void
491
 
call_content_iface_init (gpointer g_iface, gpointer iface_data)
492
 
{
493
 
  TpySvcCallContentClass *klass =
494
 
    (TpySvcCallContentClass *) g_iface;
495
 
 
496
 
#define IMPLEMENT(x) tpy_svc_call_content_implement_##x (\
497
 
    klass, tpy_call_content_##x)
498
 
  IMPLEMENT(remove);
499
 
#undef IMPLEMENT
500
 
}