[Spice-devel] [PATCH vdagent 10/12] seamless-mode: Add support for window changes
Jakub Janků
janku.jakub.jj at gmail.com
Tue Aug 8 12:57:00 UTC 2017
---
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(-)
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",
--
2.13.4
More information about the Spice-devel
mailing list