Enable the UI elements if at least one power channel has the required
capability. And only send messages to servers which support it. Since
the UI elements now depend on the capabilities, they need to be enabled
*after* the capabilities have actuall been received. Simplest way is to
just re-evaluate on all channel-events.
---
 src/virt-viewer-session-spice.c | 59 ++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 5 deletions(-)

diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c
index 381855a..bd574a3 100644
--- a/src/virt-viewer-session-spice.c
+++ b/src/virt-viewer-session-spice.c
@@ -1065,6 +1065,9 @@ virt_viewer_session_spice_vm_action(VirtViewerSession 
*sess G_GNUC_UNUSED,
                 if (!SPICE_IS_POWER_CHANNEL(channel)) {
                     continue;
                 }
+                if (!spice_channel_test_capability(channel, 
SPICE_POWER_CAP_RESET)) {
+                    continue;
+                }
 
                 spice_power_channel_send_reset(SPICE_POWER_CHANNEL(channel));
             }
@@ -1084,6 +1087,9 @@ virt_viewer_session_spice_vm_action(VirtViewerSession 
*sess G_GNUC_UNUSED,
                 if (!SPICE_IS_POWER_CHANNEL(channel)) {
                     continue;
                 }
+                if (!spice_channel_test_capability(channel, 
SPICE_POWER_CAP_POWEROFF)) {
+                    continue;
+                }
 
                 
spice_power_channel_send_poweroff(SPICE_POWER_CHANNEL(channel));
             }
@@ -1126,11 +1132,46 @@ 
virt_viewer_session_spice_has_vm_action(VirtViewerSession *sess G_GNUC_UNUSED,
     VirtViewerSessionSpice *self = VIRT_VIEWER_SESSION_SPICE(sess);
 
     if (spice_session_has_channel_type(self->session, SPICE_CHANNEL_POWER)) {
+        SpiceSession *session = self->session;
+        GList *l, *channels = spice_session_get_channels(session);
+        SpiceChannel *channel;
+
         switch (action) {
         case VIRT_VIEWER_SESSION_VM_ACTION_RESET:
+            for (l = channels; l != NULL; l = l->next) {
+                channel = l->data;
+                if (!SPICE_IS_POWER_CHANNEL(channel)) {
+                    continue;
+                }
+                if (spice_channel_test_capability(channel, 
SPICE_POWER_CAP_RESET)) {
+                    g_debug("virt_viewer_session_spice_has_vm_action reset 
yes");
+                    g_list_free(channels);
+                    // at least one supports it
+                    return TRUE;
+                }
+            }
+
+            g_debug("virt_viewer_session_spice_has_vm_action reset no");
+            break;
         case VIRT_VIEWER_SESSION_VM_ACTION_POWER_DOWN:
-            return TRUE;
+            for (l = channels; l != NULL; l = l->next) {
+                channel = l->data;
+                if (!SPICE_IS_POWER_CHANNEL(channel)) {
+                    continue;
+                }
+                if (spice_channel_test_capability(channel, 
SPICE_POWER_CAP_POWEROFF)) {
+                    g_debug("virt_viewer_session_spice_has_vm_action poweroff 
yes");
+                    g_list_free(channels);
+                    // at least one supports it
+                    return TRUE;
+                }
+            }
+
+            g_debug("virt_viewer_session_spice_has_vm_action poweroff no");
+            break;
         }
+
+        g_list_free(channels);
     }
 
 #ifdef WITH_QMP_PORT
@@ -1267,6 +1308,16 @@ spice_port_opened(SpiceChannel *channel, GParamSpec 
*pspec G_GNUC_UNUSED,
     }
 }
 
+static void
+spice_power_channel_event(SpiceChannel *channel G_GNUC_UNUSED, GParamSpec 
*pspec G_GNUC_UNUSED,
+                  VirtViewerSessionSpice *self)
+{
+    g_debug("spice_power_channel_event");
+    // to re-trigger virt_viewer_app_set_actions_sensitive() after 
capabilities are received
+    g_object_set(virt_viewer_session_get_app(VIRT_VIEWER_SESSION(self)),
+                 "vm-ui", FALSE, NULL);
+}
+
 static void
 virt_viewer_session_spice_channel_new(SpiceSession *s,
                                       SpiceChannel *channel,
@@ -1341,11 +1392,9 @@ virt_viewer_session_spice_channel_new(SpiceSession *s,
 
     if (SPICE_IS_POWER_CHANNEL(channel)) {
         g_debug("new power channel");
+        virt_viewer_signal_connect_object(channel, "channel-event",
+                                          
G_CALLBACK(spice_power_channel_event), self, 0);
         spice_channel_connect(channel);
-
-        // to re-trigger virt_viewer_app_set_actions_sensitive()
-        g_object_set(virt_viewer_session_get_app(VIRT_VIEWER_SESSION(self)),
-                     "vm-ui", FALSE, NULL);
     }
 
     self->channel_count++;
-- 
2.52.0

Reply via email to