2
* Copyright (C) 2003 Sun Microsystems, Inc.
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.
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.
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
20
* Mark McLoughlin <mark@skynet.ie>
25
#include "vino-prompt.h"
28
#include <libnotify/notify.h>
29
#include "vino-util.h"
30
#include "vino-enums.h"
31
#include "vino-marshal.h"
33
struct _VinoPromptPrivate
36
NotifyNotification *notification;
37
rfbClientPtr current_client;
38
GSList *pending_clients;
53
static gboolean vino_prompt_display (VinoPrompt *prompt,
54
rfbClientPtr rfb_client);
56
static guint prompt_signals [LAST_SIGNAL] = { 0 };
58
G_DEFINE_TYPE (VinoPrompt, vino_prompt, G_TYPE_OBJECT);
61
clear_notification (VinoPrompt *prompt)
63
if (prompt->priv->notification)
64
notify_notification_close (prompt->priv->notification, NULL);
65
g_clear_object (&prompt->priv->notification);
69
vino_prompt_finalize (GObject *object)
71
VinoPrompt *prompt = VINO_PROMPT (object);
73
g_slist_free (prompt->priv->pending_clients);
74
prompt->priv->pending_clients = NULL;
76
clear_notification (prompt);
78
g_free (prompt->priv);
81
if (G_OBJECT_CLASS (vino_prompt_parent_class)->finalize)
82
G_OBJECT_CLASS (vino_prompt_parent_class)->finalize (object);
86
vino_prompt_set_property (GObject *object,
91
VinoPrompt *prompt = VINO_PROMPT (object);
96
vino_prompt_set_screen (prompt, g_value_get_object (value));
99
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
105
vino_prompt_get_property (GObject *object,
110
VinoPrompt *prompt = VINO_PROMPT (object);
115
g_value_set_object (value, prompt->priv->screen);
118
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
124
vino_prompt_init (VinoPrompt *prompt)
126
prompt->priv = g_new0 (VinoPromptPrivate, 1);
130
vino_prompt_class_init (VinoPromptClass *klass)
132
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
133
VinoPromptClass *prompt_class = VINO_PROMPT_CLASS (klass);
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;
139
prompt_class->response = NULL;
141
g_object_class_install_property (gobject_class,
143
g_param_spec_object ("screen",
145
_("The screen on which to display the prompt"),
147
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
149
prompt_signals [RESPONSE] =
150
g_signal_new ("response",
151
G_OBJECT_CLASS_TYPE (gobject_class),
153
G_STRUCT_OFFSET (VinoPromptClass, response),
155
vino_marshal_VOID__POINTER_ENUM,
159
VINO_TYPE_PROMPT_RESPONSE);
161
vino_init_stock_items ();
165
vino_prompt_new (GdkScreen *screen)
167
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
169
return g_object_new (VINO_TYPE_PROMPT,
175
vino_prompt_get_screen (VinoPrompt *prompt)
177
g_return_val_if_fail (VINO_IS_PROMPT (prompt), NULL);
179
return prompt->priv->screen;
183
vino_prompt_set_screen (VinoPrompt *prompt,
186
g_return_if_fail (VINO_IS_PROMPT (prompt));
188
if (prompt->priv->screen != screen)
190
prompt->priv->screen = screen;
192
g_object_notify (G_OBJECT (prompt), "screen");
197
vino_prompt_process_pending_clients (VinoPrompt *prompt)
199
if (prompt->priv->pending_clients)
201
rfbClientPtr rfb_client = (rfbClientPtr) prompt->priv->pending_clients->data;
203
prompt->priv->pending_clients =
204
g_slist_delete_link (prompt->priv->pending_clients,
205
prompt->priv->pending_clients);
207
vino_prompt_display (prompt, rfb_client);
212
emit_response_signal (VinoPrompt *prompt,
213
rfbClientPtr rfb_client,
216
dprintf (PROMPT, "Emiting response signal for %p: %s\n",
218
response == VINO_RESPONSE_ACCEPT ? "accept" : "reject");
220
g_signal_emit (prompt,
221
prompt_signals [RESPONSE],
228
vino_prompt_handle_response (NotifyNotification *notification,
232
VinoPrompt *prompt = user_data;
233
rfbClientPtr rfb_client;
234
int prompt_response = VINO_RESPONSE_INVALID;
236
dprintf (PROMPT, "Got a response for client %p: %s\n",
237
prompt->priv->current_client,
240
if (g_strcmp0 (response, "accept") == 0)
241
prompt_response = VINO_RESPONSE_ACCEPT;
243
prompt_response = VINO_RESPONSE_REJECT;
245
rfb_client = prompt->priv->current_client;
246
prompt->priv->current_client = NULL;
248
clear_notification (prompt);
250
if (rfb_client != NULL)
252
emit_response_signal (prompt, rfb_client, prompt_response);
255
vino_prompt_process_pending_clients (prompt);
259
vino_prompt_setup_dialog (VinoPrompt *prompt)
261
if (!notify_is_initted () && !notify_init (g_get_application_name ()))
263
g_printerr (_("Error initializing libnotify\n"));
271
vino_prompt_display (VinoPrompt *prompt,
272
rfbClientPtr rfb_client)
276
if (prompt->priv->current_client)
277
return prompt->priv->current_client == rfb_client;
279
if (!vino_prompt_setup_dialog (prompt))
282
host_label = g_strdup_printf (_("A user on the computer '%s' is trying to remotely view or control your desktop."),
285
prompt->priv->notification = notify_notification_new (_("Another user is trying to view your desktop."),
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,
292
vino_prompt_handle_response,
295
notify_notification_add_action (prompt->priv->notification,
298
vino_prompt_handle_response,
304
prompt->priv->current_client = rfb_client;
306
notify_notification_show (prompt->priv->notification, NULL);
308
dprintf (PROMPT, "Prompting for client %p\n", rfb_client);
314
vino_prompt_add_client (VinoPrompt *prompt,
315
rfbClientPtr rfb_client)
317
g_return_if_fail (VINO_IS_PROMPT (prompt));
318
g_return_if_fail (rfb_client != NULL);
320
if (!vino_prompt_display (prompt, rfb_client))
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);
330
vino_prompt_remove_client (VinoPrompt *prompt,
331
rfbClientPtr rfb_client)
333
g_return_if_fail (VINO_IS_PROMPT (prompt));
334
g_return_if_fail (rfb_client != NULL);
336
if (prompt->priv->current_client == rfb_client)
338
clear_notification (prompt);
342
prompt->priv->pending_clients =
343
g_slist_remove (prompt->priv->pending_clients, rfb_client);