~ubuntu-branches/ubuntu/vivid/vino/vivid-proposed

« back to all changes in this revision

Viewing changes to .pc/revert_use_prompt_notification.patch/server/vino-prompt.c

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher
  • Date: 2013-11-18 15:53:41 UTC
  • mfrom: (1.4.8)
  • Revision ID: package-import@ubuntu.com-20131118155341-u7aet62hkfzomvi6
Tags: 3.8.1-0ubuntu1
* New upstream version, drop changes included in the new version
* debian/patches/revert_use_prompt_notification.patch:
  - revert upstream change to use a notification with actions to accept or
    deny clients, since notify-osd doesn't support those, we keep using
    the old standalone dialog instead
* debian/patches/git_tls_read.patch:
  - "Fix reading of TLS data to account for cached data"

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2003 Sun Microsystems, Inc.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License as
 
6
 * published by the Free Software Foundation; either version 2 of the
 
7
 * License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful, but
 
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
17
 * 02111-1307, USA.
 
18
 *
 
19
 * Authors:
 
20
 *      Mark McLoughlin <mark@skynet.ie>
 
21
 */
 
22
 
 
23
#include <config.h>
 
24
 
 
25
#include "vino-prompt.h"
 
26
 
 
27
#include <gtk/gtk.h>
 
28
#include <libnotify/notify.h>
 
29
#include "vino-util.h"
 
30
#include "vino-enums.h"
 
31
#include "vino-marshal.h"
 
32
 
 
33
struct _VinoPromptPrivate
 
34
{
 
35
  GdkScreen          *screen;
 
36
  NotifyNotification *notification;
 
37
  rfbClientPtr        current_client;
 
38
  GSList             *pending_clients;
 
39
};
 
40
 
 
41
enum
 
42
{
 
43
  PROP_0,
 
44
  PROP_SCREEN
 
45
};
 
46
 
 
47
enum
 
48
{
 
49
  RESPONSE,
 
50
  LAST_SIGNAL
 
51
};
 
52
 
 
53
static gboolean vino_prompt_display (VinoPrompt   *prompt,
 
54
                                     rfbClientPtr  rfb_client);
 
55
 
 
56
static guint prompt_signals [LAST_SIGNAL] = { 0 };
 
57
 
 
58
G_DEFINE_TYPE (VinoPrompt, vino_prompt, G_TYPE_OBJECT);
 
59
 
 
60
static void
 
61
clear_notification (VinoPrompt *prompt)
 
62
{
 
63
  if (prompt->priv->notification)
 
64
    notify_notification_close (prompt->priv->notification, NULL);
 
65
  g_clear_object (&prompt->priv->notification);
 
66
}
 
67
 
 
68
static void
 
69
vino_prompt_finalize (GObject *object)
 
70
{
 
71
  VinoPrompt *prompt = VINO_PROMPT (object);
 
72
 
 
73
  g_slist_free (prompt->priv->pending_clients);
 
74
  prompt->priv->pending_clients = NULL;
 
75
 
 
76
  clear_notification (prompt);
 
77
 
 
78
  g_free (prompt->priv);
 
79
  prompt->priv = NULL;
 
80
 
 
81
  if (G_OBJECT_CLASS (vino_prompt_parent_class)->finalize)
 
82
    G_OBJECT_CLASS (vino_prompt_parent_class)->finalize (object);
 
83
}
 
84
 
 
85
static void
 
86
vino_prompt_set_property (GObject      *object,
 
87
                          guint         prop_id,
 
88
                          const GValue *value,
 
89
                          GParamSpec   *pspec)
 
90
{
 
91
  VinoPrompt *prompt = VINO_PROMPT (object);
 
92
 
 
93
  switch (prop_id)
 
94
    {
 
95
    case PROP_SCREEN:
 
96
      vino_prompt_set_screen (prompt, g_value_get_object (value));
 
97
      break;
 
98
    default:
 
99
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
100
      break;
 
101
    }
 
102
}
 
103
 
 
104
static void
 
105
vino_prompt_get_property (GObject    *object,
 
106
                          guint       prop_id,
 
107
                          GValue     *value,
 
108
                          GParamSpec *pspec)
 
109
{
 
110
  VinoPrompt *prompt = VINO_PROMPT (object);
 
111
 
 
112
  switch (prop_id)
 
113
    {
 
114
    case PROP_SCREEN:
 
115
      g_value_set_object (value, prompt->priv->screen);
 
116
      break;
 
117
    default:
 
118
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
119
      break;
 
120
    }
 
121
}
 
