2 * Copyright (C) 2007 Elliot Fairweather
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 * Authors: Elliot Fairweather <elliot.fairweather@collabora.co.uk>
22 #include <dbus/dbus-glib.h>
24 #include <telepathy-glib/proxy-subclass.h>
25 #include <telepathy-glib/dbus.h>
27 #include <libmissioncontrol/mc-account.h>
29 #include <extensions/extensions.h>
30 #include <libempathy/empathy-contact-factory.h>
31 #include <libempathy/empathy-debug.h>
32 #include <libempathy/empathy-tp-group.h>
33 #include <libempathy/empathy-utils.h>
35 #include "empathy-tp-call.h"
37 #define DEBUG_DOMAIN "TpCall"
39 #define GET_PRIV(object) (G_TYPE_INSTANCE_GET_PRIVATE \
40 ((object), EMPATHY_TYPE_TP_CALL, EmpathyTpCallPriv))
42 #define STREAM_ENGINE_BUS_NAME "org.freedesktop.Telepathy.StreamEngine"
43 #define STREAM_ENGINE_OBJECT_PATH "/org/freedesktop/Telepathy/StreamEngine"
45 typedef struct _EmpathyTpCallPriv EmpathyTpCallPriv;
47 struct _EmpathyTpCallPriv
49 TpConnection *connection;
51 TpProxy *stream_engine;
52 TpDBusDaemon *dbus_daemon;
53 EmpathyTpGroup *group;
54 EmpathyContact *contact;
57 gboolean stream_engine_running;
59 EmpathyTpCallStream *audio;
60 EmpathyTpCallStream *video;
75 G_DEFINE_TYPE (EmpathyTpCall, empathy_tp_call, G_TYPE_OBJECT)
78 tp_call_add_stream (EmpathyTpCall *call,
83 guint stream_direction)
85 EmpathyTpCallPriv *priv = GET_PRIV (call);
89 case TP_MEDIA_STREAM_TYPE_AUDIO:
90 empathy_debug (DEBUG_DOMAIN,
91 "Audio stream - id: %d, state: %d, direction: %d",
92 stream_id, stream_state, stream_direction);
93 priv->audio->exists = TRUE;
94 priv->audio->id = stream_id;
95 priv->audio->state = stream_state;
96 priv->audio->direction = stream_direction;
97 g_object_notify (G_OBJECT (call), "audio-stream");
99 case TP_MEDIA_STREAM_TYPE_VIDEO:
100 empathy_debug (DEBUG_DOMAIN,
101 "Video stream - id: %d, state: %d, direction: %d",
102 stream_id, stream_state, stream_direction);
103 priv->video->exists = TRUE;
104 priv->video->id = stream_id;
105 priv->video->state = stream_state;
106 priv->video->direction = stream_direction;
107 g_object_notify (G_OBJECT (call), "video-stream");
110 empathy_debug (DEBUG_DOMAIN, "Unknown stream type: %d",
116 tp_call_stream_added_cb (TpChannel *channel,
118 guint contact_handle,
123 empathy_debug (DEBUG_DOMAIN,
124 "Stream added - stream id: %d, contact handle: %d, stream type: %d",
125 stream_id, contact_handle, stream_type);
127 tp_call_add_stream (EMPATHY_TP_CALL (call), stream_id, contact_handle,
128 stream_type, TP_MEDIA_STREAM_STATE_DISCONNECTED,
129 TP_MEDIA_STREAM_DIRECTION_NONE);
133 tp_call_stream_removed_cb (TpChannel *channel,
138 EmpathyTpCallPriv *priv = GET_PRIV (call);
140 empathy_debug (DEBUG_DOMAIN, "Stream removed - stream id: %d", stream_id);
142 if (stream_id == priv->audio->id)
144 priv->audio->exists = FALSE;
145 g_object_notify (call, "audio-stream");
147 else if (stream_id == priv->video->id)
149 priv->video->exists = FALSE;
150 g_object_notify (call, "video-stream");
155 tp_call_stream_state_changed_cb (TpChannel *proxy,
161 EmpathyTpCallPriv *priv = GET_PRIV (call);
163 empathy_debug (DEBUG_DOMAIN,
164 "Stream state changed - stream id: %d, state state: %d",
165 stream_id, stream_state);
167 if (stream_id == priv->audio->id)
169 priv->audio->state = stream_state;
170 g_object_notify (call, "audio-stream");
172 else if (stream_id == priv->video->id)
174 priv->video->state = stream_state;
175 g_object_notify (call, "video-stream");
180 tp_call_stream_direction_changed_cb (TpChannel *channel,
182 guint stream_direction,
187 EmpathyTpCallPriv *priv = GET_PRIV (call);
189 empathy_debug (DEBUG_DOMAIN,
190 "Stream direction changed - stream: %d, direction: %d",
191 stream_id, stream_direction);
193 if (stream_id == priv->audio->id)
195 priv->audio->direction = stream_direction;
196 g_object_notify (call, "audio-stream");
198 else if (stream_id == priv->video->id)
200 priv->video->direction = stream_direction;
201 g_object_notify (call, "video-stream");
206 tp_call_request_streams_cb (TpChannel *channel,
207 const GPtrArray *streams,
216 empathy_debug (DEBUG_DOMAIN, "Error requesting streams: %s", error->message);
220 for (i = 0; i < streams->len; i++)
224 guint contact_handle;
227 guint stream_direction;
229 values = g_ptr_array_index (streams, i);
230 stream_id = g_value_get_uint (g_value_array_get_nth (values, 0));
231 contact_handle = g_value_get_uint (g_value_array_get_nth (values, 1));
232 stream_type = g_value_get_uint (g_value_array_get_nth (values, 2));
233 stream_state = g_value_get_uint (g_value_array_get_nth (values, 3));
234 stream_direction = g_value_get_uint (g_value_array_get_nth (values, 4));
236 tp_call_add_stream (EMPATHY_TP_CALL (call), stream_id, contact_handle,
237 stream_type, stream_state, stream_direction);
242 tp_call_request_streams_for_capabilities (EmpathyTpCall *call,
243 EmpathyCapabilities capabilities)
245 EmpathyTpCallPriv *priv = GET_PRIV (call);
246 GArray *stream_types;
250 empathy_debug (DEBUG_DOMAIN, "Requesting new stream for capabilities %d",
253 stream_types = g_array_new (FALSE, FALSE, sizeof (guint));
254 handle = empathy_contact_get_handle (priv->contact);
256 if (capabilities & EMPATHY_CAPABILITIES_AUDIO)
258 stream_type = TP_MEDIA_STREAM_TYPE_AUDIO;
259 g_array_append_val (stream_types, stream_type);
261 if (capabilities & EMPATHY_CAPABILITIES_VIDEO)
263 stream_type = TP_MEDIA_STREAM_TYPE_VIDEO;
264 g_array_append_val (stream_types, stream_type);
267 tp_cli_channel_type_streamed_media_call_request_streams (priv->channel, -1,
268 handle, stream_types, tp_call_request_streams_cb, NULL, NULL,
271 g_array_free (stream_types, TRUE);
275 tp_call_request_streams (EmpathyTpCall *call)
277 EmpathyTpCallPriv *priv = GET_PRIV (call);
278 EmpathyCapabilities capabilities;
280 empathy_debug (DEBUG_DOMAIN,
281 "Requesting appropriate audio/video streams from contact");
283 /* FIXME: SIP don't have capabilities interface but we know it supports
284 * only audio and not video. */
285 if (!tp_proxy_has_interface_by_id (priv->connection,
286 TP_IFACE_QUARK_CONNECTION_INTERFACE_CAPABILITIES))
287 capabilities = EMPATHY_CAPABILITIES_AUDIO;
289 capabilities = empathy_contact_get_capabilities (priv->contact);
291 tp_call_request_streams_for_capabilities (call, capabilities);
295 tp_call_group_ready_cb (EmpathyTpCall *call)
297 EmpathyTpCallPriv *priv = GET_PRIV (call);
299 GList *local_pendings;
300 GList *remote_pendings;
302 priv->status = EMPATHY_TP_CALL_STATUS_PENDING;
304 members = empathy_tp_group_get_members (priv->group);
305 local_pendings = empathy_tp_group_get_local_pendings (priv->group);
306 remote_pendings = empathy_tp_group_get_remote_pendings (priv->group);
308 if (local_pendings &&
309 empathy_contact_is_user (((EmpathyPendingInfo *) local_pendings->data)->member))
311 empathy_debug (DEBUG_DOMAIN,
312 "Incoming call is ready - %p",
313 ((EmpathyPendingInfo *) local_pendings->data)->member);
314 priv->is_incoming = TRUE;
315 priv->contact = g_object_ref (members->data);
317 else if (remote_pendings && empathy_contact_is_user (members->data))
319 empathy_debug (DEBUG_DOMAIN,
320 "Outgoing call is ready - %p", remote_pendings->data);
321 priv->is_incoming = FALSE;
322 priv->contact = g_object_ref (remote_pendings->data);
323 tp_call_request_streams (call);
326 g_list_foreach (members, (GFunc) g_object_unref, NULL);
327 g_list_free (members);
328 g_list_foreach (local_pendings, (GFunc) empathy_pending_info_free, NULL);
329 g_list_free (local_pendings);
330 g_list_foreach (remote_pendings, (GFunc) g_object_unref, NULL);
331 g_list_free (remote_pendings);
333 g_object_notify (G_OBJECT (call), "is-incoming");
334 g_object_notify (G_OBJECT (call), "contact");
335 g_object_notify (G_OBJECT (call), "status");
339 tp_call_member_added_cb (EmpathyTpGroup *group,
340 EmpathyContact *contact,
341 EmpathyContact *actor,
343 const gchar *message,
346 EmpathyTpCallPriv *priv = GET_PRIV (call);
348 if (priv->status == EMPATHY_TP_CALL_STATUS_PENDING &&
349 ((priv->is_incoming && contact != priv->contact) ||
350 (!priv->is_incoming && contact == priv->contact)))
352 priv->status = EMPATHY_TP_CALL_STATUS_ACCEPTED;
353 g_object_notify (G_OBJECT (call), "status");
358 tp_call_channel_invalidated_cb (TpChannel *channel,
364 EmpathyTpCallPriv *priv = GET_PRIV (call);
366 empathy_debug (DEBUG_DOMAIN, "Channel invalidated: %s", message);
367 priv->status = EMPATHY_TP_CALL_STATUS_CLOSED;
368 g_object_notify (G_OBJECT (call), "status");
372 tp_call_async_cb (TpProxy *proxy,
379 empathy_debug (DEBUG_DOMAIN, "Error %s: %s",
380 user_data, error->message);
385 tp_call_close_channel (EmpathyTpCall *call)
387 EmpathyTpCallPriv *priv = GET_PRIV (call);
389 if (priv->status == EMPATHY_TP_CALL_STATUS_CLOSED)
392 empathy_debug (DEBUG_DOMAIN, "Closing channel");
394 tp_cli_channel_call_close (priv->channel, -1,
395 (tp_cli_channel_callback_for_close) tp_call_async_cb,
396 "closing channel", NULL, G_OBJECT (call));
398 priv->status = EMPATHY_TP_CALL_STATUS_CLOSED;
399 g_object_notify (G_OBJECT (call), "status");
403 tp_call_stream_engine_invalidated_cb (TpProxy *stream_engine,
409 empathy_debug (DEBUG_DOMAIN, "Stream engine proxy invalidated: %s",
411 tp_call_close_channel (call);
415 tp_call_stream_engine_watch_name_owner_cb (TpDBusDaemon *daemon,
417 const gchar *new_owner,
420 EmpathyTpCallPriv *priv = GET_PRIV (call);
422 /* G_STR_EMPTY(new_owner) means either stream-engine has not started yet or
423 * has crashed. We want to close the channel if stream-engine has crashed.
425 empathy_debug (DEBUG_DOMAIN,
426 "Watch SE: name='%s' SE running='%s' new_owner='%s'",
427 name, priv->stream_engine_running ? "yes" : "no",
428 new_owner ? new_owner : "none");
429 if (priv->stream_engine_running && G_STR_EMPTY (new_owner))
431 empathy_debug (DEBUG_DOMAIN, "Stream engine falled off the bus");
432 tp_call_close_channel (call);
436 priv->stream_engine_running = !G_STR_EMPTY (new_owner);
440 tp_call_stream_engine_handle_channel (EmpathyTpCall *call)
442 EmpathyTpCallPriv *priv = GET_PRIV (call);
443 const gchar *channel_type;
444 const gchar *object_path;
448 empathy_debug (DEBUG_DOMAIN, "Revving up the stream engine");
450 priv->stream_engine = g_object_new (TP_TYPE_PROXY,
451 "bus-name", STREAM_ENGINE_BUS_NAME,
452 "dbus-connection", tp_get_bus (),
453 "object-path", STREAM_ENGINE_OBJECT_PATH,
455 tp_proxy_add_interface_by_id (priv->stream_engine,
456 EMP_IFACE_QUARK_STREAM_ENGINE);
457 tp_proxy_add_interface_by_id (priv->stream_engine,
458 EMP_IFACE_QUARK_CHANNEL_HANDLER);
460 g_signal_connect (priv->stream_engine, "invalidated",
461 G_CALLBACK (tp_call_stream_engine_invalidated_cb),
464 /* FIXME: dbus daemon should be unique */
465 priv->dbus_daemon = tp_dbus_daemon_new (tp_get_bus ());
466 tp_dbus_daemon_watch_name_owner (priv->dbus_daemon, STREAM_ENGINE_BUS_NAME,
467 tp_call_stream_engine_watch_name_owner_cb,
470 g_object_get (priv->channel,
471 "channel-type", &channel_type,
472 "object-path", &object_path,
473 "handle_type", &handle_type,
477 emp_cli_channel_handler_call_handle_channel (priv->stream_engine, -1,
478 TP_PROXY (priv->connection)->bus_name,
479 TP_PROXY (priv->connection)->object_path,
480 channel_type, object_path, handle_type, handle,
481 tp_call_async_cb, "calling handle channel", NULL,
486 tp_call_constructor (GType type,
487 guint n_construct_params,
488 GObjectConstructParam *construct_params)
492 EmpathyTpCallPriv *priv;
496 object = G_OBJECT_CLASS (empathy_tp_call_parent_class)->constructor (type,
497 n_construct_params, construct_params);
499 call = EMPATHY_TP_CALL (object);
500 priv = GET_PRIV (call);
502 /* Setup streamed media channel */
503 g_signal_connect (priv->channel, "invalidated",
504 G_CALLBACK (tp_call_channel_invalidated_cb), call);
505 tp_cli_channel_type_streamed_media_connect_to_stream_added (priv->channel,
506 tp_call_stream_added_cb, NULL, NULL, G_OBJECT (call), NULL);
507 tp_cli_channel_type_streamed_media_connect_to_stream_removed (priv->channel,
508 tp_call_stream_removed_cb, NULL, NULL, G_OBJECT (call), NULL);
509 tp_cli_channel_type_streamed_media_connect_to_stream_state_changed (priv->channel,
510 tp_call_stream_state_changed_cb, NULL, NULL, G_OBJECT (call), NULL);
511 tp_cli_channel_type_streamed_media_connect_to_stream_direction_changed (priv->channel,
512 tp_call_stream_direction_changed_cb, NULL, NULL, G_OBJECT (call), NULL);
513 tp_cli_channel_type_streamed_media_call_list_streams (priv->channel, -1,
514 tp_call_request_streams_cb, NULL, NULL, G_OBJECT (call));
516 /* Setup group interface */
517 mc = empathy_mission_control_new ();
518 account = mission_control_get_account_for_tpconnection (mc, priv->connection, NULL);
519 priv->group = empathy_tp_group_new (account, priv->channel);
522 g_signal_connect (G_OBJECT (priv->group), "member-added",
523 G_CALLBACK (tp_call_member_added_cb), call);
525 if (empathy_tp_group_is_ready (priv->group))
526 tp_call_group_ready_cb (call);
528 g_signal_connect_swapped (priv->group, "ready",
529 G_CALLBACK (tp_call_group_ready_cb), call);
531 /* Start stream engine */
532 tp_call_stream_engine_handle_channel (call);
538 tp_call_finalize (GObject *object)
540 EmpathyTpCallPriv *priv = GET_PRIV (object);
542 empathy_debug (DEBUG_DOMAIN, "Finalizing: %p", object);
544 g_slice_free (EmpathyTpCallStream, priv->audio);
545 g_slice_free (EmpathyTpCallStream, priv->video);
546 g_object_unref (priv->group);
548 if (priv->connection != NULL)
549 g_object_unref (priv->connection);
551 if (priv->channel != NULL)
553 g_signal_handlers_disconnect_by_func (priv->channel,
554 tp_call_channel_invalidated_cb, object);
555 g_object_unref (priv->channel);
558 if (priv->stream_engine != NULL)
560 g_signal_handlers_disconnect_by_func (priv->stream_engine,
561 tp_call_stream_engine_invalidated_cb, object);
562 g_object_unref (priv->stream_engine);
565 if (priv->contact != NULL)
566 g_object_unref (priv->contact);
568 if (priv->dbus_daemon != NULL)
570 tp_dbus_daemon_cancel_name_owner_watch (priv->dbus_daemon,
571 STREAM_ENGINE_BUS_NAME,
572 tp_call_stream_engine_watch_name_owner_cb,
574 g_object_unref (priv->dbus_daemon);
577 (G_OBJECT_CLASS (empathy_tp_call_parent_class)->finalize) (object);
581 tp_call_set_property (GObject *object,
586 EmpathyTpCallPriv *priv = GET_PRIV (object);
590 case PROP_CONNECTION:
591 priv->connection = g_value_dup_object (value);
594 priv->channel = g_value_dup_object (value);
597 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
603 tp_call_get_property (GObject *object,
608 EmpathyTpCallPriv *priv = GET_PRIV (object);
612 case PROP_CONNECTION:
613 g_value_set_object (value, priv->connection);
616 g_value_set_object (value, priv->channel);
619 g_value_set_object (value, priv->contact);
621 case PROP_IS_INCOMING:
622 g_value_set_boolean (value, priv->is_incoming);
625 g_value_set_uint (value, priv->status);
627 case PROP_AUDIO_STREAM:
628 g_value_set_pointer (value, priv->audio);
630 case PROP_VIDEO_STREAM:
631 g_value_set_pointer (value, priv->video);
634 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
640 empathy_tp_call_class_init (EmpathyTpCallClass *klass)
642 GObjectClass *object_class = G_OBJECT_CLASS (klass);
646 object_class->constructor = tp_call_constructor;
647 object_class->finalize = tp_call_finalize;
648 object_class->set_property = tp_call_set_property;
649 object_class->get_property = tp_call_get_property;
651 g_type_class_add_private (klass, sizeof (EmpathyTpCallPriv));
653 g_object_class_install_property (object_class, PROP_CONNECTION,
654 g_param_spec_object ("connection", "connection", "connection",
656 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
657 G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
658 g_object_class_install_property (object_class, PROP_CHANNEL,
659 g_param_spec_object ("channel", "channel", "channel",
661 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
662 G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
663 g_object_class_install_property (object_class, PROP_CONTACT,
664 g_param_spec_object ("contact", "Call contact", "Call contact",
665 EMPATHY_TYPE_CONTACT,
666 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
667 g_object_class_install_property (object_class, PROP_IS_INCOMING,
668 g_param_spec_boolean ("is-incoming", "Is media stream incoming",
669 "Is media stream incoming", FALSE, G_PARAM_READABLE |
670 G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
671 g_object_class_install_property (object_class, PROP_STATUS,
672 g_param_spec_uint ("status", "Call status",
673 "Call status", 0, 255, 0, G_PARAM_READABLE | G_PARAM_STATIC_NICK |
674 G_PARAM_STATIC_BLURB));
675 g_object_class_install_property (object_class, PROP_AUDIO_STREAM,
676 g_param_spec_pointer ("audio-stream", "Audio stream data",
678 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
679 g_object_class_install_property (object_class, PROP_VIDEO_STREAM,
680 g_param_spec_pointer ("video-stream", "Video stream data",
682 G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
686 empathy_tp_call_init (EmpathyTpCall *call)
688 EmpathyTpCallPriv *priv = GET_PRIV (call);
690 priv->status = EMPATHY_TP_CALL_STATUS_READYING;
691 priv->contact = NULL;
692 priv->stream_engine_running = FALSE;
693 priv->audio = g_slice_new0 (EmpathyTpCallStream);
694 priv->video = g_slice_new0 (EmpathyTpCallStream);
695 priv->audio->exists = FALSE;
696 priv->video->exists = FALSE;
700 empathy_tp_call_new (TpConnection *connection, TpChannel *channel)
702 g_return_val_if_fail (TP_IS_CONNECTION (connection), NULL);
703 g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL);
705 return g_object_new (EMPATHY_TYPE_TP_CALL,
706 "connection", connection,
712 empathy_tp_call_accept_incoming_call (EmpathyTpCall *call)
714 EmpathyTpCallPriv *priv = GET_PRIV (call);
715 EmpathyContact *self_contact;
717 g_return_if_fail (EMPATHY_IS_TP_CALL (call));
718 g_return_if_fail (priv->status == EMPATHY_TP_CALL_STATUS_PENDING);
720 empathy_debug (DEBUG_DOMAIN, "Accepting incoming call");
722 self_contact = empathy_tp_group_get_self_contact (priv->group);
723 empathy_tp_group_add_member (priv->group, self_contact, NULL);
724 g_object_unref (self_contact);
728 empathy_tp_call_request_video_stream_direction (EmpathyTpCall *call,
731 EmpathyTpCallPriv *priv = GET_PRIV (call);
734 g_return_if_fail (EMPATHY_IS_TP_CALL (call));
735 g_return_if_fail (priv->status == EMPATHY_TP_CALL_STATUS_ACCEPTED);
737 empathy_debug (DEBUG_DOMAIN,
738 "Requesting video stream direction - is_sending: %d", is_sending);
740 if (!priv->video->exists)
742 tp_call_request_streams_for_capabilities (call, EMPATHY_CAPABILITIES_VIDEO);
747 new_direction = priv->video->direction | TP_MEDIA_STREAM_DIRECTION_SEND;
749 new_direction = priv->video->direction & ~TP_MEDIA_STREAM_DIRECTION_SEND;
751 tp_cli_channel_type_streamed_media_call_request_stream_direction (priv->channel,
752 -1, priv->video->id, new_direction,
753 (tp_cli_channel_type_streamed_media_callback_for_request_stream_direction)
754 tp_call_async_cb, NULL, NULL, G_OBJECT (call));
758 empathy_tp_call_add_preview_video (EmpathyTpCall *call,
759 guint preview_video_socket_id)
761 EmpathyTpCallPriv *priv = GET_PRIV (call);
763 g_return_if_fail (EMPATHY_IS_TP_CALL (call));
764 g_return_if_fail (priv->status != EMPATHY_TP_CALL_STATUS_CLOSED);
766 empathy_debug (DEBUG_DOMAIN, "Adding preview video");
768 emp_cli_stream_engine_call_add_preview_window (priv->stream_engine, -1,
769 preview_video_socket_id,
771 "adding preview window", NULL,
776 empathy_tp_call_remove_preview_video (EmpathyTpCall *call,
777 guint preview_video_socket_id)
779 EmpathyTpCallPriv *priv = GET_PRIV (call);
781 g_return_if_fail (EMPATHY_IS_TP_CALL (call));
782 g_return_if_fail (priv->status != EMPATHY_TP_CALL_STATUS_CLOSED);
784 empathy_debug (DEBUG_DOMAIN, "Removing preview video");
786 emp_cli_stream_engine_call_remove_preview_window (priv->stream_engine, -1,
787 preview_video_socket_id,
789 "removing preview window", NULL,
794 empathy_tp_call_add_output_video (EmpathyTpCall *call,
795 guint output_video_socket_id)
797 EmpathyTpCallPriv *priv = GET_PRIV (call);
799 g_return_if_fail (EMPATHY_IS_TP_CALL (call));
800 g_return_if_fail (priv->status != EMPATHY_TP_CALL_STATUS_CLOSED);
802 empathy_debug (DEBUG_DOMAIN, "Adding output video - socket: %d",
803 output_video_socket_id);
805 emp_cli_stream_engine_call_set_output_window (priv->stream_engine, -1,
806 dbus_g_proxy_get_path (DBUS_G_PROXY (priv->channel)),
807 priv->video->id, output_video_socket_id,
809 "setting output window", NULL,
814 empathy_tp_call_set_output_volume (EmpathyTpCall *call,
817 EmpathyTpCallPriv *priv = GET_PRIV (call);
819 g_return_if_fail (EMPATHY_IS_TP_CALL (call));
820 g_return_if_fail (priv->status != EMPATHY_TP_CALL_STATUS_CLOSED);
822 empathy_debug (DEBUG_DOMAIN, "Setting output volume: %d", volume);
824 emp_cli_stream_engine_call_set_output_volume (priv->stream_engine, -1,
825 dbus_g_proxy_get_path (DBUS_G_PROXY (priv->channel)),
826 priv->audio->id, volume,
828 "setting output volume", NULL,
833 empathy_tp_call_mute_output (EmpathyTpCall *call,
836 EmpathyTpCallPriv *priv = GET_PRIV (call);
838 g_return_if_fail (EMPATHY_IS_TP_CALL (call));
839 g_return_if_fail (priv->status != EMPATHY_TP_CALL_STATUS_CLOSED);
841 empathy_debug (DEBUG_DOMAIN, "Setting output mute: %d", is_muted);
843 emp_cli_stream_engine_call_mute_output (priv->stream_engine, -1,
844 dbus_g_proxy_get_path (DBUS_G_PROXY (priv->channel)),
845 priv->audio->id, is_muted,
847 "muting output", NULL,
852 empathy_tp_call_mute_input (EmpathyTpCall *call,
855 EmpathyTpCallPriv *priv = GET_PRIV (call);
857 g_return_if_fail (EMPATHY_IS_TP_CALL (call));
858 g_return_if_fail (priv->status != EMPATHY_TP_CALL_STATUS_CLOSED);
860 empathy_debug (DEBUG_DOMAIN, "Setting input mute: %d", is_muted);
862 emp_cli_stream_engine_call_mute_input (priv->stream_engine, -1,
863 dbus_g_proxy_get_path (DBUS_G_PROXY (priv->channel)),
864 priv->audio->id, is_muted,
866 "muting input", NULL,