[vdagent,10/12] seamless-mode: Add support for window changes

Submitted by =?UTF-8?q?Jakub=20Jank=C5=AF?= on Aug. 8, 2017, 12:57 p.m.

Details

Message ID 20170808125702.15037-11-janku.jakub.jj@gmail.com
State New
Headers show
Series "seamless mode support" ( rev: 1 ) in Spice

Not browsing as part of any series.

Commit Message

=?UTF-8?q?Jakub=20Jank=C5=AF?= Aug. 8, 2017, 12:57 p.m.
---
 src/vdagent/x11-priv.h          |  1 +
 src/vdagent/x11-seamless-mode.c | 33 ++++++++++++++++++++++++++++++++-
 src/vdagent/x11.c               | 13 +++++++++----
 src/vdagentd-proto-strings.h    |  1 +
 src/vdagentd-proto.h            |  1 +
 src/vdagentd/vdagentd.c         |  5 +++++
 6 files changed, 49 insertions(+), 5 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/vdagent/x11-priv.h b/src/vdagent/x11-priv.h
index c264dd3..dc8d119 100644
--- a/src/vdagent/x11-priv.h
+++ b/src/vdagent/x11-priv.h
@@ -157,5 +157,6 @@  int vdagent_x11_debug_error_handler(Display *display, XErrorEvent *error);
 int vdagent_x11_ignore_bad_window_handler(Display *display, XErrorEvent *error);
 
 void vdagent_x11_seamless_mode_send_list(struct vdagent_x11 *x11);
+void vdagent_x11_seamless_mode_send_change(struct vdagent_x11 *x11, Window window);
 
 #endif // VDAGENT_X11_PRIV
diff --git a/src/vdagent/x11-seamless-mode.c b/src/vdagent/x11-seamless-mode.c
index a664c6a..9c4deba 100644
--- a/src/vdagent/x11-seamless-mode.c
+++ b/src/vdagent/x11-seamless-mode.c
@@ -204,7 +204,7 @@  get_window_list(struct vdagent_x11 *x11, Window window)
                     g_free(spice_window);
                     continue;
                 }
-
+                spice_window->id = (uint64_t)list[i];
                 window_list = g_list_append(window_list, spice_window);
             }
 
@@ -245,6 +245,7 @@  vdagent_x11_seamless_mode_send_list(struct vdagent_x11 *x11)
         list->windows[list->num_of_windows].y = window->y;
         list->windows[list->num_of_windows].w = window->w;
         list->windows[list->num_of_windows].h = window->h;
+        list->windows[list->num_of_windows].id = window->id;
 
         list->num_of_windows++;
     }
@@ -254,3 +255,33 @@  vdagent_x11_seamless_mode_send_list(struct vdagent_x11 *x11)
     udscs_write(x11->vdagentd, VDAGENTD_SEAMLESS_MODE_LIST, 0, 0,
                 (uint8_t *)list, size);
 }
+
+void vdagent_x11_seamless_mode_send_change(struct vdagent_x11 *x11, Window window)
+{
+    VDAgentSeamlessModeWindow win;
+    GList *window_list, *l;
+
+    if (!x11->seamless_mode)
+        return;
+
+    if (is_visible(x11->display, window)) {
+        get_geometry(x11->display, window, &win);
+        
+        if (vdagent_x11_restore_error_handler(x11) != 0) {
+            vdagent_x11_set_error_handler(x11, vdagent_x11_ignore_bad_window_handler);
+            return;
+        }
+
+        win.id = (uint64_t)window;
+        udscs_write(x11->vdagentd, VDAGENTD_SEAMLESS_MODE_CHANGE, 0, 0,
+                    (uint8_t *)&win, sizeof(VDAgentSeamlessModeWindow));
+
+    } else {
+        window_list = get_window_list(x11, window);
+        for (l = window_list; l != NULL; l = l->next) {
+            udscs_write(x11->vdagentd, VDAGENTD_SEAMLESS_MODE_CHANGE, 0, 0,
+                        (uint8_t *)l->data, sizeof(VDAgentSeamlessModeWindow));
+        }
+        g_list_free_full(window_list, (GDestroyNotify)g_free);
+    }
+}
diff --git a/src/vdagent/x11.c b/src/vdagent/x11.c
index 5441792..f8d0fff 100644
--- a/src/vdagent/x11.c
+++ b/src/vdagent/x11.c
@@ -521,20 +521,25 @@  static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event)
                     event.xconfigure.width, event.xconfigure.height);
         }
 
-        vdagent_x11_seamless_mode_send_list(x11);
+        vdagent_x11_seamless_mode_send_change(x11, event.xconfigure.window);
 
         handled = 1;
         break;
     case MappingNotify:
+        vdagent_x11_seamless_mode_send_list(x11);
+        handled = 1;
+        break;
     case CreateNotify:
     case CirculateNotify:
-    case DestroyNotify:
     case GravityNotify:
     case MapNotify:
     case ReparentNotify:
     case UnmapNotify:
+        vdagent_x11_seamless_mode_send_change(x11, event.xany.window);
+        handled = 1;
+        break;
+    case DestroyNotify:
         vdagent_x11_seamless_mode_send_list(x11);
-
         handled = 1;
         break;
     case ClientMessage:
@@ -561,7 +566,7 @@  static void vdagent_x11_handle_event(struct vdagent_x11 *x11, XEvent event)
         /* Always mark as handled, since we cannot unselect input for property
            notifications once we are done with handling the incr transfer. */
 
-        vdagent_x11_seamless_mode_send_list(x11);
+        vdagent_x11_seamless_mode_send_change(x11, event.xproperty.window);
 
         handled = 1;
         break;
diff --git a/src/vdagentd-proto-strings.h b/src/vdagentd-proto-strings.h
index 8f8a58b..24fa3e8 100644
--- a/src/vdagentd-proto-strings.h
+++ b/src/vdagentd-proto-strings.h
@@ -37,6 +37,7 @@  static const char * const vdagentd_messages[] = {
         "file xfer disable",
         "seamless mode",
         "seamless mode list",
+        "seamless mode change",
         "client disconnected",
 };
 
diff --git a/src/vdagentd-proto.h b/src/vdagentd-proto.h
index 4657a19..1d734d3 100644
--- a/src/vdagentd-proto.h
+++ b/src/vdagentd-proto.h
@@ -45,6 +45,7 @@  enum {
     VDAGENTD_FILE_XFER_DISABLE,
     VDAGENTD_SEAMLESS_MODE,
     VDAGENTD_SEAMLESS_MODE_LIST,
+    VDAGENTD_SEAMLESS_MODE_CHANGE,
     VDAGENTD_CLIENT_DISCONNECTED,  /* daemon -> client */
     VDAGENTD_NO_MESSAGES /* Must always be last */
 };
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index 14d15b5..9a39696 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -943,6 +943,11 @@  static void agent_read_complete(struct udscs_connection **connp,
                                   VD_AGENT_SEAMLESS_MODE_LIST, 0,
                                   data, header->size);
         break;
+    case VDAGENTD_SEAMLESS_MODE_CHANGE:
+        vdagent_virtio_port_write(virtio_port, VDP_CLIENT_PORT,
+                                  VD_AGENT_SEAMLESS_MODE_CHANGE, 0,
+                                  data, header->size);
+        break;
 
     default:
         syslog(LOG_ERR, "unknown message from vdagent: %u, ignoring",