32 | 32 |
#include "virt-viewer-session-spice.h"
|
33 | 33 |
#include "virt-viewer-display-spice.h"
|
34 | 34 |
#include "virt-viewer-auth.h"
|
|
35 |
#include "virt-glib-compat.h"
|
35 | 36 |
|
36 | 37 |
#if !GLIB_CHECK_VERSION(2, 26, 0)
|
37 | 38 |
#include "gbinding.h"
|
|
413 | 414 |
}
|
414 | 415 |
|
415 | 416 |
static void
|
|
417 |
destroy_display(gpointer data)
|
|
418 |
{
|
|
419 |
VirtViewerDisplay *display = VIRT_VIEWER_DISPLAY(data);
|
|
420 |
VirtViewerSession *session = virt_viewer_display_get_session(display);
|
|
421 |
|
|
422 |
DEBUG_LOG("Destroying spice display %p", display);
|
|
423 |
virt_viewer_session_remove_display(session, display);
|
|
424 |
g_object_unref(display);
|
|
425 |
}
|
|
426 |
|
|
427 |
static void
|
|
428 |
virt_viewer_session_spice_display_monitors(SpiceChannel *channel,
|
|
429 |
GParamSpec *pspec G_GNUC_UNUSED,
|
|
430 |
VirtViewerSessionSpice *self)
|
|
431 |
{
|
|
432 |
GArray *monitors = NULL;
|
|
433 |
GPtrArray *displays = NULL;
|
|
434 |
GtkWidget *display;
|
|
435 |
guint i, monitors_max;
|
|
436 |
|
|
437 |
g_object_get(channel,
|
|
438 |
"monitors", &monitors,
|
|
439 |
"monitors-max", &monitors_max,
|
|
440 |
NULL);
|
|
441 |
g_return_if_fail(monitors != NULL);
|
|
442 |
g_return_if_fail(monitors->len <= monitors_max);
|
|
443 |
|
|
444 |
displays = g_object_get_data(G_OBJECT(channel), "virt-viewer-displays");
|
|
445 |
if (displays == NULL) {
|
|
446 |
displays = g_ptr_array_new();
|
|
447 |
g_ptr_array_set_free_func(displays, destroy_display);
|
|
448 |
g_object_set_data_full(G_OBJECT(channel), "virt-viewer-displays",
|
|
449 |
displays, (GDestroyNotify)g_ptr_array_unref);
|
|
450 |
}
|
|
451 |
|
|
452 |
g_ptr_array_set_size(displays, monitors_max);
|
|
453 |
|
|
454 |
for (i = 0; i < monitors_max; i++) {
|
|
455 |
display = g_ptr_array_index(displays, i);
|
|
456 |
if (display == NULL) {
|
|
457 |
display = virt_viewer_display_spice_new(self, channel, i);
|
|
458 |
DEBUG_LOG("creating spice display (#:%d)", i);
|
|
459 |
g_ptr_array_index(displays, i) = g_object_ref(display);
|
|
460 |
}
|
|
461 |
|
|
462 |
g_object_freeze_notify(G_OBJECT(display));
|
|
463 |
virt_viewer_display_set_enabled(VIRT_VIEWER_DISPLAY(display), FALSE);
|
|
464 |
virt_viewer_session_add_display(VIRT_VIEWER_SESSION(self),
|
|
465 |
VIRT_VIEWER_DISPLAY(display));
|
|
466 |
}
|
|
467 |
|
|
468 |
for (i = 0; i < monitors->len; i++) {
|
|
469 |
SpiceDisplayMonitorConfig *monitor = &g_array_index(monitors, SpiceDisplayMonitorConfig, i);
|
|
470 |
display = g_ptr_array_index(displays, monitor->id);
|
|
471 |
g_return_if_fail(display != NULL);
|
|
472 |
|
|
473 |
if (monitor->width == 0 || monitor->width == 0)
|
|
474 |
continue;
|
|
475 |
|
|
476 |
virt_viewer_display_set_enabled(VIRT_VIEWER_DISPLAY(display), TRUE);
|
|
477 |
virt_viewer_display_set_desktop_size(VIRT_VIEWER_DISPLAY(display),
|
|
478 |
monitor->width, monitor->height);
|
|
479 |
}
|
|
480 |
|
|
481 |
for (i = 0; i < monitors_max; i++)
|
|
482 |
g_object_thaw_notify(g_ptr_array_index(displays, i));
|
|
483 |
|
|
484 |
g_clear_pointer(&monitors, g_array_unref);
|
|
485 |
|
|
486 |
}
|
|
487 |
|
|
488 |
static void
|
416 | 489 |
virt_viewer_session_spice_channel_new(SpiceSession *s,
|
417 | 490 |
SpiceChannel *channel,
|
418 | 491 |
VirtViewerSession *session)
|
|
440 | 513 |
|
441 | 514 |
g_signal_connect(channel, "notify::agent-connected", G_CALLBACK(agent_connected_changed), self);
|
442 | 515 |
agent_connected_changed(channel, NULL, self);
|
|
516 |
|
|
517 |
g_signal_emit_by_name(session, "session-connected");
|
443 | 518 |
}
|
444 | 519 |
|
445 | 520 |
if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
|
446 | |
GtkWidget *display;
|
447 | |
|
448 | |
g_signal_emit_by_name(session, "session-connected");
|
449 | |
|
450 | |
DEBUG_LOG("new display channel (#%d)", id);
|
451 | |
display = virt_viewer_display_spice_new(self, channel);
|
452 | |
g_object_set_data(G_OBJECT(channel), "virt-viewer-display", display);
|
453 | |
virt_viewer_session_add_display(VIRT_VIEWER_SESSION(session),
|
454 | |
VIRT_VIEWER_DISPLAY(display));
|
455 | |
|
456 | 521 |
g_signal_emit_by_name(session, "session-initialized");
|
|
522 |
|
|
523 |
g_signal_connect(channel, "notify::monitors",
|
|
524 |
G_CALLBACK(virt_viewer_session_spice_display_monitors), self);
|
|
525 |
|
|
526 |
spice_channel_connect(channel);
|
457 | 527 |
}
|
458 | 528 |
|
459 | 529 |
if (SPICE_IS_INPUTS_CHANNEL(channel)) {
|
|
537 | 607 |
if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
|
538 | 608 |
VirtViewerDisplay *display = g_object_get_data(G_OBJECT(channel), "virt-viewer-display");
|
539 | 609 |
DEBUG_LOG("zap display channel (#%d, %p)", id, display);
|
540 | |
virt_viewer_session_remove_display(session, display);
|
541 | 610 |
}
|
542 | 611 |
|
543 | 612 |
if (SPICE_IS_PLAYBACK_CHANNEL(channel) && self->priv->audio) {
|