35 | 35 |
#endif
|
36 | 36 |
|
37 | 37 |
#ifdef HAVE_SPICE_GTK
|
38 | |
#include <spice-controller.h>
|
39 | 38 |
#include "virt-viewer-session-spice.h"
|
40 | 39 |
#endif
|
41 | 40 |
|
|
48 | 47 |
#include "remote-viewer-connect.h"
|
49 | 48 |
|
50 | 49 |
struct _RemoteViewerPrivate {
|
51 | |
#ifdef HAVE_SPICE_GTK
|
52 | |
SpiceCtrlController *controller;
|
53 | |
SpiceCtrlForeignMenu *ctrl_foreign_menu;
|
54 | |
#endif
|
55 | 50 |
#ifdef HAVE_OVIRT
|
56 | 51 |
OvirtForeignMenu *ovirt_foreign_menu;
|
57 | 52 |
#endif
|
|
77 | 72 |
#endif
|
78 | 73 |
|
79 | 74 |
static gboolean remote_viewer_start(VirtViewerApp *self, GError **error);
|
80 | |
#ifdef HAVE_SPICE_GTK
|
81 | |
static gboolean remote_viewer_activate(VirtViewerApp *self, GError **error);
|
82 | |
static void remote_viewer_window_added(GtkApplication *app, GtkWindow *w);
|
83 | |
static void spice_foreign_menu_updated(RemoteViewer *self);
|
84 | |
static void foreign_menu_title_changed(SpiceCtrlForeignMenu *menu, GParamSpec *pspec, RemoteViewer *self);
|
85 | |
#endif
|
86 | 75 |
|
87 | 76 |
static void
|
88 | 77 |
remote_viewer_dispose (GObject *object)
|
89 | 78 |
{
|
90 | |
#if defined(HAVE_SPICE_GTK) || defined(HAVE_OVIRT)
|
|
79 |
#if defined(HAVE_OVIRT)
|
91 | 80 |
RemoteViewer *self = REMOTE_VIEWER(object);
|
92 | 81 |
RemoteViewerPrivate *priv = self->priv;
|
93 | |
#endif
|
94 | |
|
95 | |
#ifdef HAVE_SPICE_GTK
|
96 | |
if (priv->controller) {
|
97 | |
g_object_unref(priv->controller);
|
98 | |
priv->controller = NULL;
|
99 | |
}
|
100 | |
|
101 | |
if (priv->ctrl_foreign_menu) {
|
102 | |
g_object_unref(priv->ctrl_foreign_menu);
|
103 | |
priv->ctrl_foreign_menu = NULL;
|
104 | |
}
|
105 | 82 |
#endif
|
106 | 83 |
|
107 | 84 |
#ifdef HAVE_OVIRT
|
|
131 | 108 |
|
132 | 109 |
static gchar **opt_args = NULL;
|
133 | 110 |
static char *opt_title = NULL;
|
134 | |
static gboolean opt_controller = FALSE;
|
135 | 111 |
|
136 | 112 |
static void
|
137 | 113 |
remote_viewer_add_option_entries(VirtViewerApp *self, GOptionContext *context, GOptionGroup *group)
|
|
139 | 115 |
static const GOptionEntry options[] = {
|
140 | 116 |
{ "title", 't', 0, G_OPTION_ARG_STRING, &opt_title,
|
141 | 117 |
N_("Set window title"), NULL },
|
142 | |
#ifdef HAVE_SPICE_GTK
|
143 | |
{ "spice-controller", '\0', 0, G_OPTION_ARG_NONE, &opt_controller,
|
144 | |
N_("Open connection using Spice controller communication"), NULL },
|
145 | |
#endif
|
146 | 118 |
{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_args,
|
147 | 119 |
NULL, "URI|VV-FILE" },
|
148 | 120 |
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
|
|
183 | 155 |
g_object_set(app, "guri", opt_args[0], NULL);
|
184 | 156 |
}
|
185 | 157 |
|
186 | |
#ifdef HAVE_SPICE_GTK
|
187 | |
if (opt_controller) {
|
188 | |
if (opt_args) {
|
189 | |
g_printerr(_("\nError: extra arguments given while using Spice controller\n\n"));
|
190 | |
ret = TRUE;
|
191 | |
*status = 1;
|
192 | |
goto end;
|
193 | |
}
|
194 | |
|
195 | |
self->priv->controller = spice_ctrl_controller_new();
|
196 | |
self->priv->ctrl_foreign_menu = spice_ctrl_foreign_menu_new();
|
197 | |
|
198 | |
g_object_set(self, "guest-name", "defined by Spice controller", NULL);
|
199 | |
|
200 | |
g_signal_connect(self->priv->ctrl_foreign_menu, "notify::title",
|
201 | |
G_CALLBACK(foreign_menu_title_changed),
|
202 | |
self);
|
203 | |
}
|
204 | |
#endif
|
205 | |
|
206 | |
if (opt_title && !opt_controller)
|
|
158 |
if (opt_title)
|
207 | 159 |
g_object_set(app, "title", opt_title, NULL);
|
208 | 160 |
|
209 | 161 |
end:
|
|
240 | 192 |
remote_viewer_class_init (RemoteViewerClass *klass)
|
241 | 193 |
{
|
242 | 194 |
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
243 | |
GtkApplicationClass *gtk_app_class = GTK_APPLICATION_CLASS(klass);
|
244 | 195 |
VirtViewerAppClass *app_class = VIRT_VIEWER_APP_CLASS (klass);
|
245 | 196 |
GApplicationClass *g_app_class = G_APPLICATION_CLASS(klass);
|
246 | 197 |
|
|
254 | 205 |
app_class->start = remote_viewer_start;
|
255 | 206 |
app_class->deactivated = remote_viewer_deactivated;
|
256 | 207 |
app_class->add_option_entries = remote_viewer_add_option_entries;
|
257 | |
#ifdef HAVE_SPICE_GTK
|
258 | |
app_class->activate = remote_viewer_activate;
|
259 | |
gtk_app_class->window_added = remote_viewer_window_added;
|
260 | |
#else
|
261 | |
(void) gtk_app_class;
|
262 | |
#endif
|
263 | 208 |
|
264 | 209 |
#ifdef HAVE_OVIRT
|
265 | 210 |
g_object_class_install_property(object_class,
|
|
287 | 232 |
NULL);
|
288 | 233 |
}
|
289 | 234 |
|
290 | |
#ifdef HAVE_SPICE_GTK
|
291 | |
static void
|
292 | |
foreign_menu_title_changed(SpiceCtrlForeignMenu *menu G_GNUC_UNUSED,
|
293 | |
GParamSpec *pspec G_GNUC_UNUSED,
|
294 | |
RemoteViewer *self)
|
295 | |
{
|
296 | |
gboolean has_focus;
|
297 | |
|
298 | |
g_object_get(G_OBJECT(self), "has-focus", &has_focus, NULL);
|
299 | |
/* FIXME: use a proper "new client connected" event
|
300 | |
** a foreign menu client set the title when connecting,
|
301 | |
** inform of focus state at that time.
|
302 | |
*/
|
303 | |
spice_ctrl_foreign_menu_app_activated_msg(self->priv->ctrl_foreign_menu, has_focus);
|
304 | |
|
305 | |
/* update menu title */
|
306 | |
spice_foreign_menu_updated(self);
|
307 | |
}
|
308 | |
|
309 | |
static void
|
310 | |
spice_ctrl_do_connect(SpiceCtrlController *ctrl G_GNUC_UNUSED,
|
311 | |
VirtViewerApp *self)
|
312 | |
{
|
313 | |
GError *error = NULL;
|
314 | |
|
315 | |
if (!virt_viewer_app_initial_connect(self, &error)) {
|
316 | |
const gchar *msg = error ? error->message :
|
317 | |
_("Failed to initiate connection");
|
318 | |
virt_viewer_app_simple_message_dialog(self, msg);
|
319 | |
g_clear_error(&error);
|
320 | |
}
|
321 | |
}
|
322 | |
|
323 | |
static void
|
324 | |
spice_ctrl_show(SpiceCtrlController *ctrl G_GNUC_UNUSED, RemoteViewer *self)
|
325 | |
{
|
326 | |
virt_viewer_app_show_display(VIRT_VIEWER_APP(self));
|
327 | |
}
|
328 | |
|
329 | |
static void
|
330 | |
spice_ctrl_hide(SpiceCtrlController *ctrl G_GNUC_UNUSED, RemoteViewer *self)
|
331 | |
{
|
332 | |
virt_viewer_app_show_status(VIRT_VIEWER_APP(self), _("Display disabled by controller"));
|
333 | |
}
|
334 | |
|
335 | |
static void
|
336 | |
spice_menuitem_activate_cb(GtkMenuItem *mi, GObject *ctrl)
|
337 | |
{
|
338 | |
SpiceCtrlMenuItem *menuitem = g_object_get_data(G_OBJECT(mi), "spice-menuitem");
|
339 | |
|
340 | |
g_return_if_fail(menuitem != NULL);
|
341 | |
if (gtk_menu_item_get_submenu(mi))
|
342 | |
return;
|
343 | |
|
344 | |
if (SPICE_CTRL_IS_CONTROLLER(ctrl))
|
345 | |
spice_ctrl_controller_menu_item_click_msg(SPICE_CTRL_CONTROLLER(ctrl), menuitem->id);
|
346 | |
else if (SPICE_CTRL_IS_FOREIGN_MENU(ctrl))
|
347 | |
spice_ctrl_foreign_menu_menu_item_click_msg(SPICE_CTRL_FOREIGN_MENU(ctrl), menuitem->id);
|
348 | |
}
|
349 | |
|
350 | |
static GtkWidget *
|
351 | |
ctrlmenu_to_gtkmenu (RemoteViewer *self, SpiceCtrlMenu *ctrlmenu, GObject *ctrl)
|
352 | |
{
|
353 | |
GList *l;
|
354 | |
GtkWidget *menu = gtk_menu_new();
|
355 | |
guint n = 0;
|
356 | |
|
357 | |
for (l = ctrlmenu->items; l != NULL; l = l->next) {
|
358 | |
SpiceCtrlMenuItem *menuitem = l->data;
|
359 | |
GtkWidget *item;
|
360 | |
char *s;
|
361 | |
if (menuitem->text == NULL) {
|
362 | |
g_warn_if_reached();
|
363 | |
continue;
|
364 | |
}
|
365 | |
|
366 | |
for (s = menuitem->text; *s; s++)
|
367 | |
if (*s == '&')
|
368 | |
*s = '_';
|
369 | |
|
370 | |
if (g_str_equal(menuitem->text, "-")) {
|
371 | |
item = gtk_separator_menu_item_new();
|
372 | |
} else if (menuitem->flags & CONTROLLER_MENU_FLAGS_CHECKED) {
|
373 | |
item = gtk_check_menu_item_new_with_mnemonic(menuitem->text);
|
374 | |
g_object_set(item, "active", TRUE, NULL);
|
375 | |
} else {
|
376 | |
item = gtk_menu_item_new_with_mnemonic(menuitem->text);
|
377 | |
}
|
378 | |
|
379 | |
if (menuitem->flags & (CONTROLLER_MENU_FLAGS_GRAYED | CONTROLLER_MENU_FLAGS_DISABLED))
|
380 | |
gtk_widget_set_sensitive(item, FALSE);
|
381 | |
|
382 | |
g_object_set_data_full(G_OBJECT(item), "spice-menuitem",
|
383 | |
g_object_ref(menuitem), g_object_unref);
|
384 | |
g_signal_connect(item, "activate", G_CALLBACK(spice_menuitem_activate_cb), ctrl);
|
385 | |
gtk_menu_attach(GTK_MENU (menu), item, 0, 1, n, n + 1);
|
386 | |
n += 1;
|
387 | |
|
388 | |
if (menuitem->submenu) {
|
389 | |
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item),
|
390 | |
ctrlmenu_to_gtkmenu(self, menuitem->submenu, ctrl));
|
391 | |
}
|
392 | |
}
|
393 | |
|
394 | |
if (n == 0) {
|
395 | |
g_object_ref_sink(menu);
|
396 | |
g_object_unref(menu);
|
397 | |
menu = NULL;
|
398 | |
}
|
399 | |
|
400 | |
gtk_widget_show_all(menu);
|
401 | |
return menu;
|
402 | |
}
|
403 | |
|
404 | |
static void
|
405 | |
spice_menu_update(RemoteViewer *self, VirtViewerWindow *win)
|
406 | |
{
|
407 | |
GtkWidget *menuitem = g_object_get_data(G_OBJECT(win), "spice-menu");
|
408 | |
SpiceCtrlMenu *menu;
|
409 | |
|
410 | |
if (self->priv->controller == NULL)
|
411 | |
return;
|
412 | |
|
413 | |
if (menuitem != NULL)
|
414 | |
gtk_widget_destroy(menuitem);
|
415 | |
|
416 | |
{
|
417 | |
GtkMenuShell *shell = GTK_MENU_SHELL(gtk_builder_get_object(virt_viewer_window_get_builder(win), "top-menu"));
|
418 | |
menuitem = gtk_menu_item_new_with_label("Spice");
|
419 | |
gtk_menu_shell_append(shell, menuitem);
|
420 | |
g_object_set_data(G_OBJECT(win), "spice-menu", menuitem);
|
421 | |
}
|
422 | |
|
423 | |
g_object_get(self->priv->controller, "menu", &menu, NULL);
|
424 | |
if (menu == NULL || g_list_length(menu->items) == 0) {
|
425 | |
gtk_widget_set_visible(menuitem, FALSE);
|
426 | |
} else {
|
427 | |
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem),
|
428 | |
ctrlmenu_to_gtkmenu(self, menu, G_OBJECT(self->priv->controller)));
|
429 | |
gtk_widget_set_visible(menuitem, TRUE);
|
430 | |
}
|
431 | |
|
432 | |
if (menu != NULL)
|
433 | |
g_object_unref(menu);
|
434 | |
}
|
435 | |
|
436 | |
static void
|
437 | |
spice_menu_update_each(gpointer value,
|
438 | |
gpointer user_data)
|
439 | |
{
|
440 | |
spice_menu_update(REMOTE_VIEWER(user_data), VIRT_VIEWER_WINDOW(value));
|
441 | |
}
|
442 | |
|
443 | |
static void
|
444 | |
spice_ctrl_menu_updated(RemoteViewer *self)
|
445 | |
{
|
446 | |
GList *windows = virt_viewer_app_get_windows(VIRT_VIEWER_APP(self));
|
447 | |
|
448 | |
g_debug("Spice controller menu updated");
|
449 | |
|
450 | |
g_list_foreach(windows, spice_menu_update_each, self);
|
451 | |
}
|
452 | |
|
453 | |
static void
|
454 | |
spice_foreign_menu_update(RemoteViewer *self, VirtViewerWindow *win)
|
455 | |
{
|
456 | |
GtkWidget *menuitem = g_object_get_data(G_OBJECT(win), "foreign-menu");
|
457 | |
SpiceCtrlMenu *menu;
|
458 | |
|
459 | |
if (self->priv->ctrl_foreign_menu == NULL)
|
460 | |
return;
|
461 | |
|
462 | |
if (menuitem != NULL)
|
463 | |
gtk_widget_destroy(menuitem);
|
464 | |
|
465 | |
{
|
466 | |
GtkMenuShell *shell = GTK_MENU_SHELL(gtk_builder_get_object(virt_viewer_window_get_builder(win), "top-menu"));
|
467 | |
const gchar *title = spice_ctrl_foreign_menu_get_title(self->priv->ctrl_foreign_menu);
|
468 | |
menuitem = gtk_menu_item_new_with_label(title);
|
469 | |
gtk_menu_shell_append(shell, menuitem);
|
470 | |
g_object_set_data(G_OBJECT(win), "foreign-menu", menuitem);
|
471 | |
}
|
472 | |
|
473 | |
g_object_get(self->priv->ctrl_foreign_menu, "menu", &menu, NULL);
|
474 | |
if (menu == NULL || g_list_length(menu->items) == 0) {
|
475 | |
gtk_widget_set_visible(menuitem, FALSE);
|
476 | |
} else {
|
477 | |
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem),
|
478 | |
ctrlmenu_to_gtkmenu(self, menu, G_OBJECT(self->priv->ctrl_foreign_menu)));
|
479 | |
gtk_widget_set_visible(menuitem, TRUE);
|
480 | |
}
|
481 | |
g_object_unref(menu);
|
482 | |
}
|
483 | |
|
484 | |
static void
|
485 | |
spice_foreign_menu_update_each(gpointer value,
|
486 | |
gpointer user_data)
|
487 | |
{
|
488 | |
spice_foreign_menu_update(REMOTE_VIEWER(user_data), VIRT_VIEWER_WINDOW(value));
|
489 | |
}
|
490 | |
|
491 | |
static void
|
492 | |
spice_foreign_menu_updated(RemoteViewer *self)
|
493 | |
{
|
494 | |
GList *windows = virt_viewer_app_get_windows(VIRT_VIEWER_APP(self));
|
495 | |
|
496 | |
g_debug("Spice foreign menu updated");
|
497 | |
|
498 | |
g_list_foreach(windows, spice_foreign_menu_update_each, self);
|
499 | |
}
|
500 | |
|
|
235 |
#if defined(HAVE_SPICE_GTK) && defined(HAVE_OVIRT)
|
501 | 236 |
static SpiceSession *
|
502 | 237 |
remote_viewer_get_spice_session(RemoteViewer *self)
|
503 | 238 |
{
|
|
512 | 247 |
g_object_unref(vsession);
|
513 | 248 |
|
514 | 249 |
return session;
|
515 | |
}
|
516 | |
|
517 | |
static void
|
518 | |
app_notified(VirtViewerApp *app,
|
519 | |
GParamSpec *pspec,
|
520 | |
RemoteViewer *self)
|
521 | |
{
|
522 | |
GValue value = G_VALUE_INIT;
|
523 | |
|
524 | |
g_value_init(&value, pspec->value_type);
|
525 | |
g_object_get_property(G_OBJECT(app), pspec->name, &value);
|
526 | |
|
527 | |
if (g_str_equal(pspec->name, "has-focus")) {
|
528 | |
if (self->priv->ctrl_foreign_menu)
|
529 | |
spice_ctrl_foreign_menu_app_activated_msg(self->priv->ctrl_foreign_menu, g_value_get_boolean(&value));
|
530 | |
}
|
531 | |
|
532 | |
g_value_unset(&value);
|
533 | |
}
|
534 | |
|
535 | |
static void
|
536 | |
spice_ctrl_notified(SpiceCtrlController *ctrl,
|
537 | |
GParamSpec *pspec,
|
538 | |
RemoteViewer *self)
|
539 | |
{
|
540 | |
SpiceSession *session = remote_viewer_get_spice_session(self);
|
541 | |
GValue value = G_VALUE_INIT;
|
542 | |
VirtViewerApp *app = VIRT_VIEWER_APP(self);
|
543 | |
|
544 | |
g_return_if_fail(session != NULL);
|
545 | |
|
546 | |
g_value_init(&value, pspec->value_type);
|
547 | |
g_object_get_property(G_OBJECT(ctrl), pspec->name, &value);
|
548 | |
|
549 | |
if (g_str_equal(pspec->name, "host") ||
|
550 | |
g_str_equal(pspec->name, "port") ||
|
551 | |
g_str_equal(pspec->name, "password") ||
|
552 | |
g_str_equal(pspec->name, "ca-file") ||
|
553 | |
g_str_equal(pspec->name, "enable-smartcard") ||
|
554 | |
g_str_equal(pspec->name, "color-depth") ||
|
555 | |
g_str_equal(pspec->name, "disable-effects") ||
|
556 | |
g_str_equal(pspec->name, "enable-usbredir") ||
|
557 | |
g_str_equal(pspec->name, "secure-channels") ||
|
558 | |
g_str_equal(pspec->name, "proxy")) {
|
559 | |
g_object_set_property(G_OBJECT(session), pspec->name, &value);
|
560 | |
} else if (g_str_equal(pspec->name, "sport")) {
|
561 | |
g_object_set_property(G_OBJECT(session), "tls-port", &value);
|
562 | |
} else if (g_str_equal(pspec->name, "tls-ciphers")) {
|
563 | |
g_object_set_property(G_OBJECT(session), "ciphers", &value);
|
564 | |
} else if (g_str_equal(pspec->name, "host-subject")) {
|
565 | |
g_object_set_property(G_OBJECT(session), "cert-subject", &value);
|
566 | |
} else if (g_str_equal(pspec->name, "enable-usb-autoshare")) {
|
567 | |
VirtViewerSession *vsession = NULL;
|
568 | |
|
569 | |
g_object_get(self, "session", &vsession, NULL);
|
570 | |
g_object_set_property(G_OBJECT(vsession), "auto-usbredir", &value);
|
571 | |
g_object_unref(G_OBJECT(vsession));
|
572 | |
} else if (g_str_equal(pspec->name, "usb-filter")) {
|
573 | |
SpiceUsbDeviceManager *manager;
|
574 | |
manager = spice_usb_device_manager_get(session, NULL);
|
575 | |
if (manager != NULL) {
|
576 | |
g_object_set_property(G_OBJECT(manager),
|
577 | |
"auto-connect-filter",
|
578 | |
&value);
|
579 | |
}
|
580 | |
} else if (g_str_equal(pspec->name, "title")) {
|
581 | |
g_object_set(app, "title", g_value_get_string(&value), NULL);
|
582 | |
} else if (g_str_equal(pspec->name, "display-flags")) {
|
583 | |
guint flags = g_value_get_uint(&value);
|
584 | |
gboolean fullscreen = !!(flags & CONTROLLER_SET_FULL_SCREEN);
|
585 | |
g_object_set(G_OBJECT(self), "fullscreen", fullscreen, NULL);
|
586 | |
} else if (g_str_equal(pspec->name, "menu")) {
|
587 | |
spice_ctrl_menu_updated(self);
|
588 | |
} else if (g_str_equal(pspec->name, "hotkeys")) {
|
589 | |
virt_viewer_app_set_hotkeys(app, g_value_get_string(&value));
|
590 | |
} else {
|
591 | |
gchar *content = g_strdup_value_contents(&value);
|
592 | |
|
593 | |
g_debug("unimplemented property: %s=%s", pspec->name, content);
|
594 | |
g_free(content);
|
595 | |
}
|
596 | |
|
597 | |
g_object_unref(session);
|
598 | |
g_value_unset(&value);
|
599 | |
}
|
600 | |
|
601 | |
static void
|
602 | |
spice_ctrl_foreign_menu_notified(SpiceCtrlForeignMenu *ctrl_foreign_menu G_GNUC_UNUSED,
|
603 | |
GParamSpec *pspec,
|
604 | |
RemoteViewer *self)
|
605 | |
{
|
606 | |
if (g_str_equal(pspec->name, "menu")) {
|
607 | |
spice_foreign_menu_updated(self);
|
608 | |
}
|
609 | |
}
|
610 | |
|
611 | |
static void
|
612 | |
spice_ctrl_listen_async_cb(GObject *object,
|
613 | |
GAsyncResult *res,
|
614 | |
gpointer user_data)
|
615 | |
{
|
616 | |
GError *error = NULL;
|
617 | |
VirtViewerApp *app = VIRT_VIEWER_APP(user_data);
|
618 | |
|
619 | |
if (SPICE_CTRL_IS_CONTROLLER(object))
|
620 | |
spice_ctrl_controller_listen_finish(SPICE_CTRL_CONTROLLER(object), res, &error);
|
621 | |
else if (SPICE_CTRL_IS_FOREIGN_MENU(object)) {
|
622 | |
spice_ctrl_foreign_menu_listen_finish(SPICE_CTRL_FOREIGN_MENU(object), res, &error);
|
623 | |
} else
|
624 | |
g_warn_if_reached();
|
625 | |
|
626 | |
if (error != NULL) {
|
627 | |
virt_viewer_app_simple_message_dialog(app,
|
628 | |
_("Controller connection failed: %s"),
|
629 | |
error->message);
|
630 | |
g_clear_error(&error);
|
631 | |
exit(EXIT_FAILURE); /* TODO: make start async? */
|
632 | |
}
|
633 | |
}
|
634 | |
|
635 | |
|
636 | |
static gboolean
|
637 | |
remote_viewer_activate(VirtViewerApp *app, GError **error)
|
638 | |
{
|
639 | |
RemoteViewer *self;
|
640 | |
gboolean ret = FALSE;
|
641 | |
|
642 | |
g_return_val_if_fail(REMOTE_VIEWER_IS(app), FALSE);
|
643 | |
|
644 | |
self = REMOTE_VIEWER(app);
|
645 | |
|
646 | |
if (self->priv->controller) {
|
647 | |
SpiceSession *session = remote_viewer_get_spice_session(self);
|
648 | |
ret = spice_session_connect(session);
|
649 | |
g_object_unref(session);
|
650 | |
} else {
|
651 | |
ret = VIRT_VIEWER_APP_CLASS(remote_viewer_parent_class)->activate(app, error);
|
652 | |
}
|
653 | |
|
654 | |
return ret;
|
655 | |
}
|
656 | |
|
657 | |
static void
|
658 | |
remote_viewer_window_added(GtkApplication *app,
|
659 | |
GtkWindow *w)
|
660 | |
{
|
661 | |
VirtViewerWindow *win = VIRT_VIEWER_WINDOW(
|
662 | |
g_object_get_data(G_OBJECT(w), "virt-viewer-window"));
|
663 | |
spice_menu_update(REMOTE_VIEWER(app), win);
|
664 | |
spice_foreign_menu_update(REMOTE_VIEWER(app), win);
|
665 | |
|
666 | |
GTK_APPLICATION_CLASS(remote_viewer_parent_class)->window_added(app, w);
|
667 | 250 |
}
|
668 | 251 |
#endif
|
669 | 252 |
|
|
1148 | 731 |
gchar *type = NULL;
|
1149 | 732 |
GError *error = NULL;
|
1150 | 733 |
|
1151 | |
#ifdef HAVE_SPICE_GTK
|
1152 | |
g_signal_connect(app, "notify", G_CALLBACK(app_notified), self);
|
1153 | |
|
1154 | |
if (priv->controller) {
|
1155 | |
if (!virt_viewer_app_create_session(app, "spice", &error)) {
|
1156 | |
g_debug("Couldn't create a Spice session");
|
1157 | |
goto cleanup;
|
1158 | |
}
|
1159 | |
|
1160 | |
g_signal_connect(priv->controller, "notify", G_CALLBACK(spice_ctrl_notified), self);
|
1161 | |
g_signal_connect(priv->controller, "do_connect", G_CALLBACK(spice_ctrl_do_connect), self);
|
1162 | |
g_signal_connect(priv->controller, "show", G_CALLBACK(spice_ctrl_show), self);
|
1163 | |
g_signal_connect(priv->controller, "hide", G_CALLBACK(spice_ctrl_hide), self);
|
1164 | |
|
1165 | |
spice_ctrl_controller_listen(priv->controller, NULL, spice_ctrl_listen_async_cb, self);
|
1166 | |
|
1167 | |
g_signal_connect(priv->ctrl_foreign_menu, "notify", G_CALLBACK(spice_ctrl_foreign_menu_notified), self);
|
1168 | |
spice_ctrl_foreign_menu_listen(priv->ctrl_foreign_menu, NULL, spice_ctrl_listen_async_cb, self);
|
1169 | |
|
1170 | |
virt_viewer_app_show_status(VIRT_VIEWER_APP(self), _("Setting up Spice session..."));
|
1171 | |
} else
|
1172 | |
#endif
|
|
734 |
retry_dialog:
|
1173 | 735 |
{
|
1174 | |
retry_dialog:
|
1175 | 736 |
if (priv->open_recent_dialog) {
|
1176 | 737 |
VirtViewerWindow *main_window = virt_viewer_app_get_main_window(app);
|
1177 | 738 |
if (!remote_viewer_connect_dialog(virt_viewer_window_get_window(main_window), &guri)) {
|