122
 
 
123
static void
 
124
vino_prompt_init (VinoPrompt *prompt)
 
125
{
 
126
  prompt->priv = g_new0 (VinoPromptPrivate, 1);
 
127
}
 
128
 
 
129
static void
 
130
vino_prompt_class_init (VinoPromptClass *klass)
 
131
{
 
132
  GObjectClass    *gobject_class = G_OBJECT_CLASS (klass);
 
133
  VinoPromptClass *prompt_class  = VINO_PROMPT_CLASS (klass);
 
134
  
 
135
  gobject_class->finalize     = vino_prompt_finalize;
 
136
  gobject_class->set_property = vino_prompt_set_property;
 
137
  gobject_class->get_property = vino_prompt_get_property;
 
138
 
 
139
  prompt_class->response = NULL;
 
140
  
 
141
  g_object_class_install_property (gobject_class,
 
142
                                   PROP_SCREEN,
 
143
                                   g_param_spec_object ("screen",
 
144
                                                        _("Screen"),
 
145
                                                        _("The screen on which to display the prompt"),
 
146
                                                        GDK_TYPE_SCREEN,
 
147
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
148
 
 
149
  prompt_signals [RESPONSE] =
 
150
    g_signal_new ("response",
 
151
                  G_OBJECT_CLASS_TYPE (gobject_class),
 
152
                  G_SIGNAL_RUN_LAST,
 
153
                  G_STRUCT_OFFSET (VinoPromptClass, response),
 
154
                  NULL, NULL,
 
155
                  vino_marshal_VOID__POINTER_ENUM,
 
156
                  G_TYPE_NONE,
 
157
                  2,
 
158
                  G_TYPE_POINTER,
 
159
                  VINO_TYPE_PROMPT_RESPONSE);
 
160
 
 
161
  vino_init_stock_items ();
 
162
}
 
163
 
 
164
VinoPrompt *
 
165
vino_prompt_new (GdkScreen *screen)
 
166
{
 
167
  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
 
168
 
 
169
  return g_object_new (VINO_TYPE_PROMPT,
 
170
                       "screen", screen,
 
171
                       NULL);
 
172
}
 
173
 
 
174
GdkScreen *
 
175
vino_prompt_get_screen (VinoPrompt *prompt)
 
176
{
 
177
  g_return_val_if_fail (VINO_IS_PROMPT (prompt), NULL);
 
178
 
 
179
  return prompt->priv->screen;
 
180
}
 
181
 
 
182
void
 
183
vino_prompt_set_screen (VinoPrompt *prompt,
 
184
                        GdkScreen  *screen)
 
185
{
 
186
  g_return_if_fail (VINO_IS_PROMPT (prompt));
 
187
 
 
188
  if (prompt->priv->screen != screen)
 
189
    {
 
190
      prompt->priv->screen = screen;
 
191
 
 
192
      g_object_notify (G_OBJECT (prompt), "screen");
 
193
    }
 
194
}
 
195
 
 
196
static void
 
197
vino_prompt_process_pending_clients (VinoPrompt *prompt)
 
198
{
 
199
  if (prompt->priv->pending_clients)
 
200
    {
 
201
      rfbClientPtr rfb_client = (rfbClientPtr) prompt->priv->pending_clients->data;
 
202
 
 
203
      prompt->priv->pending_clients =
 
204
        g_slist_delete_link (prompt->priv->pending_clients,
 
205
                             prompt->priv->pending_clients);
 
206
 
 
207
      vino_prompt_display (prompt, rfb_client);
 
208
    }
 
209
}
 
210
 
 
211
static void
 
212
emit_response_signal (VinoPrompt   *prompt,
 
213
                      rfbClientPtr  rfb_client,
 
214
                      int           response)
 
215
{
 
216
  dprintf (PROMPT, "Emiting response signal for %p: %s\n",
 
217
           rfb_client,
 
218
           response == VINO_RESPONSE_ACCEPT ? "accept" : "reject");
 
219
 
 
220
  g_signal_emit (prompt,
 
221
                 prompt_signals [RESPONSE],
 
222
                 0,
 
223
                 rfb_client,
 
224
                 response);
 
225
}
 
226
 
 
227
static void
 
228
vino_prompt_handle_response (NotifyNotification *notification,
 
229
                             char               *response,
 
230
                             gpointer            user_data)
 
231
{
 
232
  VinoPrompt *prompt = user_data;
 
233
  rfbClientPtr rfb_client;
 
234
  int          prompt_response = VINO_RESPONSE_INVALID;
 
235
 
 
236
  dprintf (PROMPT, "Got a response for client %p: %s\n",
 
237
           prompt->priv->current_client,
 
238
           response);
 
239
 
 
240
  if (g_strcmp0 (response, "accept") == 0)
 
241
    prompt_response = VINO_RESPONSE_ACCEPT;
 
242
  else
 
243
    prompt_response = VINO_RESPONSE_REJECT;
 
244
 
 
245
  rfb_client = prompt->priv->current_client;
 
246
  prompt->priv->current_client = NULL;
 
247
 
 
248
  clear_notification (prompt);
 
249
 
 
250
  if (rfb_client != NULL)
 
251
    {
 
252
      emit_response_signal (prompt, rfb_client, prompt_response);
 
253
    }
 
254
 
 
255
  vino_prompt_process_pending_clients (prompt);
 
256
}
 
257
 
 
258
static gboolean
 
259
vino_prompt_setup_dialog (VinoPrompt *prompt)
 
260
{
 
261
  if (!notify_is_initted () &&  !notify_init (g_get_application_name ()))
 
262
    {
 
263
      g_printerr (_("Error initializing libnotify\n"));
 
264
      return FALSE;
 
265
    }
 
266
 
 
267
  return TRUE;
 
268
}
 
269
 
 
270
static gboolean
 
271
vino_prompt_display (VinoPrompt   *prompt,
 
272
                     rfbClientPtr  rfb_client)
 
273
{
 
274
  char *host_label;
 
275
 
 
276
  if (prompt->priv->current_client)
 
277
    return prompt->priv->current_client == rfb_client;
 
278
 
 
279
  if (!vino_prompt_setup_dialog (prompt))
 
280
    return FALSE;
 
281
 
 
282
  host_label = g_strdup_printf (_("A user on the computer '%s' is trying to remotely view or control your desktop."),
 
283
                                rfb_client->host);
 
284
 
 
285
  prompt->priv->notification = notify_notification_new (_("Another user is trying to view your desktop."),
 
286
                                                        host_label,
 
287
                                                        "preferences-desktop-remote-desktop");
 
288
  notify_notification_set_hint_string (prompt->priv->notification, "desktop-entry", "vino-server");
 
289
  notify_notification_add_action (prompt->priv->notification,
 
290
                                  "refuse",
 
291
                                  _("Refuse"),
 
292
                                  vino_prompt_handle_response,
 
293
                                  prompt,
 
294
                                  NULL);
 
295
  notify_notification_add_action (prompt->priv->notification,
 
296
                                  "accept",
 
297
                                  _("Accept"),
 
298
                                  vino_prompt_handle_response,
 
299
                                  prompt,
 
300
                                  NULL);
 
301
 
 
302
  g_free (host_label);
 
303
 
 
304
  prompt->priv->current_client = rfb_client;
 
305
 
 
306
  notify_notification_show (prompt->priv->notification, NULL);
 
307
 
 
308
  dprintf (PROMPT, "Prompting for client %p\n", rfb_client);
 
309
 
 
310
  return TRUE;
 
311
}
 
312
 
 
313
void
 
314
vino_prompt_add_client (VinoPrompt   *prompt,
 
315
                        rfbClientPtr  rfb_client)
 
316
{
 
317
  g_return_if_fail (VINO_IS_PROMPT (prompt));
 
318
  g_return_if_fail (rfb_client != NULL);
 
319
 
 
320
  if (!vino_prompt_display (prompt, rfb_client))
 
321
    {
 
322
      dprintf (PROMPT, "Prompt in progress for %p: queueing %p\n",
 
323
               prompt->priv->current_client, rfb_client);
 
324
      prompt->priv->pending_clients =
 
325
        g_slist_append (prompt->priv->pending_clients, rfb_client);
 
326
    }
 
327
}
 
328
 
 
329
void
 
330
vino_prompt_remove_client (VinoPrompt   *prompt,
 
331
                           rfbClientPtr  rfb_client)
 
332
{
 
333
  g_return_if_fail (VINO_IS_PROMPT (prompt));
 
334
  g_return_if_fail (rfb_client != NULL);
 
335
 
 
336
  if (prompt->priv->current_client == rfb_client)
 
337
    {
 
338
      clear_notification (prompt);
 
339
    }
 
340
  else
 
341
    {
 
342
      prompt->priv->pending_clients =
 
343
        g_slist_remove (prompt->priv->pending_clients, rfb_client);
 
344
    }
 
345
}