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

« back to all changes in this revision

Viewing changes to telepathy-yell/telepathy-yell/call-content-codec-offer.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
 
 * call-content-codec-offer.c - Source for TpyCallContentCodecOffer
3
 
 * Copyright (C) 2009 Collabora Ltd.
4
 
 * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
5
 
 *
6
 
 * This library is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the GNU Lesser General Public
8
 
 * License as published by the Free Software Foundation; either
9
 
 * version 2.1 of the License, or (at your option) any later version.
10
 
 *
11
 
 * This library is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 
 * Lesser General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU Lesser General Public
17
 
 * License along with this library; if not, write to the Free Software
18
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 
 */
20
 
 
21
 
 
22
 
#include <stdio.h>
23
 
#include <stdlib.h>
24
 
 
25
 
#include <glib.h>
26
 
#include <telepathy-glib/dbus.h>
27
 
#include <telepathy-glib/dbus-properties-mixin.h>
28
 
#include <telepathy-glib/svc-properties-interface.h>
29
 
 
30
 
#include "call-content-codec-offer.h"
31
 
#include "extensions.h"
32
 
 
33
 
#define DEBUG_FLAG TPY_DEBUG_CALL
34
 
#include "debug.h"
35
 
 
36
 
static void call_content_codec_offer_iface_init (gpointer, gpointer);
37
 
 
38
 
G_DEFINE_TYPE_WITH_CODE(TpyCallContentCodecOffer,
39
 
  tpy_call_content_codec_offer,
40
 
  G_TYPE_OBJECT,
41
 
  G_IMPLEMENT_INTERFACE (TPY_TYPE_SVC_CALL_CONTENT_CODEC_OFFER,
42
 
        call_content_codec_offer_iface_init);
43
 
   G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
44
 
    tp_dbus_properties_mixin_iface_init);
45
 
  );
46
 
 
47
 
/* properties */
48
 
enum
49
 
{
50
 
  PROP_OBJECT_PATH = 1,
51
 
  PROP_INTERFACES,
52
 
  PROP_REMOTE_CONTACT_CODECS,
53
 
  PROP_REMOTE_CONTACT
54
 
};
55
 
 
56
 
/* private structure */
57
 
struct _TpyCallContentCodecOfferPrivate
58
 
{
59
 
  gboolean dispose_has_run;
60
 
 
61
 
  TpDBusDaemon *bus;
62
 
  gchar *object_path;
63
 
 
64
 
  TpHandle contact;
65
 
  GPtrArray *codecs;
66
 
 
67
 
  GSimpleAsyncResult *result;
68
 
  GCancellable *cancellable;
69
 
  guint handler_id;
70
 
};
71
 
 
72
 
#define TPY_CALL_CONTENT_CODEC_OFFER_GET_PRIVATE(o) \
73
 
    (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
74
 
    TPY_TYPE_CALL_CONTENT_CODEC_OFFER, TpyCallContentCodecOfferPrivate))
75
 
 
76
 
static void
77
 
tpy_call_content_codec_offer_init (TpyCallContentCodecOffer *self)
78
 
{
79
 
  TpyCallContentCodecOfferPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
80
 
      TPY_TYPE_CALL_CONTENT_CODEC_OFFER,
81
 
      TpyCallContentCodecOfferPrivate);
82
 
 
83
 
  self->priv = priv;
84
 
  priv->bus = tp_dbus_daemon_dup (NULL);
85
 
}
86
 
 
87
 
static void tpy_call_content_codec_offer_dispose (GObject *object);
88
 
static void tpy_call_content_codec_offer_finalize (GObject *object);
89
 
 
90
 
static const gchar *interfaces[] = {
91
 
    NULL
92
 
};
93
 
 
94
 
static void
95
 
tpy_call_content_codec_offer_get_property (GObject    *object,
96
 
    guint       property_id,
97
 
    GValue     *value,
98
 
    GParamSpec *pspec)
99
 
{
100
 
  TpyCallContentCodecOffer *offer =
101
 
    TPY_CALL_CONTENT_CODEC_OFFER (object);
102
 
  TpyCallContentCodecOfferPrivate *priv = offer->priv;
103
 
 
104
 
  switch (property_id)
105
 
    {
106
 
      case PROP_OBJECT_PATH:
107
 
        g_value_set_string (value, priv->object_path);
108
 
        break;
109
 
      case PROP_INTERFACES:
110
 
        g_value_set_boxed (value, interfaces);
111
 
        break;
112
 
      case PROP_REMOTE_CONTACT_CODECS:
113
 
        g_value_set_boxed (value, priv->codecs);
114
 
        break;
115
 
      case PROP_REMOTE_CONTACT:
116
 
        g_value_set_uint (value, priv->contact);
117
 
        break;
118
 
      default:
119
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
120
 
        break;
121
 
    }
122
 
}
123
 
 
124
 
