diff options
Diffstat (limited to 'daemon/gdm-display.c')
-rw-r--r-- | daemon/gdm-display.c | 29 |
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); } |