summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--daemon/gdm-display.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 4b035d6f..0057e2ce 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -648,6 +648,35 @@ gdm_display_finish (GdmDisplay *self)
static void
gdm_display_disconnect (GdmDisplay *self)
{
+ /* These 3 bits are reserved/unused by the X protocol */
+ guint32 unused_bits = 0b11100000000000000000000000000000;
+ XID highest_client, client;
+ guint32 client_increment;
+ const xcb_setup_t *setup;
+
+ if (self->priv->xcb_connection == NULL) {
+ return;
+ }
+
+ setup = xcb_get_setup (self->priv->xcb_connection);
+
+ /* resource_id_mask is the bits given to each client for
+ * addressing resources */
+ highest_client = (XID) ~unused_bits & ~setup->resource_id_mask;
+ client_increment = setup->resource_id_mask + 1;
+
+ /* Kill every client but ourselves, then close our own connection
+ */
+ for (client = 0;
+ client <= highest_client;
+ client += client_increment) {
+
+ if (client != setup->resource_id_base)
+ xcb_kill_client (self->priv->xcb_connection, client);
+ }
+
+ xcb_flush (self->priv->xcb_connection);
+
g_clear_pointer (&self->priv->xcb_connection, xcb_disconnect);
}