static void
125
 
tpy_call_content_codec_offer_set_property (GObject *object,
126
 
    guint property_id,
127
 
    const GValue *value,
128
 
    GParamSpec *pspec)
129
 
{
130
 
  TpyCallContentCodecOffer *content =
131
 
    TPY_CALL_CONTENT_CODEC_OFFER (object);
132
 
  TpyCallContentCodecOfferPrivate *priv = content->priv;
133
 
 
134
 
  switch (property_id)
135
 
    {
136
 
      case PROP_OBJECT_PATH:
137
 
        priv->object_path = g_value_dup_string (value);
138
 
        g_assert (priv->object_path != NULL);
139
 
        break;
140
 
      case PROP_REMOTE_CONTACT_CODECS:
141
 
        priv->codecs = g_value_dup_boxed (value);
142
 
        break;
143
 
      case PROP_REMOTE_CONTACT:
144
 
        priv->contact = g_value_get_uint (value);
145
 
        break;
146
 
      default:
147
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
148
 
        break;
149
 
    }
150
 
}
151
 
 
152
 
static void
153
 
tpy_call_content_codec_offer_class_init (
154
 
  TpyCallContentCodecOfferClass *tpy_call_content_codec_offer_class)
155
 
{
156
 
  GObjectClass *object_class =
157
 
    G_OBJECT_CLASS (tpy_call_content_codec_offer_class);
158
 
  GParamSpec *spec;
159
 
 
160
 
  static TpDBusPropertiesMixinPropImpl codec_offer_props[] = {
161
 
    { "Interfaces", "interfaces", NULL },
162
 
    { "RemoteContactCodecs", "remote-contact-codecs", NULL },
163
 
    { "RemoteContact", "remote-contact", NULL },
164
 
    { NULL }
165
 
  };
166
 
 
167
 
  static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
168
 
      { TPY_IFACE_CALL_CONTENT_CODEC_OFFER,
169
 
        tp_dbus_properties_mixin_getter_gobject_properties,
170
 
        NULL,
171
 
        codec_offer_props,
172
 
      },
173
 
      { NULL }
174
 
  };
175
 
 
176
 
 
177
 
  g_type_class_add_private (tpy_call_content_codec_offer_class,
178
 
    sizeof (TpyCallContentCodecOfferPrivate));
179
 
 
180
 
  object_class->get_property = tpy_call_content_codec_offer_get_property;
181
 
  object_class->set_property = tpy_call_content_codec_offer_set_property;
182
 
 
183
 
  object_class->dispose = tpy_call_content_codec_offer_dispose;
184
 
  object_class->finalize = tpy_call_content_codec_offer_finalize;
