]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-share-my-desktop.c
Merge commit 'staz/dnd'
[empathy.git] / libempathy-gtk / empathy-share-my-desktop.c
1 /*
2  * © 2009, Collabora Ltd
3  *
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.
8  *
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.
13  *
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
17  *
18  * Authors: Arnaud Maillet <arnaud.maillet@collabora.co.uk>
19  */
20
21 #include <gtk/gtk.h>
22
23 #include <dbus/dbus-glib.h>
24 #include <telepathy-glib/util.h>
25 #include <telepathy-glib/contact.h>
26 #include <telepathy-glib/channel.h>
27 #include <telepathy-glib/interfaces.h>
28 #define DEBUG_FLAG EMPATHY_DEBUG_SHARE_DESKTOP
29 #include <libempathy/empathy-debug.h>
30
31 #include "empathy-share-my-desktop.h"
32
33 #define DBUS_SERVICE "org.gnome.Vino"
34 #define DBUS_INTERFACE "org.gnome.VinoScreen"
35
36 typedef struct  {
37   TpContact *contact;
38   TpChannel *channel;
39   gulong signal_invalidated_id;
40 } EmpathyShareMyDesktopPrivate;
41
42
43 static void
44 empathy_share_my_desktop_tube_invalidated (TpProxy *channel,
45     guint domain,
46     gint code,
47     gchar *message,
48     gpointer object)
49 {
50   EmpathyShareMyDesktopPrivate *data = (EmpathyShareMyDesktopPrivate *) object;
51
52   DEBUG ("Tube is invalidated");
53
54   g_signal_handler_disconnect (G_OBJECT (data->channel),
55                data->signal_invalidated_id);
56
57   if (data->channel != NULL)
58     {
59       g_object_unref (data->channel);
60       data->channel = NULL;
61     }
62
63   g_slice_free (EmpathyShareMyDesktopPrivate, data);
64 }
65
66 static void
67 empathy_share_my_desktop_channel_ready (TpChannel *channel,
68     const GError *error_failed,
69     gpointer object)
70 {
71   EmpathyShareMyDesktopPrivate *data = (EmpathyShareMyDesktopPrivate *) object;
72   TpConnection *connection;
73   gchar * connection_path;
74   gchar * tube_path;
75   DBusGConnection *dbus_g_connection;
76   GHashTable *channel_properties;
77   DBusGProxy *proxy;
78   GError *error = NULL;
79   GdkScreen *screen;
80   gchar *obj_path;
81   GtkWidget *window;
82
83   if (channel == NULL)
84   {
85       DEBUG ("The channel is not ready: %s", error_failed->message);
86       return;
87   }
88
89   data->channel = channel;
90
91   data->signal_invalidated_id = g_signal_connect (G_OBJECT (channel),
92       "invalidated", G_CALLBACK (empathy_share_my_desktop_tube_invalidated),
93       data);
94
95   dbus_g_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
96
97   if (dbus_g_connection == NULL)
98     {
99       DEBUG ("Failed to open connection to bus: %s", error->message);
100       g_clear_error (&error);
101       return;
102     }
103
104   screen = gdk_screen_get_default ();
105   obj_path = g_strdup_printf ("/org/gnome/vino/screens/%d",
106       gdk_screen_get_number (screen));
107
108   proxy = dbus_g_proxy_new_for_name (dbus_g_connection, DBUS_SERVICE,
109       obj_path, DBUS_INTERFACE);
110
111   connection = tp_channel_borrow_connection (channel);
112
113   g_object_get (connection, "object-path", &connection_path, NULL);
114
115   DEBUG ("connection path : %s", connection_path);
116
117   g_object_get (channel, "object-path", &tube_path, "channel-properties",
118       &channel_properties, NULL);
119
120   DEBUG ("tube path : %s", tube_path);
121
122   if (!dbus_g_proxy_call (proxy, "ShareWithTube", &error,
123       DBUS_TYPE_G_OBJECT_PATH, connection_path,
124       DBUS_TYPE_G_OBJECT_PATH, tube_path,
125       dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
126       channel_properties,
127       G_TYPE_INVALID, G_TYPE_INVALID))
128     {
129       window = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
130           GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
131           "Vino doesn't support telepathy");
132       gtk_dialog_run (GTK_DIALOG (window));
133       gtk_widget_destroy (window);
134       DEBUG ("Failed to request name: %s",
135           error ? error->message : "No error given");
136       g_clear_error (&error);
137     }
138
139   g_hash_table_unref (channel_properties);
140   g_free (connection_path);
141   g_free (tube_path);
142   g_free (obj_path);
143   g_object_unref (proxy);
144 }
145
146 static void
147 empathy_share_my_desktop_create_channel_cb (TpConnection *connection,
148     const gchar *object_path,
149     GHashTable *channel_properties,
150     const GError *error_failed,
151     gpointer user_data,
152     GObject *object)
153 {
154   EmpathyShareMyDesktopPrivate *data = (EmpathyShareMyDesktopPrivate *)
155       user_data;
156
157   TpChannel *channel;
158   GError *error = NULL;
159
160   if (object_path == NULL)
161   {
162       DEBUG ("CreateChannel failed: %s", error_failed->message);
163       return;
164   }
165
166   DEBUG ("Offering a new stream tube");
167
168   channel = tp_channel_new_from_properties (connection, object_path,
169       channel_properties, &error);
170
171   if (channel == NULL)
172     {
173       DEBUG ("Error requesting channel: %s", error->message);
174       g_clear_error (&error);
175       return;
176     }
177
178   tp_channel_call_when_ready (channel,
179       empathy_share_my_desktop_channel_ready, data);
180 }
181
182 static void
183 empathy_share_my_desktop_connection_ready (TpConnection *connection,
184     const GError *error,
185     gpointer object)
186 {
187   EmpathyShareMyDesktopPrivate *data = (EmpathyShareMyDesktopPrivate *) object;
188   GHashTable *request;
189   GValue *value;
190
191   if (connection == NULL)
192     {
193       DEBUG ("The connection is not ready: %s", error->message);
194       return;
195     }
196
197   request = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
198       (GDestroyNotify) tp_g_value_slice_free);
199
200   /* org.freedesktop.Telepathy.Channel.ChannelType */
201   value = tp_g_value_slice_new_static_string
202       (TP_IFACE_CHANNEL_TYPE_STREAM_TUBE);
203   g_hash_table_insert (request, TP_IFACE_CHANNEL ".ChannelType", value);
204
205   /* org.freedesktop.Telepathy.Channel.TargetHandleType */
206   value = tp_g_value_slice_new_uint (TP_HANDLE_TYPE_CONTACT);
207   g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandleType", value);
208
209   /* org.freedesktop.Telepathy.Channel.TargetHandleType */
210   value = tp_g_value_slice_new_uint (tp_contact_get_handle
211       (data->contact));
212   g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandle", value);
213
214   /* org.freedesktop.Telepathy.Channel.Type.StreamTube.Service */
215   value = tp_g_value_slice_new_static_string ("rfb");
216   g_hash_table_insert (request,
217       TP_IFACE_CHANNEL_TYPE_STREAM_TUBE  ".Service",
218       value);
219
220   tp_cli_connection_interface_requests_call_create_channel
221       (connection, -1, request, empathy_share_my_desktop_create_channel_cb,
222       data, NULL, NULL);
223
224   g_hash_table_destroy (request);
225 }
226
227 void
228 empathy_share_my_desktop_share_with_contact (EmpathyContact *contact)
229 {
230   TpConnection *connection;
231   EmpathyShareMyDesktopPrivate *data;
232   data = g_slice_new (EmpathyShareMyDesktopPrivate);
233   data->contact = empathy_contact_get_tp_contact (contact);
234
235   DEBUG ("Creation of ShareMyDesktop");
236
237   if (!TP_IS_CONTACT (data->contact))
238     {
239       DEBUG ("It's not a tp contact");
240       return;
241     }
242
243   connection = tp_contact_get_connection (data->contact);
244
245   tp_connection_call_when_ready (connection,
246       empathy_share_my_desktop_connection_ready, data);
247 }