185
 
 
186
 
  spec = g_param_spec_string ("object-path", "D-Bus object path",
187
 
      "The D-Bus object path used for this "
188
 
      "object on the bus.",
189
 
      NULL,
190
 
      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
191
 
  g_object_class_install_property (object_class, PROP_OBJECT_PATH, spec);
192
 
 
193
 
  spec = g_param_spec_boxed ("interfaces",
194
 
      "Interfaces",
195
 
      "Extra interfaces provided by this codec offer",
196
 
      G_TYPE_STRV,
197
 
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
198
 
  g_object_class_install_property (object_class, PROP_INTERFACES,
199
 
      spec);
200
 
 
201
 
  spec = g_param_spec_boxed ("remote-contact-codecs",
202
 
      "RemoteContactCodecs",
203
 
      "A list of codecs the remote contact supports",
204
 
      TPY_ARRAY_TYPE_CODEC_LIST,
205
 
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
206
 
  g_object_class_install_property (object_class, PROP_REMOTE_CONTACT_CODECS,
207
 
      spec);
208
 
 
209
 
  spec = g_param_spec_uint ("remote-contact",
210
 
      "RemoteContact",
211
 
      "The contact handle that this codec offer applies to",
212
 
      0, G_MAXUINT, 0,
213
 
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
214
 
  g_object_class_install_property (object_class, PROP_REMOTE_CONTACT,
215
 
      spec);
216
 
 
217
 
  tpy_call_content_codec_offer_class->dbus_props_class.interfaces
218
 
    = prop_interfaces;
219
 
  tp_dbus_properties_mixin_class_init (object_class,
220
 
      G_STRUCT_OFFSET (TpyCallContentCodecOfferClass, dbus_props_class));
221
 
}
222
 
 
223
 
void
224
 
tpy_call_content_codec_offer_dispose (GObject *object)
225
 
{
226
 
  TpyCallContentCodecOffer *self = TPY_CALL_CONTENT_CODEC_OFFER (object);
227
 
  TpyCallContentCodecOfferPrivate *priv = self->priv;
228
 
 
229
 
  g_assert (priv->result == NULL);
230
 
 
231
 
  if (priv->dispose_has_run)
232
 
    return;
233
 
 
234
 
  priv->dispose_has_run = TRUE;
235
 
 
236
 
  if (priv->codecs != NULL)
237
 
    {
238
 
      /* dbus-glib :( */
239
 
      g_boxed_free (TPY_ARRAY_TYPE_CODEC_LIST, priv->codecs);
240
 
    }
241
 
  priv->codecs = NULL;
242
 
 
243
 
  g_object_unref (priv->bus);
244
 
  priv->bus = NULL;
245
 
 
246
 
  /* release any references held by the object here */
247
 
  if (G_OBJECT_CLASS (tpy_call_content_codec_offer_parent_class)->dispose)
248
 
    G_OBJECT_CLASS (tpy_call_content_codec_offer_parent_class)->dispose (
249
 
      object);
250
 
}
251
 
 
252
 
void
253
 
tpy_call_content_codec_offer_finalize (GObject *object)
254
 
{
255
 
  TpyCallContentCodecOffer *self = TPY_CALL_CONTENT_CODEC_OFFER (object);
256
 
  TpyCallContentCodecOfferPrivate *priv = self->priv;
257
 
 
258
 
  g_free (priv->object_path);
259
 
  /* free any data held directly by the object here */
260
 
 
261
 
  G_OBJECT_CLASS (tpy_call_content_codec_offer_parent_class)->finalize (
262
 
    object);
263
 
}
264
 
 
265
 
static void
266
 
tpy_call_content_codec_offer_accept (TpySvcCallContentCodecOffer *iface,
267
 
    const GPtrArray *codecs,
268
 
    DBusGMethodInvocation *context)
269
 
{
270
 
  TpyCallContentCodecOffer *self = TPY_CALL_CONTENT_CODEC_OFFER (iface);
271
 
  TpyCallContentCodecOfferPrivate *priv = self->priv;
272
 
 
273
 
  g_return_if_fail (priv->bus != NULL);
274
 
 
275
 
  DEBUG ("%s was accepted", priv->object_path);
276
 
 
277
 
  if (priv->cancellable != NULL)
278
 
    {
279
 
      g_cancellable_disconnect (priv->cancellable, priv->handler_id);
280
 
      g_object_unref (priv->cancellable);
281
 
      priv->cancellable = NULL;
282
 
      priv->handler_id = 0;
283
 
    }
284
 
 
285
 
  g_simple_async_result_set_op_res_gpointer (priv->result,
286
 
    (gpointer) codecs, NULL);
287
 
  g_simple_async_result_complete (priv->result);
288
 
  g_object_unref (priv->result);
289
 
  priv->result = NULL;
290
 
 
291
 
  tpy_svc_call_content_codec_offer_return_from_accept (context);
292
 
 
293
 
  tp_dbus_daemon_unregister_object (priv->bus, G_OBJECT (self));
294
 
}
295
 
 
296
 
static void
297
 
tpy_call_content_codec_offer_reject (TpySvcCallContentCodecOffer *iface,
298
 
    DBusGMethodInvocation *context)
299
 
{
300
 
  TpyCallContentCodecOffer *self = TPY_CALL_CONTENT_CODEC_OFFER (iface);
301
 
  TpyCallContentCodecOfferPrivate *priv = self->priv;
302
 
 
303
 
  g_return_if_fail (priv->bus != NULL);
304
 
 
305
 
  DEBUG ("%s was rejected", priv->object_path);
306
 
 
307
 
  if (priv->cancellable != NULL)
308
 
    {
309
 
      g_cancellable_disconnect (priv->cancellable, priv->handler_id);
310
 
      g_object_unref (priv->cancellable);
311
 
      priv->cancellable = NULL;
312
 
      priv->handler_id = 0;
313
 
    }
314
 
 
315
 
  g_simple_async_result_set_error (priv->result,
316
 
      G_IO_ERROR, G_IO_ERROR_FAILED, "Codec offer was rejected");
317
 
  g_simple_async_result_complete (priv->result);
318
 
  g_object_unref (priv->result);
319
 
  priv->result = NULL;
320
 
 
321
 
  tpy_svc_call_content_codec_offer_return_from_reject (context);
322
 
 
323
 
  tp_dbus_daemon_unregister_object (priv->bus, G_OBJECT (self));
324
 
}
325
 
 
326
 
static void
327
 
call_content_codec_offer_iface_init (gpointer iface, gpointer data)
328
 
{
329
 
  TpySvcCallContentCodecOfferClass *klass =
330
 
    (TpySvcCallContentCodecOfferClass *) iface;
331
 
 
332
 
#define IMPLEMENT(x) tpy_svc_call_content_codec_offer_implement_##x (\
333
 
    klass, tpy_call_content_codec_offer_##x)
334
 
  IMPLEMENT(accept);
335
 
  IMPLEMENT(reject);
336
 
#undef IMPLEMENT
337
 
}
338
 
 
339
 
TpyCallContentCodecOffer *
340
 
tpy_call_content_codec_offer_new (const gchar *object_path,
341
 
  TpHandle remote_contact,
342
 
  GPtrArray *codecs)
343
 
{
344
 
  return g_object_new (TPY_TYPE_CALL_CONTENT_CODEC_OFFER,
345
 
    "object-path", object_path,
346
 
    "remote-contact", remote_contact,
347
 
    "remote-contact-codecs", codecs,
348
 
    NULL);
349
 
}
350
 
 
351
 
static void
352
 
cancelled_cb (GCancellable *cancellable, gpointer user_data)
353
 
{
354
 
  TpyCallContentCodecOffer *offer = user_data;
355
 
  TpyCallContentCodecOfferPrivate *priv = offer->priv;
356
 
 
357
 
  g_return_if_fail (priv->bus != NULL);
358
 
 
359
 
  tp_dbus_daemon_unregister_object (priv->bus, G_OBJECT (offer));
360
 
 
361
 
  g_simple_async_result_set_error (priv->result,
362
 
      G_IO_ERROR, G_IO_ERROR_CANCELLED, "Offer cancelled");
363
 
  g_simple_async_result_complete_in_idle (priv->result);
364
 
 
365
 
  g_object_unref (priv->cancellable);
366
 
  g_object_unref (priv->result);
367
 
  priv->result = NULL;
368
 
  priv->cancellable = NULL;
369
 
  priv->handler_id = 0;
370
 
}
371
 
 
372
 
void
373
 
tpy_call_content_codec_offer_offer (TpyCallContentCodecOffer *offer,
374
 
  GCancellable *cancellable,
375
 
  GAsyncReadyCallback callback,
376
 
  gpointer user_data)
377
 
{
378
 
  TpyCallContentCodecOfferPrivate *priv = offer->priv;
379
 
 
380
 
  g_return_if_fail (priv->bus != NULL);
381
 
 
382
 
  /* FIXME implement cancellable support */
383
 
  if (G_UNLIKELY (priv->result != NULL))
384
 
    goto pending;
385
 
 
386
 
  priv->result = g_simple_async_result_new (G_OBJECT (offer),
387
 
    callback, user_data, tpy_call_content_codec_offer_offer_finish);
388
 
 
389
 
  /* register object on the bus */
390
 
  DEBUG ("Registering %s", priv->object_path);
391
 
  tp_dbus_daemon_register_object (priv->bus, priv->object_path,
392
 
    G_OBJECT (offer));
393
 
 
394
 
  if (cancellable != NULL)
395
 
    {
396
 
      priv->cancellable = cancellable;
397
 
      priv->handler_id = g_cancellable_connect (
398
 
          cancellable, G_CALLBACK (cancelled_cb), offer, NULL);
399
 
    }
400
 
 
401
 
  return;
402
 
 
403
 
pending:
404
 
  g_simple_async_report_error_in_idle (G_OBJECT (offer), callback, user_data,
405
 
    G_IO_ERROR, G_IO_ERROR_PENDING, "Another offer operation is pending");
406
 
}
407
 
 
408
 
GPtrArray *
409
 
tpy_call_content_codec_offer_offer_finish (
410
 
  TpyCallContentCodecOffer *offer,
411
 
  GAsyncResult *result,
412
 
  GError **error)
413
 
{
414
 
  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
415
 
      error))
416
 
    return FALSE;
417
 
 
418
 
  g_return_val_if_fail (g_simple_async_result_is_valid (result,
419
 
    G_OBJECT (offer), tpy_call_content_codec_offer_offer_finish),
420
 
    NULL);
421
 
 
422
 
  return g_simple_async_result_get_op_res_gpointer (
423
 
    G_SIMPLE_ASYNC_RESULT (result));
424
 
}