// Copyright 2017 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "compositor/sommelier-linux-dmabuf.h"  // NOLINT(build/include_directory)
#include "sommelier.h"  // NOLINT(build/include_directory)
#include <cstdint>
#include <cstring>
#include "sommelier-logging.h"      // NOLINT(build/include_directory)
#include "sommelier-scope-timer.h"  // NOLINT(build/include_directory)
#include "sommelier-tracing.h"      // NOLINT(build/include_directory)
#include "sommelier-transform.h"    // NOLINT(build/include_directory)
#include "sommelier-window.h"       // NOLINT(build/include_directory)
#include "sommelier-xdg-shell.h"    // NOLINT(build/include_directory)
#include "sommelier-xshape.h"       // NOLINT(build/include_directory)
#ifdef GAMEPAD_SUPPORT
#include "libevdev/libevdev-shim.h"
#endif
#include "viewporter-shim.h"  // NOLINT(build/include_directory)
#include "xcb/xcb-shim.h"

#include <assert.h>
#include <cstdlib>
#include <errno.h>
#include <fcntl.h>
#include <gbm.h>
#include <libgen.h>
#include <limits>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory>
#include <string>
#include <string.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <unistd.h>
#include <vector>
#include <wayland-client.h>
#include <xcb/composite.h>
#include <xcb/shape.h>
#include <xcb/xcb.h>
#include <xcb/xfixes.h>
#include <xcb/xproto.h>

#include "aura-shell-client-protocol.h"  // NOLINT(build/include_directory)
#include "drm-server-protocol.h"         // NOLINT(build/include_directory)
#include "fractional-scale-v1-client-protocol.h"  // NOLINT(build/include_directory)
#ifdef GAMEPAD_SUPPORT
#include "gaming-input-unstable-v2-client-protocol.h"  // NOLINT(build/include_directory)
#endif
#include "idle-inhibit-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)
#include "keyboard-extension-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)
#include "linux-dmabuf-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)
#include "linux-explicit-synchronization-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)
#include "pointer-constraints-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)
#include "relative-pointer-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)
#include "stylus-unstable-v2-client-protocol.h"  // NOLINT(build/include_directory)
#include "text-input-extension-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)
#include "text-input-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)
#include "viewporter-client-protocol.h"  // NOLINT(build/include_directory)
#include "xdg-output-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)
#include "xdg-shell-client-protocol.h"  // NOLINT(build/include_directory)
#include "xdg-shell-shim.h"             // NOLINT(build/include_directory)

#ifdef QUIRKS_SUPPORT
#include "quirks/sommelier-quirks.h"
#endif

// Check that required macro definitions exist.
#ifndef XWAYLAND_PATH
#error XWAYLAND_PATH must be defined
#endif
#ifndef XWAYLAND_GL_DRIVER_PATH
#error XWAYLAND_GL_DRIVER_PATH must be defined
#endif
#ifndef FRAME_COLOR
#error FRAME_COLOR must be defined
#endif
#ifndef DARK_FRAME_COLOR
#error DARK_FRAME_COLOR must be defined
#endif

struct sl_data_source {
  struct sl_context* ctx;
  struct wl_data_source* internal;
};

#define SEND_EVENT_MASK 0x80

#define MIN_SCALE 0.1
#define MAX_SCALE 10.0

#define MIN_DPI 72
#define MAX_DPI 9600

#define XCURSOR_SIZE_BASE 24

#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX 108
#endif

#define LOCK_SUFFIX ".lock"
#define LOCK_SUFFIXLEN 5

#define MIN_AURA_SHELL_VERSION 6
#define MAX_AURA_SHELL_VERSION 38

static const char STEAM_APP_CLASS_PREFIX[] = "steam_app_";

int sl_open_wayland_socket(const char* socket_name,
                           struct sockaddr_un* addr,
                           int* lock_fd,
                           int* sock_fd);

const char* net_wm_state_to_string(int i) {
  switch (i) {
    case NET_WM_STATE_REMOVE:
      return "NET_WM_STATE_REMOVE";
    case NET_WM_STATE_ADD:
      return "NET_WM_STATE_ADD";
    case NET_WM_STATE_TOGGLE:
      return "NET_WM_STATE_TOGGLE";
  }
  return "<unknown NET_WM_STATE>";
}

struct sl_sync_point* sl_sync_point_create(int fd) {
  TRACE_EVENT("sync", "sl_sync_point_create");
  struct sl_sync_point* sync_point = new sl_sync_point();
  sync_point->fd = fd;
  sync_point->sync = nullptr;

  return sync_point;
}

void sl_sync_point_destroy(struct sl_sync_point* sync_point) {
  TRACE_EVENT("sync", "sl_sync_point_destroy");
  close(sync_point->fd);
  delete sync_point;
}

static void sl_internal_xdg_shell_ping(void* data,
                                       struct xdg_wm_base* xdg_shell,
                                       uint32_t serial) {
  TRACE_EVENT("shell", "sl_internal_xdg_shell_ping");
  xdg_wm_base_pong(xdg_shell, serial);
}

static const struct xdg_wm_base_listener sl_internal_xdg_shell_listener = {
    sl_internal_xdg_shell_ping};

static void sl_adjust_window_size_for_screen_size(struct sl_window* window) {
  TRACE_EVENT("surface", "sl_adjust_window_size_for_screen_size", "id",
              window->id);
  struct sl_context* ctx = window->ctx;

  if (!sl_window_is_containerized(window)) {
    // Clamp size to screen if the window is not containerized. Containerized
    // window's size can only be modified by the X11 client.
    window->width = MIN(window->width, ctx->screen->width_in_pixels);
    window->height = MIN(window->height, ctx->screen->height_in_pixels);
  }
}

static void sl_adjust_window_position_for_screen_size(
    struct sl_window* window) {
  struct sl_context* ctx = window->ctx;

  const sl_host_output* output =
      window->paired_surface ? window->paired_surface->output.get() : nullptr;
  if (output) {
    window->x =
        output->virt_x + (output->virt_rotated_width - window->width) / 2;
    window->y = (output->virt_rotated_height - window->height) / 2;
  } else {
    // Center horizontally/vertically.
    window->x = ctx->screen->width_in_pixels / 2 - window->width / 2;
    window->y = ctx->screen->height_in_pixels / 2 - window->height / 2;
  }
}

static void sl_set_input_focus(struct sl_context* ctx,
                               struct sl_window* window) {
  if (window) {
    xcb_client_message_event_t event;
    event.response_type = XCB_CLIENT_MESSAGE;
    event.format = 32;
    event.window = window->id;
    event.type = ctx->atoms[ATOM_WM_PROTOCOLS].value;
    event.data.data32[0] = ctx->atoms[ATOM_WM_TAKE_FOCUS].value;
    event.data.data32[1] = XCB_CURRENT_TIME;

    if (!window->managed) {
      return;
    }

    if (window->focus_model_take_focus) {
      xcb_send_event(ctx->connection, 0, window->id, XCB_EVENT_MASK_NO_EVENT,
                     reinterpret_cast<char*>(&event));
    }

    xcb_set_input_focus(ctx->connection, XCB_INPUT_FOCUS_NONE, window->id,
                        XCB_CURRENT_TIME);
  } else {
    xcb_set_input_focus(ctx->connection, XCB_INPUT_FOCUS_NONE, XCB_NONE,
                        XCB_CURRENT_TIME);
  }
}

void sl_restack_windows(struct sl_context* ctx, uint32_t focus_resource_id) {
  struct sl_window* sibling;
  uint32_t values[1];

  wl_list_for_each(sibling, &ctx->windows, link) {
    if (!sibling->managed) {
      continue;
    }

    // Move focus window to the top and all other windows to the bottom.
    values[0] = sibling->host_surface_id == focus_resource_id
                    ? XCB_STACK_MODE_ABOVE
                    : XCB_STACK_MODE_BELOW;
    xcb_configure_window(ctx->connection, sibling->frame_id,
                         XCB_CONFIG_WINDOW_STACK_MODE, values);
  }
}

void sl_roundtrip(struct sl_context* ctx) {
  TRACE_EVENT("other", "sl_roundtrip", "id",
              ctx->application_id != nullptr ? ctx->application_id : "<null>");
  free(xcb_get_input_focus_reply(
      ctx->connection, xcb_get_input_focus(ctx->connection), nullptr));
}

static void sl_window_set_wm_state(struct sl_window* window, int state) {
  TRACE_EVENT("surface", "sl_window_set_wm_state", "id", window->id);
  struct sl_context* ctx = window->ctx;
  uint32_t values[2];

  values[0] = state;
  values[1] = XCB_WINDOW_NONE;

  xcb_change_property(ctx->connection, XCB_PROP_MODE_REPLACE, window->id,
                      ctx->atoms[ATOM_WM_STATE].value,
                      ctx->atoms[ATOM_WM_STATE].value, 32, 2, values);
}

static void sl_host_buffer_destroy(struct wl_client* client,
                                   struct wl_resource* resource) {
  TRACE_EVENT("surface", "sl_host_buffer_destroy");
  wl_resource_destroy(resource);
}

static const struct wl_buffer_interface sl_buffer_implementation = {
    sl_host_buffer_destroy};

static void sl_buffer_release(void* data, struct wl_buffer* buffer) {
  struct sl_host_buffer* host =
      static_cast<sl_host_buffer*>(wl_buffer_get_user_data(buffer));

  auto resource_id = host->resource ? wl_resource_get_id(host->resource) : -1;
  TRACE_EVENT("surface", "sl_buffer_release", "resource_id", resource_id);
  if (host->ctx->timing != nullptr) {
    host->ctx->timing->UpdateLastRelease(resource_id);
  }
  wl_buffer_send_release(host->resource);
}

static const struct wl_buffer_listener sl_buffer_listener = {sl_buffer_release};

static void sl_destroy_host_buffer(struct wl_resource* resource) {
  TRACE_EVENT("surface", "sl_destroy_host_buffer", "resource_id",
              resource ? wl_resource_get_id(resource) : -1);
  struct sl_host_buffer* host =
      static_cast<sl_host_buffer*>(wl_resource_get_user_data(resource));

  if (host->proxy) {
    wl_buffer_destroy(host->proxy);
  }
  if (host->shm_mmap) {
    host->shm_mmap->buffer_resource = nullptr;
    sl_mmap_unref(host->shm_mmap);
  }
  if (host->sync_point) {
    sl_sync_point_destroy(host->sync_point);
  }
  wl_resource_set_user_data(resource, nullptr);
  delete host;
}

struct sl_host_buffer* sl_create_host_buffer(struct sl_context* ctx,
                                             struct wl_client* client,
                                             uint32_t id,
                                             struct wl_buffer* proxy,
                                             int32_t width,
                                             int32_t height,
                                             bool is_drm) {
  TRACE_EVENT("surface", "sl_create_host_buffer", "id", id);
  struct sl_host_buffer* host_buffer = new sl_host_buffer();

  host_buffer->ctx = ctx;
  host_buffer->width = width;
  host_buffer->height = height;
  host_buffer->resource =
      wl_resource_create(client, &wl_buffer_interface, 1, id);
  wl_resource_set_implementation(host_buffer->resource,
                                 &sl_buffer_implementation, host_buffer,
                                 sl_destroy_host_buffer);
  host_buffer->shm_mmap = nullptr;
  host_buffer->shm_format = 0;
  host_buffer->proxy = proxy;
  if (host_buffer->proxy) {
    wl_buffer_add_listener(host_buffer->proxy, &sl_buffer_listener,
                           host_buffer);
  }
  host_buffer->sync_point = nullptr;
  host_buffer->is_drm = is_drm;

  return host_buffer;
}

static void sl_internal_data_offer_destroy(struct sl_data_offer* host) {
  TRACE_EVENT("other", "sl_internal_data_offer_destroy");
  wl_data_offer_destroy(host->internal);
  wl_array_release(&host->atoms);
  wl_array_release(&host->cookies);
  delete host;
}

static void sl_set_selection(struct sl_context* ctx,
                             struct sl_data_offer* data_offer) {
  TRACE_EVENT("other", "sl_set_selection");
  if (ctx->selection_data_offer) {
    sl_internal_data_offer_destroy(ctx->selection_data_offer);
    ctx->selection_data_offer = nullptr;
  }

  if (ctx->clipboard_manager) {
    if (!data_offer) {
      if (ctx->selection_owner == ctx->selection_window) {
        xcb_set_selection_owner(ctx->connection, XCB_ATOM_NONE,
                                ctx->atoms[ATOM_CLIPBOARD].value,
                                ctx->selection_timestamp);
      }
      return;
    }

    int atoms = data_offer->cookies.size / sizeof(xcb_intern_atom_cookie_t);
    wl_array_add(&data_offer->atoms, sizeof(xcb_atom_t) * (atoms + 2));
    (reinterpret_cast<xcb_atom_t*>(data_offer->atoms.data))[0] =
        ctx->atoms[ATOM_TARGETS].value;
    (reinterpret_cast<xcb_atom_t*>(data_offer->atoms.data))[1] =
        ctx->atoms[ATOM_TIMESTAMP].value;
    for (int i = 0; i < atoms; i++) {
      xcb_intern_atom_cookie_t cookie =
          (reinterpret_cast<xcb_intern_atom_cookie_t*>(
              data_offer->cookies.data))[i];
      xcb_intern_atom_reply_t* reply =
          xcb_intern_atom_reply(ctx->connection, cookie, nullptr);
      if (reply) {
        (reinterpret_cast<xcb_atom_t*>(data_offer->atoms.data))[i + 2] =
            reply->atom;
        free(reply);
      }
    }

    xcb_set_selection_owner(ctx->connection, ctx->selection_window,
                            ctx->atoms[ATOM_CLIPBOARD].value, XCB_CURRENT_TIME);
  }

  ctx->selection_data_offer = data_offer;
}

static void sl_internal_data_offer_offer(void* data,
                                         struct wl_data_offer* data_offer,
                                         const char* type) {
  TRACE_EVENT("other", "sl_internal_data_offer_offer");
  struct sl_data_offer* host = static_cast<sl_data_offer*>(data);
  xcb_intern_atom_cookie_t* cookie = static_cast<xcb_intern_atom_cookie_t*>(
      wl_array_add(&host->cookies, sizeof(xcb_intern_atom_cookie_t)));
  *cookie = xcb_intern_atom(host->ctx->connection, 0, strlen(type), type);
}

static void sl_internal_data_offer_source_actions(
    void* data, struct wl_data_offer* data_offer, uint32_t source_actions) {
  TRACE_EVENT("other", "sl_internal_data_offer_source_actions");
}

static void sl_internal_data_offer_action(void* data,
                                          struct wl_data_offer* data_offer,
                                          uint32_t dnd_action) {
  TRACE_EVENT("other", "sl_internal_data_offer_action");
}

static const struct wl_data_offer_listener sl_internal_data_offer_listener = {
    sl_internal_data_offer_offer, sl_internal_data_offer_source_actions,
    sl_internal_data_offer_action};

static void sl_internal_data_device_data_offer(
    void* data,
    struct wl_data_device* data_device,
    struct wl_data_offer* data_offer) {
  struct sl_context* ctx = (struct sl_context*)data;
  struct sl_data_offer* host_data_offer = new sl_data_offer();

  host_data_offer->ctx = ctx;
  host_data_offer->internal = data_offer;
  wl_array_init(&host_data_offer->atoms);
  wl_array_init(&host_data_offer->cookies);

  wl_data_offer_add_listener(host_data_offer->internal,
                             &sl_internal_data_offer_listener, host_data_offer);
}

static void sl_internal_data_device_selection(
    void* data,
    struct wl_data_device* data_device,
    struct wl_data_offer* data_offer) {
  struct sl_context* ctx = (struct sl_context*)data;
  struct sl_data_offer* host_data_offer =
      data_offer
          ? static_cast<sl_data_offer*>(wl_data_offer_get_user_data(data_offer))
          : nullptr;

  sl_set_selection(ctx, host_data_offer);
}

static const struct wl_data_device_listener sl_internal_data_device_listener = {
    sl_internal_data_device_data_offer,
    /*enter=*/DoNothing,
    /*leave=*/DoNothing,
    /*motion=*/DoNothing,
    /*drop=*/DoNothing,
    sl_internal_data_device_selection};

void sl_host_seat_added(struct sl_host_seat* host) {
  struct sl_context* ctx = host->seat->ctx;

  if (ctx->default_seat) {
    return;
  }

  ctx->default_seat = host;

  // Get data device for selections.
  if (ctx->data_device_manager && ctx->data_device_manager->internal) {
    ctx->selection_data_device = wl_data_device_manager_get_data_device(
        ctx->data_device_manager->internal, host->proxy);
    wl_data_device_add_listener(ctx->selection_data_device,
                                &sl_internal_data_device_listener, ctx);
  }

#ifdef GAMEPAD_SUPPORT
  sl_gaming_seat_add_listener(ctx);
#endif
}

void sl_host_seat_removed(struct sl_host_seat* host) {
  TRACE_EVENT("other", "sl_host_seat_removed");
  if (host->seat->ctx->default_seat == host) {
    host->seat->ctx->default_seat = nullptr;
  }
}

bool sl_client_supports_interface(const sl_context* ctx,
                                  const wl_client* client,
                                  const wl_interface* interface) {
  if (ctx->client == client) {
    return true;
  }
  // Clients created for IME support only receive the minimal set of required
  // interfaces.
  const char* name = interface->name;
  return strcmp(name, "wl_seat") == 0 ||
         strcmp(name, "zwp_text_input_manager_v1") == 0 ||
         strcmp(name, "zcr_text_input_extension_v1") == 0 ||
         strcmp(name, "zcr_text_input_crostini_manager_v1") == 0 ||
         strcmp(name, "zcr_text_input_x11_v1") == 0;
}

static void sl_global_destroy(struct sl_global* global) {
  TRACE_EVENT("other", "sl_global_destroy");
  struct sl_host_registry* registry;

  wl_list_for_each(registry, &global->ctx->registries, link) {
    if (sl_client_supports_interface(global->ctx,
                                     wl_resource_get_client(registry->resource),
                                     global->interface)) {
      wl_resource_post_event(registry->resource, WL_REGISTRY_GLOBAL_REMOVE,
                             global->name);
    }
  }

  wl_list_remove(&global->link);
  free(global);
}

// Called on each "wl_registry::global" event from the host compositor,
// giving Sommelier an opportunity to bind to the new global object
// (so we can receive events or invoke requests on it), and/or forward the
// wl_registry::global event on to our clients.
void sl_registry_handler(void* data,
                         struct wl_registry* registry,
                         uint32_t id,
                         const char* interface,
                         uint32_t version) {
  struct sl_context* ctx = (struct sl_context*)data;

  TRACE_EVENT("other", "sl_registry_handler", "id", id);
  if (strcmp(interface, "wl_compositor") == 0) {
    sl_compositor_init_context(ctx, registry, id, version);
  } else if (strcmp(interface, "wl_subcompositor") == 0) {
    struct sl_subcompositor* subcompositor =
        static_cast<sl_subcompositor*>(malloc(sizeof(struct sl_subcompositor)));
    assert(subcompositor);
    subcompositor->ctx = ctx;
    subcompositor->id = id;
    assert(!ctx->subcompositor);
    ctx->subcompositor = subcompositor;
    subcompositor->host_global = sl_subcompositor_global_create(ctx);
  } else if (strcmp(interface, "wl_shm") == 0) {
    struct sl_shm* shm = static_cast<sl_shm*>(malloc(sizeof(struct sl_shm)));
    assert(shm);
    shm->ctx = ctx;
    shm->id = id;
    shm->internal = static_cast<wl_shm*>(
        wl_registry_bind(registry, id, &wl_shm_interface, 1));
    assert(!ctx->shm);
    ctx->shm = shm;
    shm->host_global = sl_shm_global_create(ctx);
  } else if (strcmp(interface, "wl_shell") == 0) {
    struct sl_shell* shell =
        static_cast<sl_shell*>(malloc(sizeof(struct sl_shell)));
    assert(shell);
    shell->ctx = ctx;
    shell->id = id;
    assert(!ctx->shell);
    ctx->shell = shell;
    shell->host_global = sl_shell_global_create(ctx);
  } else if (strcmp(interface, "wl_output") == 0) {
    struct sl_output* output =
        static_cast<sl_output*>(malloc(sizeof(struct sl_output)));
    assert(output);
    output->ctx = ctx;
    output->id = id;
    output->version = MIN(3, version);
    output->host_global = sl_output_global_create(output);
    wl_list_insert(&ctx->outputs, &output->link);
    output->host_output = nullptr;
  } else if (strcmp(interface, "wl_seat") == 0) {
    struct sl_seat* seat =
        static_cast<sl_seat*>(malloc(sizeof(struct sl_seat)));
    assert(seat);
    seat->ctx = ctx;
    seat->id = id;
    seat->version = MIN(5, version);
    seat->last_serial = 0;
    seat->stylus_tablet = nullptr;
    seat->host_global = sl_seat_global_create(seat);
    wl_list_insert(&ctx->seats, &seat->link);
  } else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
    struct sl_relative_pointer_manager* relative_pointer =
        static_cast<sl_relative_pointer_manager*>(
            malloc(sizeof(struct sl_relative_pointer_manager)));
    assert(relative_pointer);
    relative_pointer->ctx = ctx;
    relative_pointer->id = id;
    assert(!ctx->relative_pointer_manager);
    ctx->relative_pointer_manager = relative_pointer;
    relative_pointer->host_global =
        sl_relative_pointer_manager_global_create(ctx);
  } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
    struct sl_pointer_constraints* pointer_constraints =
        static_cast<sl_pointer_constraints*>(
            malloc(sizeof(struct sl_pointer_constraints)));
    assert(pointer_constraints);
    pointer_constraints->ctx = ctx;
    pointer_constraints->id = id;
    assert(!ctx->pointer_constraints);
    ctx->pointer_constraints = pointer_constraints;
    pointer_constraints->host_global =
        sl_pointer_constraints_global_create(ctx);
  } else if (strcmp(interface, "wl_data_device_manager") == 0) {
    struct sl_data_device_manager* data_device_manager =
        static_cast<sl_data_device_manager*>(
            malloc(sizeof(struct sl_data_device_manager)));
    assert(data_device_manager);
    data_device_manager->ctx = ctx;
    data_device_manager->id = id;
    data_device_manager->version = MIN(3, version);
    data_device_manager->internal = nullptr;
    data_device_manager->host_global = nullptr;
    assert(!ctx->data_device_manager);
    ctx->data_device_manager = data_device_manager;
    if (ctx->xwayland) {
      data_device_manager->internal = static_cast<wl_data_device_manager*>(
          wl_registry_bind(registry, id, &wl_data_device_manager_interface,
                           data_device_manager->version));
    } else {
      data_device_manager->host_global =
          sl_data_device_manager_global_create(ctx);
    }
  } else if (strcmp(interface, "xdg_wm_base") == 0) {
    struct sl_xdg_shell* xdg_shell =
        static_cast<sl_xdg_shell*>(malloc(sizeof(struct sl_xdg_shell)));
    assert(xdg_shell);
    xdg_shell->ctx = ctx;
    xdg_shell->id = id;
    xdg_shell->version = MIN(SL_XDG_SHELL_MAX_VERSION, version);
    xdg_shell->internal = nullptr;
    xdg_shell->host_global = nullptr;
    assert(!ctx->xdg_shell);
    ctx->xdg_shell = xdg_shell;
    if (ctx->xwayland) {
      xdg_shell->internal = static_cast<xdg_wm_base*>(wl_registry_bind(
          registry, id, &xdg_wm_base_interface, xdg_shell->version));
      xdg_wm_base_add_listener(xdg_shell->internal,
                               &sl_internal_xdg_shell_listener, nullptr);
    } else {
      xdg_shell->host_global =
          sl_xdg_shell_global_create(ctx, xdg_shell->version);
    }
  } else if (strcmp(interface, "zaura_shell") == 0) {
    if (version >= MIN_AURA_SHELL_VERSION) {
      struct sl_aura_shell* aura_shell =
          static_cast<sl_aura_shell*>(malloc(sizeof(struct sl_aura_shell)));
      assert(aura_shell);
      aura_shell->ctx = ctx;
      aura_shell->id = id;
      aura_shell->version = MIN(MAX_AURA_SHELL_VERSION, version);
      aura_shell->host_gtk_shell_global = nullptr;
      aura_shell->internal = static_cast<zaura_shell*>(wl_registry_bind(
          registry, id, &zaura_shell_interface, aura_shell->version));
      assert(!ctx->aura_shell);
      ctx->aura_shell = aura_shell;
      aura_shell->host_gtk_shell_global = sl_gtk_shell_global_create(ctx);
    }
  } else if (strcmp(interface, "wp_viewporter") == 0) {
    struct sl_viewporter* viewporter =
        static_cast<sl_viewporter*>(malloc(sizeof(struct sl_viewporter)));
    assert(viewporter);
    viewporter->ctx = ctx;
    viewporter->id = id;
    viewporter->host_viewporter_global = nullptr;
    viewporter->internal = static_cast<wp_viewporter*>(
        wl_registry_bind(registry, id, &wp_viewporter_interface, 1));
    assert(!ctx->viewporter);
    ctx->viewporter = viewporter;
    viewporter->host_viewporter_global = sl_viewporter_global_create(ctx);
    // Allow non-integer scale.
    ctx->scale = MIN(MAX_SCALE, MAX(MIN_SCALE, ctx->desired_scale));
  } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0) {
    struct sl_linux_dmabuf* linux_dmabuf =
        static_cast<sl_linux_dmabuf*>(malloc(sizeof(struct sl_linux_dmabuf)));
    assert(linux_dmabuf);
    linux_dmabuf->ctx = ctx;
    linux_dmabuf->id = id;
    linux_dmabuf->version = MIN(SL_LINUX_DMABUF_MAX_VERSION, version);

    linux_dmabuf->host_drm_global = sl_drm_global_create(ctx, linux_dmabuf);

    if (ctx->enable_linux_dmabuf) {
      linux_dmabuf->host_linux_dmabuf_global =
          sl_linux_dmabuf_global_create(ctx, linux_dmabuf);
    }

    if (linux_dmabuf->version >= 2) {
      linux_dmabuf->proxy_v2 = static_cast<zwp_linux_dmabuf_v1*>(
          wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, 2));
    }

    ctx->linux_dmabuf = linux_dmabuf;
  } else if (strcmp(interface, "zwp_linux_explicit_synchronization_v1") == 0) {
    struct sl_linux_explicit_synchronization* linux_explicit_synchronization =
        static_cast<sl_linux_explicit_synchronization*>(
            malloc(sizeof(struct sl_linux_explicit_synchronization)));
    assert(linux_explicit_synchronization);
    linux_explicit_synchronization->ctx = ctx;
    linux_explicit_synchronization->id = id;
    linux_explicit_synchronization->internal =
        static_cast<zwp_linux_explicit_synchronization_v1*>(wl_registry_bind(
            registry, id, &zwp_linux_explicit_synchronization_v1_interface, 1));
    assert(!ctx->linux_explicit_synchronization);
    ctx->linux_explicit_synchronization = linux_explicit_synchronization;
  } else if (strcmp(interface, "zcr_keyboard_extension_v1") == 0) {
    struct sl_keyboard_extension* keyboard_extension =
        static_cast<sl_keyboard_extension*>(
            malloc(sizeof(struct sl_keyboard_extension)));
    assert(keyboard_extension);
    keyboard_extension->ctx = ctx;
    keyboard_extension->id = id;
    keyboard_extension->internal =
        static_cast<zcr_keyboard_extension_v1*>(wl_registry_bind(
            registry, id, &zcr_keyboard_extension_v1_interface, 1));
    assert(!ctx->keyboard_extension);
    ctx->keyboard_extension = keyboard_extension;
  } else if (strcmp(interface, "zwp_text_input_manager_v1") == 0) {
    struct sl_text_input_manager* text_input_manager =
        static_cast<sl_text_input_manager*>(
            malloc(sizeof(struct sl_text_input_manager)));
    assert(text_input_manager);
    text_input_manager->ctx = ctx;
    text_input_manager->id = id;
    text_input_manager->host_global =
        sl_text_input_manager_global_create(ctx, version);
    text_input_manager->host_crostini_manager_global =
        sl_text_input_crostini_manager_global_create(ctx);
    text_input_manager->host_x11_global = sl_text_input_x11_global_create(ctx);
    assert(!ctx->text_input_manager);
    ctx->text_input_manager = text_input_manager;
  } else if (strcmp(interface, "zcr_text_input_extension_v1") == 0) {
    struct sl_text_input_extension* text_input_extension =
        static_cast<sl_text_input_extension*>(
            malloc(sizeof(struct sl_text_input_extension)));
    assert(text_input_extension);
    text_input_extension->ctx = ctx;
    text_input_extension->id = id;
    text_input_extension->host_global =
        sl_text_input_extension_global_create(ctx, version);
    assert(!ctx->text_input_extension);
    ctx->text_input_extension = text_input_extension;
#ifdef GAMEPAD_SUPPORT
  } else if (strcmp(interface, "zcr_gaming_input_v2") == 0) {
    struct sl_gaming_input_manager* gaming_input_manager =
        static_cast<sl_gaming_input_manager*>(
            malloc(sizeof(struct sl_gaming_input_manager)));
    assert(gaming_input_manager);
    gaming_input_manager->ctx = ctx;
    gaming_input_manager->id = id;
    gaming_input_manager->internal = static_cast<zcr_gaming_input_v2*>(
        wl_registry_bind(registry, id, &zcr_gaming_input_v2_interface, 2));
    assert(!ctx->gaming_input_manager);
    ctx->gaming_input_manager = gaming_input_manager;
#endif
  } else if (strcmp(interface, "zcr_stylus_v2") == 0) {
    struct sl_stylus_input_manager* stylus_input_manager =
        static_cast<sl_stylus_input_manager*>(
            malloc(sizeof(struct sl_stylus_input_manager)));
    assert(stylus_input_manager);
    stylus_input_manager->ctx = ctx;
    stylus_input_manager->id = id;
    stylus_input_manager->internal = static_cast<zcr_stylus_v2*>(
        wl_registry_bind(registry, id, &zcr_stylus_v2_interface, 1));

    // Note: This does not forward the stylus-unstable-v2 protcol to the
    // clients. Instead, it exposes tablet-unstable-v2 protocol to the clients.
    // Note: This is the only user of ctx->stylus_input_manager
    stylus_input_manager->tablet_host_global =
        sl_stylus_to_tablet_manager_global_create(ctx);

    assert(!ctx->stylus_input_manager);
    ctx->stylus_input_manager = stylus_input_manager;
  } else if (strcmp(interface, "zxdg_output_manager_v1") == 0 &&
             ctx->use_direct_scale) {
    // This protocol cannot be bound unconditionally as doing so
    // causes issues under Crostini. For this reason we will only
    // bind it when we need to do so (direct mode enabled).

    struct sl_xdg_output_manager* output_manager =
        static_cast<sl_xdg_output_manager*>(
            malloc(sizeof(struct sl_xdg_output_manager)));
    assert(output_manager);

    output_manager->ctx = ctx;
    output_manager->id = id;
    output_manager->internal =
        static_cast<zxdg_output_manager_v1*>(wl_registry_bind(
            registry, id, &zxdg_output_manager_v1_interface, MIN(3, version)));
    ctx->xdg_output_manager = output_manager;
  } else if (strcmp(interface, wp_fractional_scale_manager_v1_interface.name) ==
             0) {
    struct sl_fractional_scale_manager* fractional_scale_manager =
        static_cast<sl_fractional_scale_manager*>(
            malloc(sizeof(struct sl_fractional_scale_manager)));
    assert(fractional_scale_manager);
    fractional_scale_manager->ctx = ctx;
    fractional_scale_manager->id = id;
    fractional_scale_manager->host_fractional_scale_manager_global = nullptr;
    fractional_scale_manager->internal =
        static_cast<wp_fractional_scale_manager_v1*>(wl_registry_bind(
            registry, id, &wp_fractional_scale_manager_v1_interface, 1));
    assert(!ctx->fractional_scale_manager);
    ctx->fractional_scale_manager = fractional_scale_manager;
    fractional_scale_manager->host_fractional_scale_manager_global =
        sl_fractional_scale_manager_global_create(ctx);
  } else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) {
    struct sl_idle_inhibit_manager* idle_inhibit =
        static_cast<sl_idle_inhibit_manager*>(
            malloc(sizeof(struct sl_idle_inhibit_manager)));
    assert(idle_inhibit);
    idle_inhibit->ctx = ctx;
    idle_inhibit->id = id;
    assert(!ctx->idle_inhibit_manager);
    ctx->idle_inhibit_manager = idle_inhibit;
    idle_inhibit->host_global = sl_idle_inhibit_manager_global_create(ctx);
  }
}

void sl_registry_remover(void* data,
                         struct wl_registry* registry,
                         uint32_t id) {
  TRACE_EVENT("other", "sl_registry_remover");
  struct sl_context* ctx = (struct sl_context*)data;
  struct sl_output* output;
  struct sl_seat* seat;

  if (ctx->compositor && ctx->compositor->id == id) {
    sl_global_destroy(ctx->compositor->host_global);
    wl_compositor_destroy(ctx->compositor->internal);
    free(ctx->compositor);
    ctx->compositor = nullptr;
    return;
  }
  if (ctx->subcompositor && ctx->subcompositor->id == id) {
    sl_global_destroy(ctx->subcompositor->host_global);
    wl_shm_destroy(ctx->shm->internal);
    free(ctx->subcompositor);
    ctx->subcompositor = nullptr;
    return;
  }
  if (ctx->shm && ctx->shm->id == id) {
    sl_global_destroy(ctx->shm->host_global);
    free(ctx->shm);
    ctx->shm = nullptr;
    return;
  }
  if (ctx->shell && ctx->shell->id == id) {
    sl_global_destroy(ctx->shell->host_global);
    free(ctx->shell);
    ctx->shell = nullptr;
    return;
  }
  if (ctx->data_device_manager && ctx->data_device_manager->id == id) {
    if (ctx->data_device_manager->host_global) {
      sl_global_destroy(ctx->data_device_manager->host_global);
    }
    if (ctx->data_device_manager->internal) {
      wl_data_device_manager_destroy(ctx->data_device_manager->internal);
    }
    free(ctx->data_device_manager);
    ctx->data_device_manager = nullptr;
    return;
  }
  if (ctx->xdg_shell && ctx->xdg_shell->id == id) {
    if (ctx->xdg_shell->host_global) {
      sl_global_destroy(ctx->xdg_shell->host_global);
    }
    if (ctx->xdg_shell->internal) {
      xdg_wm_base_destroy(ctx->xdg_shell->internal);
    }
    free(ctx->xdg_shell);
    ctx->xdg_shell = nullptr;
    return;
  }
  if (ctx->aura_shell && ctx->aura_shell->id == id) {
    if (ctx->aura_shell->host_gtk_shell_global) {
      sl_global_destroy(ctx->aura_shell->host_gtk_shell_global);
    }
    zaura_shell_destroy(ctx->aura_shell->internal);
    free(ctx->aura_shell);
    ctx->aura_shell = nullptr;
    return;
  }
  if (ctx->viewporter && ctx->viewporter->id == id) {
    if (ctx->viewporter->host_viewporter_global) {
      sl_global_destroy(ctx->viewporter->host_viewporter_global);
    }
    wp_viewporter_destroy(ctx->viewporter->internal);
    free(ctx->viewporter);
    ctx->viewporter = nullptr;
    return;
  }
  if (ctx->linux_dmabuf && ctx->linux_dmabuf->id == id) {
    if (ctx->linux_dmabuf->host_drm_global) {
      sl_global_destroy(ctx->linux_dmabuf->host_drm_global);
    }
    if (ctx->linux_dmabuf->proxy_v2) {
      zwp_linux_dmabuf_v1_destroy(ctx->linux_dmabuf->proxy_v2);
    }
    if (ctx->linux_dmabuf->host_linux_dmabuf_global) {
      sl_global_destroy(ctx->linux_dmabuf->host_linux_dmabuf_global);
    }
    free(ctx->linux_dmabuf);
    ctx->linux_dmabuf = nullptr;
    return;
  }
  if (ctx->linux_explicit_synchronization &&
      ctx->linux_explicit_synchronization->id == id) {
    zwp_linux_explicit_synchronization_v1_destroy(
        ctx->linux_explicit_synchronization->internal);
    free(ctx->linux_explicit_synchronization);
    ctx->linux_explicit_synchronization = nullptr;
    return;
  }
  if (ctx->keyboard_extension && ctx->keyboard_extension->id == id) {
    zcr_keyboard_extension_v1_destroy(ctx->keyboard_extension->internal);
    free(ctx->keyboard_extension);
    ctx->keyboard_extension = nullptr;
    return;
  }
  if (ctx->text_input_manager && ctx->text_input_manager->id == id) {
    sl_global_destroy(ctx->text_input_manager->host_global);
    free(ctx->text_input_manager);
    ctx->text_input_manager = nullptr;
    return;
  }
  if (ctx->text_input_extension && ctx->text_input_extension->id == id) {
    sl_global_destroy(ctx->text_input_extension->host_global);
    free(ctx->text_input_extension);
    ctx->text_input_extension = nullptr;
    return;
  }
#ifdef GAMEPAD_SUPPORT
  if (ctx->gaming_input_manager && ctx->gaming_input_manager->id == id) {
    zcr_gaming_input_v2_destroy(ctx->gaming_input_manager->internal);
    free(ctx->gaming_input_manager);
    ctx->gaming_input_manager = nullptr;
    return;
  }
#endif
  if (ctx->stylus_input_manager && ctx->stylus_input_manager->id == id) {
    sl_global_destroy(ctx->stylus_input_manager->tablet_host_global);
    free(ctx->stylus_input_manager);
    ctx->stylus_input_manager = nullptr;
  }
  if (ctx->relative_pointer_manager &&
      ctx->relative_pointer_manager->id == id) {
    sl_global_destroy(ctx->relative_pointer_manager->host_global);
    free(ctx->relative_pointer_manager);
    ctx->relative_pointer_manager = nullptr;
    return;
  }
  if (ctx->pointer_constraints && ctx->pointer_constraints->id == id) {
    sl_global_destroy(ctx->pointer_constraints->host_global);
    free(ctx->pointer_constraints);
    ctx->pointer_constraints = nullptr;
    return;
  }
  if (ctx->idle_inhibit_manager && ctx->idle_inhibit_manager->id == id) {
    sl_global_destroy(ctx->idle_inhibit_manager->host_global);
    free(ctx->idle_inhibit_manager);
    ctx->idle_inhibit_manager = nullptr;
    return;
  }
  wl_list_for_each(output, &ctx->outputs, link) {
    if (output->id == id) {
      sl_global_destroy(output->host_global);
      if (output->host_output) {
        wl_resource_destroy(output->host_output->resource);
      }
      wl_list_remove(&output->link);
      free(output);
      return;
    }
  }
  wl_list_for_each(seat, &ctx->seats, link) {
    if (seat->id == id) {
      sl_global_destroy(seat->host_global);
      wl_list_remove(&seat->link);
      free(seat);
      return;
    }
  }

  // Not reached.
  assert(0);
}

const struct wl_registry_listener sl_registry_listener = {sl_registry_handler,
                                                          sl_registry_remover};

static int sl_handle_event(int fd, uint32_t mask, void* data) {
  TRACE_EVENT("other", "sl_handle_event");
  struct sl_context* ctx = (struct sl_context*)data;
  int count = 0;

  if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
    wl_client_flush(ctx->client);
    exit(EXIT_SUCCESS);
  }

  if (mask & WL_EVENT_READABLE) {
    count = wl_display_dispatch(ctx->display);
  }
  if (mask & WL_EVENT_WRITABLE) {
    wl_display_flush(ctx->display);
  }

  if (mask == 0) {
    count = wl_display_dispatch_pending(ctx->display);
    wl_display_flush(ctx->display);
  }

  return count;
}

void sl_create_window(struct sl_context* ctx,
                      xcb_window_t id,
                      int x,
                      int y,
                      int width,
                      int height,
                      int border_width) {
  TRACE_EVENT("surface", "sl_create_window");
  sl_window* window = new sl_window(ctx, id, x, y, width, height, border_width);
  uint32_t values[1];
  values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_FOCUS_CHANGE;
  xcb()->change_window_attributes(ctx->connection, window->id,
                                  XCB_CW_EVENT_MASK, values);

  // Also enable shape events for this window to come in if the xshape
  // flag has been enabled
  if (ctx->enable_xshape) {
    xcb_shape_select_input(ctx->connection, id, 1);
  }
}

static void sl_destroy_window(struct sl_window* window) {
  TRACE_EVENT("surface", "sl_destroy_window");
  if (window->frame_id != XCB_WINDOW_NONE) {
    xcb_destroy_window(window->ctx->connection, window->frame_id);
  }

  if (window->xdg_popup) {
    xdg_popup_destroy(window->xdg_popup);
  }
  if (window->xdg_toplevel) {
    xdg_toplevel_destroy(window->xdg_toplevel);
  }
  if (window->xdg_surface) {
    xdg_surface_destroy(window->xdg_surface);
  }
  if (window->aura_surface) {
    zaura_surface_destroy(window->aura_surface);
  }

  delete window;
}

static int sl_is_window(struct sl_window* window, xcb_window_t id) {
  if (window->id == id) {
    return 1;
  }

  if (window->frame_id != XCB_WINDOW_NONE) {
    if (window->frame_id == id) {
      return 1;
    }
  }

  return 0;
}

struct sl_window* sl_lookup_window(struct sl_context* ctx, xcb_window_t id) {
  struct sl_window* window;

  wl_list_for_each(window, &ctx->windows, link) {
    if (sl_is_window(window, id)) {
      return window;
    }
  }
  wl_list_for_each(window, &ctx->unpaired_windows, link) {
    if (sl_is_window(window, id)) {
      return window;
    }
  }
  return nullptr;
}

int sl_is_our_window(struct sl_context* ctx, xcb_window_t id) {
  const xcb_setup_t* setup = xcb_get_setup(ctx->connection);

  return (id & ~setup->resource_id_mask) == setup->resource_id_base;
}

static void sl_handle_create_notify(struct sl_context* ctx,
                                    xcb_create_notify_event_t* event) {
  if (sl_is_our_window(ctx, event->window)) {
    return;
  }

  sl_create_window(ctx, event->window, event->x, event->y, event->width,
                   event->height, event->border_width);
}

void sl_handle_destroy_notify(struct sl_context* ctx,
                              xcb_destroy_notify_event_t* event) {
  struct sl_window* window;

  if (sl_is_our_window(ctx, event->window)) {
    return;
  }

  window = sl_lookup_window(ctx, event->window);
  if (!window) {
    return;
  }

  sl_destroy_window(window);
}

void sl_handle_reparent_notify(struct sl_context* ctx,
                               xcb_reparent_notify_event_t* event) {
  struct sl_window* window;

  if (event->parent == ctx->screen->root) {
    int width = 1;
    int height = 1;
    int border_width = 0;

    // Return early if window is already tracked. This happens when we
    // reparent an unampped window back to the root window.
    window = sl_lookup_window(ctx, event->window);
    if (window) {
      return;
    }

    xcb_get_geometry_reply_t* geometry_reply = xcb_get_geometry_reply(
        ctx->connection, xcb_get_geometry(ctx->connection, event->window),
        nullptr);

    if (geometry_reply) {
      width = geometry_reply->width;
      height = geometry_reply->height;
      border_width = geometry_reply->border_width;
      free(geometry_reply);
    }
    sl_create_window(ctx, event->window, event->x, event->y, width, height,
                     border_width);
    return;
  }

  if (sl_is_our_window(ctx, event->parent)) {
    return;
  }

  window = sl_lookup_window(ctx, event->window);
  if (!window) {
    return;
  }

  sl_destroy_window(window);
}

static const char* sl_decode_wm_class(struct sl_window* window,
                                      xcb_get_property_reply_t* reply) {
  // WM_CLASS property contains two consecutive null-terminated strings.
  // These specify the Instance and Class names. If a global app ID is
  // not set then use Class name for app ID.
  const char* value = static_cast<char*>(xcb()->get_property_value(reply));
  int value_length = xcb()->get_property_value_length(reply);
  int instance_length = strnlen(value, value_length);
  if (value_length > instance_length) {
    window->clazz = strndup(value + instance_length + 1,
                            value_length - instance_length - 1);

    if (!window->steam_game_id) {
      // If there's no known Steam Game ID for this window,
      // attempt to parse one from the class name.
      if (strncmp(window->clazz, STEAM_APP_CLASS_PREFIX,
                  strlen(STEAM_APP_CLASS_PREFIX)) == 0) {
        // atoi() returns 0 on error, in which case steam_game_id
        // simply remains effectively unset.
        window->steam_game_id =
            atoi(window->clazz + strlen(STEAM_APP_CLASS_PREFIX));
      }
    }
    return window->clazz;
  }
  return nullptr;
}

static void sl_set_application_id_from_atom(struct sl_context* ctx,
                                            struct sl_window* window,
                                            xcb_get_property_reply_t* reply) {
  if (reply->type == XCB_ATOM_CARDINAL) {
    uint32_t value = *static_cast<uint32_t*>(xcb()->get_property_value(reply));
    window->app_id_property = std::to_string(value);
  }
}

static void on_steam_game_id_updated(struct sl_context* ctx,
                                     struct sl_window* window,
                                     xcb_get_property_reply_t* reply) {
  if (reply->type == XCB_ATOM_CARDINAL) {
    window->steam_game_id =
        *static_cast<uint32_t*>(xcb()->get_property_value(reply));
  } else {
    window->steam_game_id = 0;
  }
}

void sl_handle_map_request(struct sl_context* ctx,
                           xcb_map_request_event_t* event) {
  TRACE_EVENT("shm", "sl_handle_map_request", [&](perfetto::EventContext p) {
    perfetto_annotate_window(ctx, p, "window", event->window);
  });
  struct sl_window* window = sl_lookup_window(ctx, event->window);
  struct {
    int type;
    xcb_atom_t atom;
  } properties[] = {
      {PROPERTY_WM_NAME, XCB_ATOM_WM_NAME},
      {PROPERTY_NET_WM_NAME, ctx->atoms[ATOM_NET_WM_NAME].value},
      {PROPERTY_WM_CLASS, XCB_ATOM_WM_CLASS},
      {PROPERTY_WM_TRANSIENT_FOR, XCB_ATOM_WM_TRANSIENT_FOR},
      {PROPERTY_WM_NORMAL_HINTS, XCB_ATOM_WM_NORMAL_HINTS},
      {PROPERTY_WM_CLIENT_LEADER, ctx->atoms[ATOM_WM_CLIENT_LEADER].value},
      {PROPERTY_WM_PROTOCOLS, ctx->atoms[ATOM_WM_PROTOCOLS].value},
      {PROPERTY_MOTIF_WM_HINTS, ctx->atoms[ATOM_MOTIF_WM_HINTS].value},
      {PROPERTY_NET_STARTUP_ID, ctx->atoms[ATOM_NET_STARTUP_ID].value},
      {PROPERTY_NET_WM_STATE, ctx->atoms[ATOM_NET_WM_STATE].value},
      {PROPERTY_GTK_THEME_VARIANT, ctx->atoms[ATOM_GTK_THEME_VARIANT].value},
      {PROPERTY_XWAYLAND_RANDR_EMU_MONITOR_RECTS,
       ctx->atoms[ATOM_XWAYLAND_RANDR_EMU_MONITOR_RECTS].value},
      {PROPERTY_STEAM_GAME, ctx->atoms[ATOM_STEAM_GAME].value},
      {PROPERTY_SPECIFIED_FOR_APP_ID, ctx->application_id_property_atom},
      {PROPERTY_NET_WM_WINDOW_TYPE, ctx->atoms[ATOM_NET_WM_WINDOW_TYPE].value},
      {PROPERTY_NET_WM_PID, ctx->atoms[ATOM_NET_WM_PID].value},
  };
  xcb_get_geometry_cookie_t geometry_cookie;
  xcb_get_property_cookie_t property_cookies[ARRAY_SIZE(properties)];
  struct sl_wm_size_hints size_hints = {0};
  struct sl_mwm_hints mwm_hints = {0};
  bool maximize_h = false, maximize_v = false, fullscreen = false;
  uint32_t values[5];

  if (!window) {
    return;
  }

  if (sl_is_our_window(ctx, event->window)) {
    return;
  }

  window->managed = 1;
  if (window->frame_id == XCB_WINDOW_NONE) {
    geometry_cookie = xcb()->get_geometry(ctx->connection, window->id);
  }

  for (unsigned i = 0; i < ARRAY_SIZE(properties); ++i) {
    property_cookies[i] =
        xcb()->get_property(ctx->connection, 0, window->id, properties[i].atom,
                            XCB_ATOM_ANY, 0, 2048);
  }

  if (window->frame_id == XCB_WINDOW_NONE) {
    xcb_get_geometry_reply_t* geometry_reply =
        xcb()->get_geometry_reply(ctx->connection, geometry_cookie, nullptr);
    if (geometry_reply) {
      window->x = geometry_reply->x;
      window->y = geometry_reply->y;
      window->width = geometry_reply->width;
      window->height = geometry_reply->height;
      window->depth = geometry_reply->depth;
      free(geometry_reply);
    }
  }

  free(window->name);
  window->name = nullptr;
  free(window->clazz);
  window->clazz = nullptr;
  free(window->startup_id);
  window->startup_id = nullptr;
  window->transient_for = XCB_WINDOW_NONE;
  window->client_leader = XCB_WINDOW_NONE;
  window->decorated = 1;
  window->size_flags = 0;
  window->dark_frame = 0;

  for (unsigned i = 0; i < ARRAY_SIZE(properties); ++i) {
    xcb_get_property_reply_t* reply = xcb()->get_property_reply(
        ctx->connection, property_cookies[i], nullptr);

    if (!reply) {
      continue;
    }

    if (reply->type == XCB_ATOM_NONE) {
      free(reply);
      continue;
    }

    const char* value = nullptr;
    int value_int = std::numeric_limits<int>::max();
    xcb_atom_t* property_values = nullptr;

    switch (properties[i].type) {
      case PROPERTY_WM_NAME:
        // WM_NAME is only used for the window name if _NET_WM_NAME is not
        // present or not yet processed, thus window->name is null.
        if (!window->has_net_wm_name) {
          window->name =
              strndup(static_cast<char*>(xcb()->get_property_value(reply)),
                      xcb()->get_property_value_length(reply));
          value = window->name;
        }
        break;
      case PROPERTY_NET_WM_NAME:
        // _NET_WM_NAME is the preferred window name property. Remove any
        // previously set window name.
        if (window->name) {
          free(window->name);
          window->name = nullptr;
        }
        window->has_net_wm_name = true;
        window->name =
            strndup(static_cast<char*>(xcb()->get_property_value(reply)),
                    xcb()->get_property_value_length(reply));
        value = window->name;
        break;
      case PROPERTY_WM_CLASS:
        value = sl_decode_wm_class(window, reply);
        if (!value) {
          value = "<invalid>";
        }
        break;
      case PROPERTY_WM_TRANSIENT_FOR:
        if (xcb()->get_property_value_length(reply) >= 4) {
          window->transient_for =
              *(reinterpret_cast<uint32_t*>(xcb()->get_property_value(reply)));
          value_int = window->transient_for;
        }
        break;
      case PROPERTY_WM_NORMAL_HINTS:
        if (xcb()->get_property_value_length(reply) >=
            static_cast<int>(sizeof(size_hints))) {
          memcpy(&size_hints, xcb()->get_property_value(reply),
                 sizeof(size_hints));
        }
        break;
      case PROPERTY_WM_CLIENT_LEADER:
        if (xcb()->get_property_value_length(reply) >= 4) {
          window->client_leader =
              *(reinterpret_cast<uint32_t*>(xcb()->get_property_value(reply)));
          value_int = window->client_leader;
        }
        break;
      case PROPERTY_WM_PROTOCOLS:
        property_values =
            static_cast<xcb_atom_t*>(xcb()->get_property_value(reply));
        for (unsigned j = 0;
             j < xcb()->get_property_value_length(reply) / sizeof(xcb_atom_t);
             ++j) {
          if (property_values[j] == ctx->atoms[ATOM_WM_TAKE_FOCUS].value) {
            window->focus_model_take_focus = 1;
            value = "ATOM_WM_TAKE_FOCUS";
          }
        }
        break;
      case PROPERTY_MOTIF_WM_HINTS:
        if (xcb()->get_property_value_length(reply) >=
            static_cast<int>(sizeof(mwm_hints))) {
          memcpy(&mwm_hints, xcb()->get_property_value(reply),
                 sizeof(mwm_hints));
        }
        break;
      case PROPERTY_NET_STARTUP_ID:
        window->startup_id =
            strndup(static_cast<char*>(xcb()->get_property_value(reply)),
                    xcb()->get_property_value_length(reply));
        value = window->startup_id;
        break;
      case PROPERTY_NET_WM_STATE:
        property_values =
            static_cast<xcb_atom_t*>(xcb()->get_property_value(reply));
        for (unsigned j = 0;
             j < xcb()->get_property_value_length(reply) / sizeof(xcb_atom_t);
             ++j) {
          if (property_values[j] ==
              ctx->atoms[ATOM_NET_WM_STATE_MAXIMIZED_HORZ].value) {
            maximize_h = true;
          } else if (property_values[j] ==
                     ctx->atoms[ATOM_NET_WM_STATE_MAXIMIZED_VERT].value) {
            maximize_v = true;
          } else if (property_values[j] ==
                     ctx->atoms[ATOM_NET_WM_STATE_FULLSCREEN].value) {
            fullscreen = true;
          }
        }
        // Neither wayland not CrOS support 1D maximizing, so sommelier will
        // only consider a window maximized if both dimensions are. This
        // behaviour is consistent with sl_handle_client_message().
        window->maximized = maximize_h && maximize_v;
        window->fullscreen = fullscreen;
        LOG(VERBOSE) << window << " fullscreen=" << fullscreen;
        if (window->maximized) {
          if (window->fullscreen) {
            value =
                "_NET_WM_STATE_FULLSCREEN, _NET_WM_STATE_MAXIMIZED_VERT && "
                "HORZ";
          } else {
            value = "_NET_WM_STATE_MAXIMIZED_VERT && HORZ";
          }
        } else if (window->fullscreen) {
          value = "_NET_WM_STATE_FULLSCREEN";
        }
        break;
      case PROPERTY_GTK_THEME_VARIANT:
        if (xcb()->get_property_value_length(reply) >= 4) {
          window->dark_frame = !strcmp(
              static_cast<char*>(xcb()->get_property_value(reply)), "dark");
        }
        break;
      case PROPERTY_STEAM_GAME:
        on_steam_game_id_updated(ctx, window, reply);
        break;
      case PROPERTY_SPECIFIED_FOR_APP_ID:
        sl_set_application_id_from_atom(ctx, window, reply);
        value = window->app_id_property.c_str();
        break;
      case PROPERTY_NET_WM_WINDOW_TYPE:
        property_values =
            static_cast<xcb_atom_t*>(xcb()->get_property_value(reply));
        if (xcb()->get_property_value_length(reply) == sizeof(xcb_atom_t)) {
          window->type = property_values[0];
        }
        break;
      case PROPERTY_NET_WM_PID:
        property_values =
            static_cast<xcb_atom_t*>(xcb()->get_property_value(reply));
        if (xcb()->get_property_value_length(reply) == sizeof(xcb_atom_t)) {
          window->pid = property_values[0];
          // Double check if the window should be containerized
          sl_window_update_should_be_containerized_from_pid(window);
        }
        break;
      default:
        break;
    }

    TRACE_EVENT("x11wm", "XCB_MAP_REQUEST: X property",
                [&](perfetto::EventContext p) {
                  perfetto_annotate_atom(ctx, p, "name", properties[i].atom);

                  if (value_int != std::numeric_limits<int>::max()) {
                    auto* dbg = p.event()->add_debug_annotations();
                    dbg->set_name("int value");
                    dbg->set_int_value(value_int);
                  }
                  if (value) {
                    auto* dbg = p.event()->add_debug_annotations();
                    dbg->set_name("str value");
                    dbg->set_string_value(value, strlen(value));
                  }

                  switch (properties[i].type) {
                    case PROPERTY_WM_NORMAL_HINTS:
                      perfetto_annotate_size_hints(p, size_hints);
                      break;
                    case PROPERTY_XWAYLAND_RANDR_EMU_MONITOR_RECTS:
                      perfetto_annotate_cardinal_list(p, "value", reply);
                      break;
                  }
                });
#ifndef PERFETTO_TRACING
    UNUSED(value_int);
#endif

    free(reply);
  }

  if (mwm_hints.flags & MWM_HINTS_DECORATIONS) {
    if (mwm_hints.decorations & MWM_DECOR_ALL) {
      window->decorated = ~mwm_hints.decorations & MWM_DECOR_TITLE;
    } else {
      window->decorated = mwm_hints.decorations & MWM_DECOR_TITLE;
    }
  }

  // Allow user/program controlled position for transients,
  // and other client-positioned windows.
  if (window->transient_for || sl_window_is_client_positioned(window)) {
    window->size_flags |= size_hints.flags & (US_POSITION | P_POSITION);
  }

  // If startup ID is not set, then try the client leader window.
  if (!window->startup_id && window->client_leader) {
    xcb_get_property_reply_t* reply = xcb()->get_property_reply(
        ctx->connection,
        xcb()->get_property(ctx->connection, 0, window->client_leader,
                            ctx->atoms[ATOM_NET_STARTUP_ID].value, XCB_ATOM_ANY,
                            0, 2048),
        nullptr);
    if (reply) {
      if (reply->type != XCB_ATOM_NONE) {
        window->startup_id =
            strndup(static_cast<char*>(xcb()->get_property_value(reply)),
                    xcb()->get_property_value_length(reply));
      }
      free(reply);
    }
  }

  window->size_flags |= size_hints.flags & (P_MIN_SIZE | P_MAX_SIZE);
  if (window->size_flags & P_MIN_SIZE) {
    window->min_width = size_hints.min_width;
    window->min_height = size_hints.min_height;
    LOG(VERBOSE) << window << " min=" << window->min_width << "x"
                 << window->min_height;
  }
  if (window->size_flags & P_MAX_SIZE) {
    if (size_hints.max_width < INT_MAX) {
      window->max_width = size_hints.max_width;
    } else {
      window->max_width = 0;
    }
    if (size_hints.max_height < INT_MAX) {
      window->max_height = size_hints.max_height;
    } else {
      window->max_height = 0;
    }
    LOG(VERBOSE) << window << " max=" << window->max_width << "x"
                 << window->max_height;
  }

  window->border_width = 0;
  sl_adjust_window_size_for_screen_size(window);
  if (!(window->size_flags & (US_POSITION | P_POSITION))) {
    sl_adjust_window_position_for_screen_size(window);
  }

  sl_window_get_width_height(window, &values[0], &values[1]);
  values[2] = 0;
  xcb()->configure_window(ctx->connection, window->id,
                          XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT |
                              XCB_CONFIG_WINDOW_BORDER_WIDTH,
                          values);
  // This needs to match the frame extents of the X11 frame window used
  // for reparenting or applications tend to be confused. The actual window
  // frame size used by the host compositor can be different.
  values[0] = 0;
  values[1] = 0;
  values[2] = 0;
  values[3] = 0;
  xcb()->change_property(ctx->connection, XCB_PROP_MODE_REPLACE, window->id,
                         ctx->atoms[ATOM_NET_FRAME_EXTENTS].value,
                         XCB_ATOM_CARDINAL, 32, 4, values);

  // Remove weird gravities.
  values[0] = XCB_GRAVITY_NORTH_WEST;
  xcb()->change_window_attributes(ctx->connection, window->id,
                                  XCB_CW_WIN_GRAVITY, values);

  if (window->frame_id == XCB_WINDOW_NONE) {
    int depth = window->depth ? window->depth : ctx->screen->root_depth;

    values[0] = ctx->screen->black_pixel;
    values[1] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
                XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
    values[2] = ctx->colormaps[depth];

    window->frame_id = xcb()->generate_id(ctx->connection);
    xcb()->create_window(
        ctx->connection, depth, window->frame_id, ctx->screen->root, window->x,
        window->y, window->width, window->height, 0,
        XCB_WINDOW_CLASS_INPUT_OUTPUT, ctx->visual_ids[depth],
        XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP, values);
    values[0] = XCB_STACK_MODE_BELOW;
    xcb()->configure_window(ctx->connection, window->frame_id,
                            XCB_CONFIG_WINDOW_STACK_MODE, values);
    xcb()->reparent_window(ctx->connection, window->id, window->frame_id, 0, 0);
  } else {
    // Populate values[0~3] with x,y,w,h
    sl_window_get_x_y(window, &values[0], &values[1]);
    sl_window_get_width_height(window, &values[2], &values[3]);
    values[4] = XCB_STACK_MODE_BELOW;
    xcb()->configure_window(
        ctx->connection, window->frame_id,
        XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH |
            XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_STACK_MODE,
        values);
  }

  sl_window_set_wm_state(window, WM_STATE_NORMAL);
  sl_send_configure_notify(window);

  xcb()->map_window(ctx->connection, window->id);
  xcb()->map_window(ctx->connection, window->frame_id);
}

static void sl_handle_map_notify(struct sl_context* ctx,
                                 xcb_map_notify_event_t* event) {}

void sl_handle_unmap_notify(struct sl_context* ctx,
                            xcb_unmap_notify_event_t* event) {
  struct sl_window* window;

  if (sl_is_our_window(ctx, event->window)) {
    return;
  }

  if (event->response_type & SEND_EVENT_MASK) {
    return;
  }

  window = sl_lookup_window(ctx, event->window);
  if (!window) {
    return;
  }

  if (ctx->host_focus_window == window) {
    ctx->host_focus_window = nullptr;
    ctx->needs_set_input_focus = 1;
  }

  if (window->host_surface_id) {
    window->host_surface_id = 0;
    sl_window_update(window);
  }

  sl_window_set_wm_state(window, WM_STATE_WITHDRAWN);

  // Reparent window and destroy frame if it exists.
  if (window->frame_id != XCB_WINDOW_NONE) {
    xcb_reparent_window(ctx->connection, window->id, ctx->screen->root,
                        window->x, window->y);
    xcb_destroy_window(ctx->connection, window->frame_id);
    window->frame_id = XCB_WINDOW_NONE;
  }

  // Reset properties to unmanaged state in case the window transitions to
  // an override-redirect window.
  window->managed = 0;
  window->decorated = 0;
  window->size_flags = P_POSITION;
}

void sl_handle_configure_request(struct sl_context* ctx,
                                 xcb_configure_request_event_t* event) {
  struct sl_window* window = sl_lookup_window(ctx, event->window);
  if (!window) {
    return;
  }
  int width = window->width;
  int height = window->height;
  uint32_t values[7];

  if (sl_is_our_window(ctx, event->window)) {
    return;
  }

  if (!window->managed) {
    int i = 0;

    if (event->value_mask & XCB_CONFIG_WINDOW_X) {
      values[i++] = event->x;
    }
    if (event->value_mask & XCB_CONFIG_WINDOW_Y) {
      values[i++] = event->y;
    }
    if (event->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
      values[i++] = event->width;
    }
    if (event->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
      values[i++] = event->height;
    }
    if (event->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) {
      values[i++] = event->border_width;
    }
    if (event->value_mask & XCB_CONFIG_WINDOW_SIBLING) {
      values[i++] = event->sibling;
    }
    if (event->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) {
      values[i++] = event->stack_mode;
    }

    xcb_configure_window(ctx->connection, window->id, event->value_mask,
                         values);
    return;
  }

  // Ack configure events as satisfying request removes the guarantee
  // that matching contents will arrive.
  if (window->xdg_toplevel) {
    if (window->pending_config.serial) {
      xdg_surface_ack_configure(window->xdg_surface,
                                window->pending_config.serial);
      window->pending_config.serial = 0;
      window->pending_config.mask = 0;
      window->pending_config.states_length = 0;
    }
    if (window->next_config.serial) {
      xdg_surface_ack_configure(window->xdg_surface,
                                window->next_config.serial);
      window->next_config.serial = 0;
      window->next_config.mask = 0;
      window->next_config.states_length = 0;
    }
  }

  if (event->value_mask & XCB_CONFIG_WINDOW_X) {
    window->x = event->x;
  }
  if (event->value_mask & XCB_CONFIG_WINDOW_Y) {
    window->y = event->y;
  }

  if (window->allow_resize) {
    if (event->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
      window->width = event->width;
    }
    if (event->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
      window->height = event->height;
    }
  }

  sl_adjust_window_size_for_screen_size(window);
  if (window->size_flags & (US_POSITION | P_POSITION)) {
    sl_window_update(window);
  } else {
    sl_adjust_window_position_for_screen_size(window);
  }

  // Populate values[0~3] with x,y,w,h
  sl_window_get_x_y(window, &values[0], &values[1]);
  sl_window_get_width_height(window, &values[2], &values[3]);
  values[4] = 0;
  xcb_configure_window(ctx->connection, window->frame_id,
                       XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
                           XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
                       values);

  // We need to send a synthetic configure notify if:
  // - Not changing the size, location, border width.
  // - Moving the window without resizing it or changing its border width.
  if (width != window->width || height != window->height ||
      window->border_width) {
    xcb_configure_window(ctx->connection, window->id,
                         XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT |
                             XCB_CONFIG_WINDOW_BORDER_WIDTH,
                         &values[2]);
    window->border_width = 0;
  } else {
    sl_send_configure_notify(window);
  }

  // If client requested a location change, forward that to the host.
  //
  // This is handled as a special case because there's no existing way
  // to send location changes, and it's done only upon ConfigureRequest
  // since most of the time the host has authority over window position
  // (important so that window dragging works properly, for example).
  //
  // This implies sending width and height as well, only because we
  // don't have a way to omit them from the request.
  if (event->value_mask & (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y)) {
    sl_toplevel_send_window_bounds_to_host(window);
  }
}

static void sl_handle_configure_notify(struct sl_context* ctx,
                                       xcb_configure_notify_event_t* event) {
  struct sl_window* window;

  if (sl_is_our_window(ctx, event->window)) {
    return;
  }

  if (event->window == ctx->screen->root) {
    xcb_get_geometry_reply_t* geometry_reply = xcb_get_geometry_reply(
        ctx->connection, xcb_get_geometry(ctx->connection, event->window),
        nullptr);
    int width = ctx->screen->width_in_pixels;
    int height = ctx->screen->height_in_pixels;

    if (geometry_reply) {
      width = geometry_reply->width;
      height = geometry_reply->height;
      free(geometry_reply);
    }

    if (width == ctx->screen->width_in_pixels ||
        height == ctx->screen->height_in_pixels) {
      return;
    }

    ctx->screen->width_in_pixels = width;
    ctx->screen->height_in_pixels = height;

    // Re-center managed windows.
    wl_list_for_each(window, &ctx->windows, link) {
      int x, y;

      if (window->size_flags & (US_POSITION | P_POSITION)) {
        continue;
      }

      x = window->x;
      y = window->y;
      sl_adjust_window_position_for_screen_size(window);
      if (window->x != x || window->y != y) {
        uint32_t values[2];

        values[0] = window->x;
        values[1] = window->y;
        xcb_configure_window(ctx->connection, window->frame_id,
                             XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values);
        sl_send_configure_notify(window);
      }
    }
    return;
  }

  window = sl_lookup_window(ctx, event->window);
  if (!window) {
    return;
  }

  if (window->managed) {
    return;
  }

  window->width = event->width;
  window->height = event->height;
  window->border_width = event->border_width;
  if (event->x != window->x || event->y != window->y) {
    window->x = event->x;
    window->y = event->y;
    sl_window_update(window);
  }
}

static uint32_t sl_resize_edge(int net_wm_moveresize_size) {
  switch (net_wm_moveresize_size) {
    case NET_WM_MOVERESIZE_SIZE_TOPLEFT:
      return XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
    case NET_WM_MOVERESIZE_SIZE_TOP:
      return XDG_TOPLEVEL_RESIZE_EDGE_TOP;
    case NET_WM_MOVERESIZE_SIZE_TOPRIGHT:
      return XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
    case NET_WM_MOVERESIZE_SIZE_RIGHT:
      return XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
    case NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
      return XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
    case NET_WM_MOVERESIZE_SIZE_BOTTOM:
      return XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
    case NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
      return XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
    case NET_WM_MOVERESIZE_SIZE_LEFT:
      return XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
    default:
      return XDG_TOPLEVEL_RESIZE_EDGE_NONE;
  }
}

static void sl_request_attention(struct sl_context* ctx,
                                 struct sl_window* window,
                                 bool is_strong_request) {
  if (!window->aura_surface ||
      ctx->aura_shell->version < ZAURA_SURFACE_DRAW_ATTENTION_SINCE_VERSION) {
    return;
  }
  if (is_strong_request) {
    zaura_surface_activate(window->aura_surface);
  } else {
    zaura_surface_draw_attention(window->aura_surface);
  }
}

void sl_handle_client_message(struct sl_context* ctx,
                              xcb_client_message_event_t* event) {
  TRACE_EVENT("x11wm", "XCB_CLIENT_MESSAGE", [&](perfetto::EventContext p) {
    perfetto_annotate_atom(ctx, p, "event->type", event->type);
    perfetto_annotate_window(ctx, p, "event->window", event->window);
  });
  if (event->type == ctx->atoms[ATOM_WL_SURFACE_ID].value) {
    struct sl_window *window, *unpaired_window = nullptr;

    wl_list_for_each(window, &ctx->unpaired_windows, link) {
      if (sl_is_window(window, event->window)) {
        unpaired_window = window;
        break;
      }
    }

    if (unpaired_window) {
      unpaired_window->host_surface_id = event->data.data32[0];
      sl_window_update(unpaired_window);
    }
  } else if (event->type == ctx->atoms[ATOM_NET_ACTIVE_WINDOW].value) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);
    if (window) {
      sl_request_attention(ctx, window, /*is_strong_request=*/true);
    }
  } else if (event->type == ctx->atoms[ATOM_NET_WM_MOVERESIZE].value) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);

    if (window && window->xdg_toplevel) {
      struct sl_host_seat* seat = window->ctx->default_seat;

      if (!seat) {
        return;
      }

      if (event->data.data32[2] == NET_WM_MOVERESIZE_MOVE) {
        xdg_toplevel_move(window->xdg_toplevel, seat->proxy,
                          seat->seat->last_serial);
      } else {
        uint32_t edge = sl_resize_edge(event->data.data32[2]);

        if (edge == XDG_TOPLEVEL_RESIZE_EDGE_NONE) {
          return;
        }

        xdg_toplevel_resize(window->xdg_toplevel, seat->proxy,
                            seat->seat->last_serial, edge);
      }
    }
  } else if (event->type == ctx->atoms[ATOM_NET_WM_STATE].value) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);

    if (window) {
      int changed[ATOM_LAST + 1];
      uint32_t action = event->data.data32[0];
      unsigned i;

      for (i = 0; i < ARRAY_SIZE(ctx->atoms); ++i) {
        changed[i] = event->data.data32[1] == ctx->atoms[i].value ||
                     event->data.data32[2] == ctx->atoms[i].value;
      }

      if (changed[ATOM_NET_WM_STATE_FULLSCREEN]) {
        TRACE_EVENT("x11wm", "XCB_CLIENT_MESSAGE: ATOM_NET_WM_STATE_FULLSCREEN",
                    "action", net_wm_state_to_string(action), "window->name",
                    window->name);
        if (action == NET_WM_STATE_ADD) {
          // Ignore additional calls to change to fullscreen
          // if X11 state is already fullscreen. Prevents issues when changing
          // focus back to game and Exo/X11 state differ.
          if (!window->fullscreen) {
            window->fullscreen = 1;
            LOG(VERBOSE) << window << " fullscreen=1";
            if (window->xdg_toplevel && !window->iconified) {
              xdg_toplevel_set_fullscreen(window->xdg_toplevel, nullptr);
            } else {
              window->pending_fullscreen_change = true;
            }
          }
        } else if (action == NET_WM_STATE_REMOVE) {
          // Ignore additional calls to change to windowed
          // if X11 state is already windowed. Prevents issues when changing
          // focus back to game and Exo/X11 state differ.
          if (window->fullscreen) {
            // Preemptively ask Exo to remove fullscreen then check during
            // surface commit (ie. after all states aggregated).
            window->maybe_promote_to_fullscreen = true;

            window->fullscreen = 0;
            LOG(VERBOSE) << window << " fullscreen=0";
            if (window->xdg_toplevel && !window->iconified) {
              xdg_toplevel_unset_fullscreen(window->xdg_toplevel);
            } else {
              window->pending_fullscreen_change = true;
            }
          }
        }
      }

      if (changed[ATOM_NET_WM_STATE_MAXIMIZED_VERT] &&
          changed[ATOM_NET_WM_STATE_MAXIMIZED_HORZ]) {
        TRACE_EVENT(
            "x11wm",
            "XCB_CLIENT_MESSAGE: ATOM_NET_WM_STATE_MAXIMIZED_VERT && HORZ",
            "action", net_wm_state_to_string(action), "window->name",
            window->name);
        if (action == NET_WM_STATE_ADD) {
          window->maximized = 1;
          if (window->xdg_toplevel && !window->iconified) {
            xdg_toplevel_set_maximized(window->xdg_toplevel);
          } else {
            window->pending_maximized_change = true;
          }
        } else if (action == NET_WM_STATE_REMOVE) {
          window->maximized = 0;
          if (window->xdg_toplevel && !window->iconified) {
            xdg_toplevel_unset_maximized(window->xdg_toplevel);
          } else {
            window->pending_maximized_change = true;
          }
        }
      }
    }
  } else if (event->type == ctx->atoms[ATOM_WM_CHANGE_STATE].value &&
             event->data.data32[0] == WM_STATE_ICONIC) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);
    TRACE_EVENT("x11wm", "XCB_CLIENT_MESSAGE: WM_STATE_ICONIC (minimize)",
                "window->name", window ? window->name : "<unknown>");
    if (window && window->xdg_toplevel) {
      xdg_toplevel_set_minimized(window->xdg_toplevel);
#ifdef QUIRKS_SUPPORT
      // TODO(b/333819234): Migrate FEATURE_BLACK_SCREEN_FIX to quirk condition
      // `runtime: Proton`.
      if (window->ctx->quirks.IsEnabled(window,
                                        quirks::FEATURE_BLACK_SCREEN_FIX)) {
        // Workaround for some borealis apps showing a black screen after losing
        // focus from fullscreen.
        // When a window is iconified, it should be unmapped. To return it back
        // to a visible state, it should be remapped. However sommelier does not
        // do this. Therefore we are sending a synthetic unmap then map notify
        // so that the app is rendered again.
        xcb_unmap_notify_event_t unmap_event = {
            .response_type = XCB_UNMAP_NOTIFY,
            .pad0 = 0,
            .event = window->id,
            .window = window->id,
            .from_configure = 0};

        xcb_send_event(ctx->connection, 0, window->id,
                       XCB_EVENT_MASK_STRUCTURE_NOTIFY,
                       reinterpret_cast<char*>(&unmap_event));
        sl_send_configure_notify(window);

        sl_window_set_wm_state(window, WM_STATE_ICONIC);
        sl_send_configure_notify(window);

        // When we are iconified we want to suppress any calls that deiconify
        // the window as it should in theory be unmapped.
        window->iconified = 1;
      }
#endif  // QUIRKS_SUPPORT
    }
  }
}

void sl_handle_focus_in(struct sl_context* ctx, xcb_focus_in_event_t* event) {
  struct sl_window* window = sl_lookup_window(ctx, event->event);
  if (window && window->transient_for != XCB_WINDOW_NONE) {
    // Set our parent now as it might not have been set properly when the
    // window was realized.
    struct sl_window* parent = sl_lookup_window(ctx, window->transient_for);
    if (parent && parent->xdg_toplevel && window->xdg_toplevel) {
      xdg_toplevel_set_parent(window->xdg_toplevel, parent->xdg_toplevel);
    }
  }
  if (window) {
    if (window->xdg_toplevel && window->pending_fullscreen_change) {
      if (window->fullscreen) {
        xdg_toplevel_set_fullscreen(window->xdg_toplevel, nullptr);
      } else {
        xdg_toplevel_unset_fullscreen(window->xdg_toplevel);
      }

      window->pending_fullscreen_change = false;
    }
    if (window->xdg_toplevel && window->pending_maximized_change) {
      if (window->maximized) {
        xdg_toplevel_set_maximized(window->xdg_toplevel);
      } else {
        xdg_toplevel_unset_maximized(window->xdg_toplevel);
      }
      window->pending_maximized_change = false;
    }
    if (window->iconified) {
      // Remap the window that was iconified upon gaining focus.
      xcb_map_notify_event_t map_event = {.response_type = XCB_MAP_NOTIFY,
                                          .pad0 = 0,
                                          .event = window->id,
                                          .window = window->id,
                                          .override_redirect = 0};

      xcb_send_event(window->ctx->connection, 0, window->id,
                     XCB_EVENT_MASK_STRUCTURE_NOTIFY,
                     reinterpret_cast<char*>(&map_event));
      sl_send_configure_notify(window);

      sl_window_set_wm_state(window, WM_STATE_NORMAL);
      sl_send_configure_notify(window);

      xcb_flush(window->ctx->connection);

      window->iconified = 0;
    }
  }
}

static void sl_handle_focus_out(struct sl_context* ctx,
                                xcb_focus_out_event_t* event) {}

int sl_begin_data_source_send(struct sl_context* ctx,
                              int fd,
                              xcb_intern_atom_cookie_t cookie,
                              struct sl_data_source* data_source) {
  xcb_intern_atom_reply_t* reply =
      xcb_intern_atom_reply(ctx->connection, cookie, nullptr);

  if (!reply) {
    close(fd);
    return 0;
  }

  int flags, rv;

  xcb_convert_selection(ctx->connection, ctx->selection_window,
                        ctx->atoms[ATOM_CLIPBOARD].value, reply->atom,
                        ctx->atoms[ATOM_WL_SELECTION].value, XCB_CURRENT_TIME);

  flags = fcntl(fd, F_GETFL, 0);
  rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
  errno_assert(!rv);

  ctx->selection_data_source_send_fd = fd;
  free(reply);
  return 1;
}

void sl_process_data_source_send_pending_list(struct sl_context* ctx) {
  while (!wl_list_empty(&ctx->selection_data_source_send_pending)) {
    struct wl_list* next = ctx->selection_data_source_send_pending.next;
    struct sl_data_source_send_request* request;
    request = wl_container_of(next, request, link);
    wl_list_remove(next);

    int rv = sl_begin_data_source_send(ctx, request->fd, request->cookie,
                                       request->data_source);
    free(request);
    if (rv) {
      break;
    }
  }
}

static int sl_handle_selection_fd_writable(int fd, uint32_t mask, void* data) {
  struct sl_context* ctx = static_cast<sl_context*>(data);
  int bytes, bytes_left;

  uint8_t* value = static_cast<uint8_t*>(
      xcb_get_property_value(ctx->selection_property_reply));
  bytes_left = xcb_get_property_value_length(ctx->selection_property_reply) -
               ctx->selection_property_offset;

  bytes = write(fd, value + ctx->selection_property_offset, bytes_left);
  if (bytes == -1) {
    LOG(ERROR) << "write error to target fd: " << strerror(errno);
    close(fd);
    fd = -1;
  } else if (bytes == bytes_left) {
    if (ctx->selection_incremental_transfer) {
      xcb_delete_property(ctx->connection, ctx->selection_window,
                          ctx->atoms[ATOM_WL_SELECTION].value);
    } else {
      close(fd);
      fd = -1;
    }
  } else {
    ctx->selection_property_offset += bytes;
    return 1;
  }

  free(ctx->selection_property_reply);
  ctx->selection_property_reply = nullptr;
  if (ctx->selection_send_event_source) {
    ctx->selection_send_event_source.reset();
  }
  if (fd < 0) {
    ctx->selection_data_source_send_fd = -1;
    sl_process_data_source_send_pending_list(ctx);
  }
  return 1;
}

static void sl_write_selection_property(struct sl_context* ctx,
                                        xcb_get_property_reply_t* reply) {
  ctx->selection_property_offset = 0;
  ctx->selection_property_reply = reply;
  sl_handle_selection_fd_writable(ctx->selection_data_source_send_fd,
                                  WL_EVENT_WRITABLE, ctx);

  if (!ctx->selection_property_reply) {
    return;
  }

  assert(!ctx->selection_send_event_source);
  ctx->selection_send_event_source.reset(wl_event_loop_add_fd(
      wl_display_get_event_loop(ctx->host_display),
      ctx->selection_data_source_send_fd, WL_EVENT_WRITABLE,
      sl_handle_selection_fd_writable, ctx));
}

static void sl_send_selection_notify(struct sl_context* ctx,
                                     xcb_atom_t property) {
  TRACE_EVENT("other", "sl_send_selection_notify");
  xcb_selection_notify_event_t event = {
      .response_type = XCB_SELECTION_NOTIFY,
      .pad0 = 0,
      .sequence = 0,
      .time = ctx->selection_request.time,
      .requestor = ctx->selection_request.requestor,
      .selection = ctx->selection_request.selection,
      .target = ctx->selection_request.target,
      .property = property};

  xcb_send_event(ctx->connection, 0, ctx->selection_request.requestor,
                 XCB_EVENT_MASK_NO_EVENT, reinterpret_cast<char*>(&event));
}

static void sl_send_selection_data(struct sl_context* ctx) {
  assert(!ctx->selection_data_ack_pending);
  xcb_change_property(
      ctx->connection, XCB_PROP_MODE_REPLACE, ctx->selection_request.requestor,
      ctx->selection_request.property, ctx->selection_data_type,
      /*format=*/8, ctx->selection_data.size, ctx->selection_data.data);
  ctx->selection_data_ack_pending = 1;
  ctx->selection_data.size = 0;
}

static const uint32_t sl_incr_chunk_size = 64 * 1024;

static int sl_handle_selection_fd_readable(int fd, uint32_t mask, void* data) {
  struct sl_context* ctx = static_cast<sl_context*>(data);

  // When a selection starts, the wl_array in |ctx->selection_data| is
  // initialized with a size of zero. Since we now need to actually write into
  // it, allocate |sl_incr_chunk_size| bytes to store the selection data in. We
  // need to buffer this much to decide between a one-shot transfer and an
  // incremental transfer, as this decision must be made before the first
  // response is sent.
  if (ctx->selection_data.alloc == 0) {
    // wl_array_add is ostensibly failable, but the only failure case comes from
    // calling malloc, and if that fails we should just die anyway.
    errno_assert(
        (size_t)wl_array_add(&ctx->selection_data, sl_incr_chunk_size));

    // wl_array_add increments |size| as well as |alloc|, but we don't actually
    // want that yet. Instead we will set |size| later based on the results of
    // the read call.
    ctx->selection_data.size -= sl_incr_chunk_size;
  }

  int offset = ctx->selection_data.size;
  void* p = reinterpret_cast<char*>(ctx->selection_data.data) + offset;
  int bytes_left = ctx->selection_data.alloc - offset;

  int bytes = read(fd, p, bytes_left);
  if (bytes == -1) {
    LOG(ERROR) << "read error from data source: " << strerror(errno);
    sl_send_selection_notify(ctx, XCB_ATOM_NONE);
    ctx->selection_data_offer_receive_fd = -1;
    close(fd);
  } else {
    ctx->selection_data.size = offset + bytes;
    if (ctx->selection_data.size >= sl_incr_chunk_size) {
      if (!ctx->selection_incremental_transfer) {
        ctx->selection_incremental_transfer = 1;
        xcb_change_property(
            ctx->connection, XCB_PROP_MODE_REPLACE,
            ctx->selection_request.requestor, ctx->selection_request.property,
            ctx->atoms[ATOM_INCR].value, 32, 1, &sl_incr_chunk_size);
        ctx->selection_data_ack_pending = 1;
        sl_send_selection_notify(ctx, ctx->selection_request.property);
      } else if (!ctx->selection_data_ack_pending) {
        sl_send_selection_data(ctx);
      }
    } else if (bytes == 0) {
      if (!ctx->selection_data_ack_pending) {
        sl_send_selection_data(ctx);
      }
      if (!ctx->selection_incremental_transfer) {
        sl_send_selection_notify(ctx, ctx->selection_request.property);
        ctx->selection_request.requestor = XCB_NONE;
        wl_array_release(&ctx->selection_data);
      }
      xcb_flush(ctx->connection);
      ctx->selection_data_offer_receive_fd = -1;
      close(fd);
    } else {
      ctx->selection_data.size = offset + bytes;
      return 1;
    }
  }

  ctx->selection_event_source.reset();
  return 1;
}

void sl_handle_property_notify(struct sl_context* ctx,
                               xcb_property_notify_event_t* event) {
  TRACE_EVENT("x11wm", "XCB_PROPERTY_NOTIFY", [&](perfetto::EventContext p) {
    perfetto_annotate_atom(ctx, p, "event->atom", event->atom);
    perfetto_annotate_xcb_property_state(p, "event->state", event->state);
    perfetto_annotate_window(ctx, p, "event->window", event->window);
  });
  if (event->atom == XCB_ATOM_WM_NAME ||
      event->atom == ctx->atoms[ATOM_NET_WM_NAME].value) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);
    if (!window) {
      return;
    }

    bool atom_is_net_wm_name =
        event->atom == ctx->atoms[ATOM_NET_WM_NAME].value;

    // If _NET_WM_NAME is set, ignore changes to WM_NAME.
    if (!atom_is_net_wm_name && window->has_net_wm_name) {
      return;
    }

    if (window->name) {
      free(window->name);
      window->name = nullptr;
      window->has_net_wm_name = false;
    }

    xcb_atom_t atom = XCB_ATOM_NONE;
    if (event->state != XCB_PROPERTY_DELETE) {
      atom = event->atom;
    } else if (atom_is_net_wm_name) {
      // If _NET_WM_NAME is deleted, fall back to WM_NAME if it is set.
      atom = XCB_ATOM_WM_NAME;
    }

    if (atom != XCB_ATOM_NONE) {
      xcb_get_property_reply_t* reply = xcb()->get_property_reply(
          ctx->connection,
          xcb()->get_property(ctx->connection, 0, window->id, atom,
                              XCB_ATOM_ANY, 0, 2048),
          nullptr);
      if (reply) {
        window->name =
            strndup(static_cast<char*>(xcb()->get_property_value(reply)),
                    xcb()->get_property_value_length(reply));
        free(reply);

        if (atom == ctx->atoms[ATOM_NET_WM_NAME].value) {
          window->has_net_wm_name = true;
        }
      }
    }

    if (!window->xdg_toplevel) {
      return;
    }

    if (window->name) {
      xdg_toplevel_set_title(window->xdg_toplevel, window->name);
    } else {
      xdg_toplevel_set_title(window->xdg_toplevel, "");
    }
  } else if (event->atom == XCB_ATOM_WM_CLASS) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);
    if (!window || event->state == XCB_PROPERTY_DELETE) {
      return;
    }

    xcb_get_property_cookie_t cookie =
        xcb()->get_property(ctx->connection, 0, window->id, XCB_ATOM_WM_CLASS,
                            XCB_ATOM_ANY, 0, 2048);
    xcb_get_property_reply_t* reply =
        xcb()->get_property_reply(ctx->connection, cookie, nullptr);
    if (reply) {
      sl_decode_wm_class(window, reply);
      free(reply);
    }
    sl_update_application_id(ctx, window);
  } else if (event->atom == ctx->atoms[ATOM_STEAM_GAME].value) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);
    if (window) {
      xcb_get_property_cookie_t cookie = xcb()->get_property(
          ctx->connection, 0, window->id, event->atom, XCB_ATOM_CARDINAL, 0, 1);
      xcb_get_property_reply_t* reply =
          xcb()->get_property_reply(ctx->connection, cookie, nullptr);
      on_steam_game_id_updated(ctx, window, reply);
    }
  } else if (event->atom == ctx->application_id_property_atom) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);
    if (!window || event->state == XCB_PROPERTY_DELETE) {
      return;
    }

    // TODO(cpelling): Support other atom types (e.g. strings) if/when a use
    // case arises. The current use case is for cardinals (uint32) but this
    // is easy enough to extend later.
    xcb_get_property_cookie_t cookie = xcb()->get_property(
        ctx->connection, 0, window->id, ctx->application_id_property_atom,
        XCB_ATOM_CARDINAL, 0, 1);
    xcb_get_property_reply_t* reply =
        xcb()->get_property_reply(ctx->connection, cookie, nullptr);
    if (reply) {
      sl_set_application_id_from_atom(ctx, window, reply);
      sl_update_application_id(ctx, window);
      free(reply);
    }
  } else if (event->atom == XCB_ATOM_WM_NORMAL_HINTS) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);
    if (!window) {
      return;
    }

    // Don't report min/max size by default.
    window->size_flags &= ~(P_MIN_SIZE | P_MAX_SIZE);

    if (event->state != XCB_PROPERTY_DELETE) {
      struct sl_wm_size_hints size_hints = {0};
      xcb_get_property_reply_t* reply = xcb()->get_property_reply(
          ctx->connection,
          xcb()->get_property(ctx->connection, 0, window->id,
                              XCB_ATOM_WM_NORMAL_HINTS, XCB_ATOM_ANY, 0,
                              sizeof(size_hints)),
          nullptr);
      if (reply) {
        memcpy(&size_hints, xcb()->get_property_value(reply),
               sizeof(size_hints));
        free(reply);
      }
      TRACE_EVENT("x11wm", "XCB_PROPERTY_NOTIFY: XCB_ATOM_WM_NORMAL_HINTS",
                  [&](perfetto::EventContext p) {
                    perfetto_annotate_size_hints(p, size_hints);
                  });

      window->size_flags |= size_hints.flags & (P_MIN_SIZE | P_MAX_SIZE);
      if (window->size_flags & P_MIN_SIZE) {
        window->min_width = size_hints.min_width;
        window->min_height = size_hints.min_height;
        LOG(VERBOSE) << window << " min=" << window->min_width << "x"
                     << window->min_height;
      }
      if (window->size_flags & P_MAX_SIZE) {
        if (size_hints.max_width < INT_MAX) {
          window->max_width = size_hints.max_width;
        } else {
          window->max_width = 0;
        }
        if (size_hints.max_height < INT_MAX) {
          window->max_height = size_hints.max_height;
        } else {
          window->max_height = 0;
        }
        LOG(VERBOSE) << window << " max=" << window->max_width << "x"
                     << window->max_height;
      }
    }

    if (!window->xdg_toplevel) {
      return;
    }

    if (window->size_flags & P_MIN_SIZE) {
      int32_t minw = window->min_width;
      int32_t minh = window->min_height;

      sl_transform_guest_to_host(window->ctx, window->paired_surface, &minw,
                                 &minh);
      xdg_toplevel_set_min_size(window->xdg_toplevel, minw, minh);
    } else {
      xdg_toplevel_set_min_size(window->xdg_toplevel, 0, 0);
    }

    if (window->size_flags & P_MAX_SIZE) {
      int32_t maxw = window->max_width;
      int32_t maxh = window->max_height;

      sl_transform_guest_to_host(window->ctx, window->paired_surface, &maxw,
                                 &maxh);
      xdg_toplevel_set_max_size(window->xdg_toplevel, maxw, maxh);
    } else {
      xdg_toplevel_set_max_size(window->xdg_toplevel, 0, 0);
    }
  } else if (event->atom == XCB_ATOM_WM_HINTS) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);
    if (!window) {
      return;
    }

    if (event->state == XCB_PROPERTY_DELETE) {
      return;
    }
    struct sl_wm_hints wm_hints = {0};
    xcb_get_property_reply_t* reply = xcb()->get_property_reply(
        ctx->connection,
        xcb()->get_property(ctx->connection, 0, window->id, XCB_ATOM_WM_HINTS,
                            XCB_ATOM_ANY, 0, sizeof(wm_hints)),
        nullptr);

    if (!reply) {
      return;
    }
    memcpy(&wm_hints, xcb()->get_property_value(reply), sizeof(wm_hints));
    free(reply);

    if (wm_hints.flags & WM_HINTS_FLAG_URGENCY) {
      sl_request_attention(ctx, window, /*is_strong_request=*/false);
    }
  } else if (event->atom == ctx->atoms[ATOM_MOTIF_WM_HINTS].value) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);
    if (!window) {
      return;
    }

    // Managed windows are decorated by default.
    window->decorated = window->managed;

    if (event->state != XCB_PROPERTY_DELETE) {
      struct sl_mwm_hints mwm_hints = {0};
      xcb_get_property_reply_t* reply = xcb()->get_property_reply(
          ctx->connection,
          xcb()->get_property(ctx->connection, 0, window->id,
                              ctx->atoms[ATOM_MOTIF_WM_HINTS].value,
                              XCB_ATOM_ANY, 0, sizeof(mwm_hints)),
          nullptr);
      if (reply) {
        if (xcb()->get_property_value_length(reply) >=
            static_cast<int>(sizeof(mwm_hints))) {
          memcpy(&mwm_hints, xcb()->get_property_value(reply),
                 sizeof(mwm_hints));
        }
        free(reply);
        if (mwm_hints.flags & MWM_HINTS_DECORATIONS) {
          if (mwm_hints.decorations & MWM_DECOR_ALL) {
            window->decorated = ~mwm_hints.decorations & MWM_DECOR_TITLE;
          } else {
            window->decorated = mwm_hints.decorations & MWM_DECOR_TITLE;
          }
        }
      }
    }

    if (!window->aura_surface) {
      return;
    }

    zaura_surface_set_frame(window->aura_surface,
                            window->decorated ? ZAURA_SURFACE_FRAME_TYPE_NORMAL
                            : window->depth == 32
                                ? ZAURA_SURFACE_FRAME_TYPE_NONE
                                : ZAURA_SURFACE_FRAME_TYPE_SHADOW);
  } else if (event->atom == ctx->atoms[ATOM_GTK_THEME_VARIANT].value) {
    struct sl_window* window;
    uint32_t frame_color;

    window = sl_lookup_window(ctx, event->window);
    if (!window) {
      return;
    }

    window->dark_frame = 0;

    if (event->state != XCB_PROPERTY_DELETE) {
      xcb_get_property_reply_t* reply = xcb()->get_property_reply(
          ctx->connection,
          xcb()->get_property(ctx->connection, 0, window->id,
                              ctx->atoms[ATOM_GTK_THEME_VARIANT].value,
                              XCB_ATOM_ANY, 0, 2048),
          nullptr);
      if (reply) {
        if (xcb()->get_property_value_length(reply) >= 4) {
          window->dark_frame = !strcmp(
              static_cast<char*>(xcb()->get_property_value(reply)), "dark");
        }
        free(reply);
      }
    }

    if (!window->aura_surface) {
      return;
    }

    frame_color = window->dark_frame ? ctx->dark_frame_color : ctx->frame_color;
    zaura_surface_set_frame_colors(window->aura_surface, frame_color,
                                   frame_color);
  } else if (event->atom ==
             ctx->atoms[ATOM_XWAYLAND_RANDR_EMU_MONITOR_RECTS].value) {
    struct sl_window* window = sl_lookup_window(ctx, event->window);

    if (!window) {
      TRACE_EVENT("x11wm",
                  "XCB_PROPERTY_NOTIFY: _XWAYLAND_RANDR_EMU_MONITOR_RECTS",
                  [&](perfetto::EventContext p) {
                    perfetto_annotate_window(ctx, p, "window", event->window);
                  });
      return;
    }

    xcb_get_property_reply_t* reply = xcb()->get_property_reply(
        ctx->connection,
        xcb()->get_property(
            ctx->connection, 0, window->id,
            ctx->atoms[ATOM_XWAYLAND_RANDR_EMU_MONITOR_RECTS].value,
            XCB_ATOM_CARDINAL, 0, 2048),
        nullptr);

    xcb_get_property_reply_t* reply_for_trace =
        static_cast<xcb_get_property_reply_t*>(
            malloc(sizeof(xcb_get_property_reply_t)));
    memcpy(reply_for_trace, reply, sizeof(*reply));
    TRACE_EVENT("x11wm",
                "XCB_PROPERTY_NOTIFY: _XWAYLAND_RANDR_EMU_MONITOR_RECTS",
                [&](perfetto::EventContext p) {
                  perfetto_annotate_window(ctx, p, "window", event->window);
                  perfetto_annotate_cardinal_list(p, "value", reply_for_trace);
                  free(reply_for_trace);
                });

    if (!ctx->allow_xwayland_emulate_screen_pos_size) {
      return;
    }

    if (!reply || reply->value_len == 0 || reply->value_len % 4 != 0) {
      // Stop using emulated rects when:
      // - the window property is unset (ie. len == 0), we are back to native
      // - the window property length is not a multiple of 4 (property invalid)
      //   resolution
      // - we failed to get reply
      LOG(VERBOSE) << window << " _RANDR_EMU_MONITOR_RECTS unset";
      window->use_emulated_rects = false;
      free(reply);
      return;
    }

    uint32_t* xywh = static_cast<uint32_t*>(xcb()->get_property_value(reply));
    if (!xywh) {
      // The values are probably incorrectly set by XWayland, consider it as
      // buggy and do not proceed further.
      LOG(VERBOSE) << window << " _RANDR_EMU_MONITOR_RECTS invalid values";
      window->use_emulated_rects = false;
      free(reply);
      return;
    }

    // We need to select the appropriate emulated screen based on the screen the
    // window is in.
    uint32_t target_x = 0;
    uint32_t target_y = 0;
    if (!sl_window_get_output_virt_position(window, target_x, target_y)) {
      LOG(ERROR) << window
                 << " _RANDR_EMU_MONITOR_RECTS failed to find output it is in";
      window->use_emulated_rects = false;
      free(reply);
      return;
    }

    for (uint32_t i = 0; i < reply->value_len; i += 4) {
      // Assume the fullscreen window position is the screen's position.
      // XWayland emulation must match this x/y coordinates.
      if (xywh[i] == target_x && xywh[i + 1] == target_y) {
        window->emulated_x = xywh[i];
        window->emulated_y = xywh[i + 1];
        window->emulated_width = xywh[i + 2];
        window->emulated_height = xywh[i + 3];
        window->use_emulated_rects = true;
        // XWayland will send a wp_viewport.set_source and destination request
        // (plus, do other busy work such as setting pointer scaling) based on
        // window property set. Configure window manually here to trigger
        // necessary changes since some games do not do anything further than
        // adding the attributes.
        xcb()->configure_window(window->ctx->connection, window->id,
                                XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
                                    XCB_CONFIG_WINDOW_WIDTH |
                                    XCB_CONFIG_WINDOW_HEIGHT,
                                &xywh[i]);
        LOG(VERBOSE) << window << " _RANDR_EMU_MONITOR_RECTS set as "
                     << xywh[i + 2] << "x" << xywh[i + 3] << " (" << xywh[i]
                     << "," << xywh[i + 1] << ")";
        free(reply);
        return;
      }
    }

    LOG(ERROR)
        << "_RANDR_EMU_MONITOR_RECTS failed to find screen with position "
        << target_x << ", " << target_y;
    window->use_emulated_rects = false;
    free(reply);

  } else if (event->atom == ctx->atoms[ATOM_WL_SELECTION].value) {
    if (event->window == ctx->selection_window &&
        event->state == XCB_PROPERTY_NEW_VALUE &&
        ctx->selection_incremental_transfer) {
      xcb_get_property_reply_t* reply = xcb()->get_property_reply(
          ctx->connection,
          xcb()->get_property(ctx->connection, 0, ctx->selection_window,
                              ctx->atoms[ATOM_WL_SELECTION].value,
                              XCB_GET_PROPERTY_TYPE_ANY, 0, 0x1fffffff),
          nullptr);

      if (!reply) {
        return;
      }

      if (xcb()->get_property_value_length(reply) > 0) {
        sl_write_selection_property(ctx, reply);
      } else {
        assert(!ctx->selection_send_event_source);
        close(ctx->selection_data_source_send_fd);
        ctx->selection_data_source_send_fd = -1;
        free(reply);

        sl_process_data_source_send_pending_list(ctx);
      }
    }
  } else if (event->atom == ctx->selection_request.property) {
    if (event->window == ctx->selection_request.requestor &&
        event->state == XCB_PROPERTY_DELETE &&
        ctx->selection_incremental_transfer) {
      int data_size = ctx->selection_data.size;

      ctx->selection_data_ack_pending = 0;

      // Handle the case when there's more data to be received.
      if (ctx->selection_data_offer_receive_fd >= 0) {
        // Avoid sending empty data until transfer is complete.
        if (data_size) {
          sl_send_selection_data(ctx);
        }

        if (!ctx->selection_event_source) {
          ctx->selection_event_source.reset(wl_event_loop_add_fd(
              wl_display_get_event_loop(ctx->host_display),
              ctx->selection_data_offer_receive_fd, WL_EVENT_READABLE,
              sl_handle_selection_fd_readable, ctx));
        }
        return;
      }

      sl_send_selection_data(ctx);

      // Release data if transfer is complete.
      if (!data_size) {
        ctx->selection_request.requestor = XCB_NONE;
        wl_array_release(&ctx->selection_data);
      }
    }
  }
}

static void sl_internal_data_source_send(void* data,
                                         struct wl_data_source* data_source,
                                         const char* mime_type,
                                         int32_t fd) {
  TRACE_EVENT("other", "sl_internal_data_source_send");
  struct sl_data_source* host = static_cast<sl_data_source*>(data);
  struct sl_context* ctx = host->ctx;

  xcb_intern_atom_cookie_t cookie =
      xcb_intern_atom(ctx->connection, false, strlen(mime_type), mime_type);

  if (ctx->selection_data_source_send_fd < 0) {
    sl_begin_data_source_send(ctx, fd, cookie, host);
  } else {
    struct sl_data_source_send_request* request =
        static_cast<sl_data_source_send_request*>(
            malloc(sizeof(struct sl_data_source_send_request)));

    request->fd = fd;
    request->cookie = cookie;
    request->data_source = host;
    wl_list_insert(&ctx->selection_data_source_send_pending, &request->link);
  }
}

static void sl_internal_data_source_cancelled(
    void* data, struct wl_data_source* data_source) {
  TRACE_EVENT("other", "sl_internal_data_source_cancelled");
  struct sl_data_source* host = static_cast<sl_data_source*>(data);

  if (host->ctx->selection_data_source == host) {
    host->ctx->selection_data_source = nullptr;
  }

  wl_data_source_destroy(data_source);
}

static const struct wl_data_source_listener sl_internal_data_source_listener = {
    /*target=*/DoNothing, sl_internal_data_source_send,
    sl_internal_data_source_cancelled};

char* sl_copy_atom_name(xcb_get_atom_name_reply_t* reply) {
  // The string produced by xcb_get_atom_name_name isn't null terminated, so we
  // have to copy |name_len| bytes into a new buffer and add the null character
  // ourselves.
  char* name_start = xcb_get_atom_name_name(reply);
  int name_len = xcb_get_atom_name_name_length(reply);
  char* name = static_cast<char*>(malloc(name_len + 1));
  memcpy(name, name_start, name_len);
  name[name_len] = '\0';
  return name;
}

static void sl_get_selection_targets(struct sl_context* ctx) {
  TRACE_EVENT("other", "sl_get_selection_targets");
  struct sl_data_source* data_source = nullptr;
  xcb_get_property_reply_t* reply;
  xcb_atom_t* value;
  uint32_t i;

  reply = xcb_get_property_reply(
      ctx->connection,
      xcb_get_property(ctx->connection, 1, ctx->selection_window,
                       ctx->atoms[ATOM_WL_SELECTION].value,
                       XCB_GET_PROPERTY_TYPE_ANY, 0, DEFAULT_BUFFER_SIZE),
      nullptr);
  if (!reply) {
    return;
  }

  if (reply->type != XCB_ATOM_ATOM) {
    free(reply);
    return;
  }

  if (ctx->data_device_manager) {
    data_source = static_cast<sl_data_source*>(malloc(sizeof(*data_source)));
    assert(data_source);

    data_source->ctx = ctx;
    data_source->internal = wl_data_device_manager_create_data_source(
        ctx->data_device_manager->internal);
    wl_data_source_add_listener(data_source->internal,
                                &sl_internal_data_source_listener, data_source);

    value = static_cast<xcb_atom_t*>(xcb_get_property_value(reply));

    // We need to convert all of the offered target types from X11 atoms to
    // strings (i.e. getting the names of the atoms). Each conversion requires a
    // round trip to the X server, but none of the requests depend on each
    // other. Therefore, we can speed things up by sending out all the requests
    // as a batch with xcb_get_atom_name, and then read all the replies as a
    // batch with xcb_get_atom_name_reply.
    xcb_get_atom_name_cookie_t* atom_name_cookies =
        static_cast<xcb_get_atom_name_cookie_t*>(
            malloc(sizeof(xcb_get_atom_name_cookie_t) * reply->value_len));
    for (i = 0; i < reply->value_len; i++) {
      atom_name_cookies[i] = xcb_get_atom_name(ctx->connection, value[i]);
    }
    for (i = 0; i < reply->value_len; i++) {
      xcb_get_atom_name_reply_t* atom_name_reply = xcb_get_atom_name_reply(
          ctx->connection, atom_name_cookies[i], nullptr);
      if (atom_name_reply) {
        char* name = sl_copy_atom_name(atom_name_reply);
        wl_data_source_offer(data_source->internal, name);
        free(atom_name_reply);
        free(name);
      }
    }
    free(atom_name_cookies);

    if (ctx->selection_data_device && ctx->default_seat) {
      wl_data_device_set_selection(ctx->selection_data_device,
                                   data_source->internal,
                                   ctx->default_seat->seat->last_serial);
    }

    if (ctx->selection_data_source) {
      wl_data_source_destroy(ctx->selection_data_source->internal);
      free(ctx->selection_data_source);
    }
    ctx->selection_data_source = data_source;
  }

  free(reply);
}

static void sl_get_selection_data(struct sl_context* ctx) {
  TRACE_EVENT("other", "sl_get_selection_data");
  xcb_get_property_reply_t* reply = xcb_get_property_reply(
      ctx->connection,
      xcb_get_property(ctx->connection, 1, ctx->selection_window,
                       ctx->atoms[ATOM_WL_SELECTION].value,
                       XCB_GET_PROPERTY_TYPE_ANY, 0, 0x1fffffff),
      nullptr);
  if (!reply) {
    return;
  }

  if (reply->type == ctx->atoms[ATOM_INCR].value) {
    ctx->selection_incremental_transfer = 1;
    free(reply);
  } else {
    ctx->selection_incremental_transfer = 0;
    sl_write_selection_property(ctx, reply);
  }
}

static void sl_handle_selection_notify(struct sl_context* ctx,
                                       xcb_selection_notify_event_t* event) {
  if (event->property == XCB_ATOM_NONE) {
    return;
  }

  if (event->target == ctx->atoms[ATOM_TARGETS].value) {
    sl_get_selection_targets(ctx);
  } else {
    sl_get_selection_data(ctx);
  }
}

static void sl_send_targets(struct sl_context* ctx) {
  xcb_change_property(
      ctx->connection, XCB_PROP_MODE_REPLACE, ctx->selection_request.requestor,
      ctx->selection_request.property, XCB_ATOM_ATOM, 32,
      ctx->selection_data_offer->atoms.size / sizeof(xcb_atom_t),
      ctx->selection_data_offer->atoms.data);

  sl_send_selection_notify(ctx, ctx->selection_request.property);
}

static void sl_send_timestamp(struct sl_context* ctx) {
  xcb_change_property(ctx->connection, XCB_PROP_MODE_REPLACE,
                      ctx->selection_request.requestor,
                      ctx->selection_request.property, XCB_ATOM_INTEGER, 32, 1,
                      &ctx->selection_timestamp);

  sl_send_selection_notify(ctx, ctx->selection_request.property);
}

static void sl_send_data(struct sl_context* ctx, xcb_atom_t data_type) {
  TRACE_EVENT("other", "sl_send_data");
  int rv, fd_to_receive, fd_to_wayland;

  if (!ctx->selection_data_offer) {
    sl_send_selection_notify(ctx, XCB_ATOM_NONE);
    return;
  }

  if (ctx->selection_event_source) {
    LOG(ERROR) << "error: selection transfer already pending";
    sl_send_selection_notify(ctx, XCB_ATOM_NONE);
    return;
  }

  ctx->selection_data_type = data_type;

  // We will need the name of this atom later to tell the wayland server what
  // type of data to send us, so start the request now.
  xcb_get_atom_name_cookie_t atom_name_cookie =
      xcb_get_atom_name(ctx->connection, data_type);

  wl_array_init(&ctx->selection_data);
  ctx->selection_data_ack_pending = 0;

  if (ctx->channel == nullptr) {
    // Running in noop mode, without virtualization.
    int p[2];

    rv = pipe2(p, O_CLOEXEC | O_NONBLOCK);
    errno_assert(!rv);

    fd_to_receive = p[0];
    fd_to_wayland = p[1];
  } else {
    int pipe_fd;
    rv = ctx->channel->create_pipe(pipe_fd);
    if (rv) {
      LOG(ERROR) << "error: failed to create virtwl pipe: " << strerror(-rv);
      sl_send_selection_notify(ctx, XCB_ATOM_NONE);
      return;
    }

    fd_to_receive = pipe_fd;
    fd_to_wayland = pipe_fd;
  }

  xcb_get_atom_name_reply_t* atom_name_reply =
      xcb_get_atom_name_reply(ctx->connection, atom_name_cookie, nullptr);
  if (atom_name_reply) {
    // If we got the atom name, then send the request to wayland and add our end
    // of the pipe to the wayland event loop.
    ctx->selection_data_offer_receive_fd = fd_to_receive;
    char* name = sl_copy_atom_name(atom_name_reply);
    wl_data_offer_receive(ctx->selection_data_offer->internal, name,
                          fd_to_wayland);
    free(atom_name_reply);
    free(name);

    ctx->selection_event_source.reset(wl_event_loop_add_fd(
        wl_display_get_event_loop(ctx->host_display),
        ctx->selection_data_offer_receive_fd, WL_EVENT_READABLE,
        sl_handle_selection_fd_readable, ctx));
  } else {
    // If getting the atom name failed, notify the requestor that there won't be
    // any data, and close our end of the pipe.
    close(fd_to_receive);
    sl_send_selection_notify(ctx, XCB_ATOM_NONE);
  }

  // Close the wayland end of the pipe, now that it's either been sent or not
  // going to be sent. The VIRTWL driver uses the same fd for both ends of the
  // pipe, so don't close the fd if both ends are the same.
  if (fd_to_receive != fd_to_wayland) {
    close(fd_to_wayland);
  }
}

static void sl_handle_selection_request(struct sl_context* ctx,
                                        xcb_selection_request_event_t* event) {
  ctx->selection_request = *event;
  ctx->selection_incremental_transfer = 0;

  if (event->selection == ctx->atoms[ATOM_CLIPBOARD_MANAGER].value) {
    sl_send_selection_notify(ctx, ctx->selection_request.property);
    return;
  }

  if (event->target == ctx->atoms[ATOM_TARGETS].value) {
    sl_send_targets(ctx);
  } else if (event->target == ctx->atoms[ATOM_TIMESTAMP].value) {
    sl_send_timestamp(ctx);
  } else {
    int success = 0;
    xcb_atom_t* atom;
    sl_array_for_each(atom, &ctx->selection_data_offer->atoms) {
      if (event->target == *atom) {
        success = 1;
        sl_send_data(ctx, *atom);
        break;
      }
    }
    if (!success) {
      sl_send_selection_notify(ctx, XCB_ATOM_NONE);
    }
  }
}

static void sl_handle_xfixes_selection_notify(
    struct sl_context* ctx, xcb_xfixes_selection_notify_event_t* event) {
  if (event->selection != ctx->atoms[ATOM_CLIPBOARD].value) {
    return;
  }

  if (event->owner == XCB_WINDOW_NONE) {
    // If client selection is gone. Set nullptr selection for each seat.
    if (ctx->selection_owner != ctx->selection_window) {
      if (ctx->selection_data_device && ctx->default_seat) {
        wl_data_device_set_selection(ctx->selection_data_device, nullptr,
                                     ctx->default_seat->seat->last_serial);
      }
    }
    ctx->selection_owner = XCB_WINDOW_NONE;
    return;
  }

  ctx->selection_owner = event->owner;

  // Save timestamp if it's our selection.
  if (event->owner == ctx->selection_window) {
    ctx->selection_timestamp = event->timestamp;
    return;
  }

  ctx->selection_incremental_transfer = 0;
  xcb_convert_selection(ctx->connection, ctx->selection_window,
                        ctx->atoms[ATOM_CLIPBOARD].value,
                        ctx->atoms[ATOM_TARGETS].value,
                        ctx->atoms[ATOM_WL_SELECTION].value, event->timestamp);
}

static int sl_handle_x_connection_event(int fd, uint32_t mask, void* data) {
  TRACE_EVENT("other", "sl_handle_x_connection_event");
  struct sl_context* ctx = (struct sl_context*)data;
  xcb_generic_event_t* event;
  uint32_t count = 0;

  if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
    LOG(FATAL) << "got error or hangup (mask " << mask
               << ") on X connection, exiting";
    exit(EXIT_SUCCESS);
  }

  while ((event = xcb_poll_for_event(ctx->connection))) {
    switch (event->response_type & ~SEND_EVENT_MASK) {
      case XCB_CREATE_NOTIFY:
        sl_handle_create_notify(
            ctx, reinterpret_cast<xcb_create_notify_event_t*>(event));
        break;
      case XCB_DESTROY_NOTIFY:
        sl_handle_destroy_notify(
            ctx, reinterpret_cast<xcb_destroy_notify_event_t*>(event));
        break;
      case XCB_REPARENT_NOTIFY:
        sl_handle_reparent_notify(
            ctx, reinterpret_cast<xcb_reparent_notify_event_t*>(event));
        break;
      case XCB_MAP_REQUEST:
        sl_handle_map_request(
            ctx, reinterpret_cast<xcb_map_request_event_t*>(event));
        break;
      case XCB_MAP_NOTIFY:
        sl_handle_map_notify(ctx,
                             reinterpret_cast<xcb_map_notify_event_t*>(event));
        break;
      case XCB_UNMAP_NOTIFY:
        sl_handle_unmap_notify(
            ctx, reinterpret_cast<xcb_unmap_notify_event_t*>(event));
        break;
      case XCB_CONFIGURE_REQUEST:
        sl_handle_configure_request(
            ctx, reinterpret_cast<xcb_configure_request_event_t*>(event));
        break;
      case XCB_CONFIGURE_NOTIFY:
        sl_handle_configure_notify(
            ctx, reinterpret_cast<xcb_configure_notify_event_t*>(event));
        break;
      case XCB_CLIENT_MESSAGE:
        sl_handle_client_message(
            ctx, reinterpret_cast<xcb_client_message_event_t*>(event));
        break;
      case XCB_FOCUS_IN:
        sl_handle_focus_in(ctx, reinterpret_cast<xcb_focus_in_event_t*>(event));
        break;
      case XCB_FOCUS_OUT:
        sl_handle_focus_out(ctx,
                            reinterpret_cast<xcb_focus_out_event_t*>(event));
        break;
      case XCB_PROPERTY_NOTIFY:
        sl_handle_property_notify(
            ctx, reinterpret_cast<xcb_property_notify_event_t*>(event));
        break;
      case XCB_SELECTION_NOTIFY:
        sl_handle_selection_notify(
            ctx, reinterpret_cast<xcb_selection_notify_event_t*>(event));
        break;
      case XCB_SELECTION_REQUEST:
        sl_handle_selection_request(
            ctx, reinterpret_cast<xcb_selection_request_event_t*>(event));
        break;
    }

    switch (event->response_type - ctx->xfixes_extension->first_event) {
      case XCB_XFIXES_SELECTION_NOTIFY:
        sl_handle_xfixes_selection_notify(
            ctx, reinterpret_cast<xcb_xfixes_selection_notify_event_t*>(event));
        break;
    }

    // Xshape specific events extend the normal event numbers
    // The first event id is retrieved when querying for xshape
    // extension information. This can be used to determine
    // if the event that is received is Xshape specific.
    if (ctx->enable_xshape) {
      uint8_t xshape_event_id =
          event->response_type - ctx->xshape_extension->first_event;
      switch (xshape_event_id) {
        case XCB_SHAPE_NOTIFY:
          sl_handle_shape_notify(
              ctx, reinterpret_cast<xcb_shape_notify_event_t*>(event));
          break;
      }
    }

    free(event);
    ++count;
  }

  if ((mask & ~WL_EVENT_WRITABLE) == 0) {
    xcb_flush(ctx->connection);
  }

  return count;
}

static void sl_set_supported(struct sl_context* ctx) {
  const xcb_atom_t supported_atoms[] = {
      ctx->atoms[ATOM_NET_ACTIVE_WINDOW].value,
      ctx->atoms[ATOM_NET_WM_MOVERESIZE].value,
      ctx->atoms[ATOM_NET_WM_NAME].value,
      ctx->atoms[ATOM_NET_WM_STATE].value,
      ctx->atoms[ATOM_NET_WM_STATE_FULLSCREEN].value,
      ctx->atoms[ATOM_NET_WM_STATE_MAXIMIZED_VERT].value,
      ctx->atoms[ATOM_NET_WM_STATE_MAXIMIZED_HORZ].value,
      ctx->atoms[ATOM_NET_WM_STATE_FOCUSED].value,
      // TODO(hollingum): STATE_MODAL and CLIENT_LIST, based on what wlroots
      // has.
  };

  xcb_change_property(ctx->connection, XCB_PROP_MODE_REPLACE, ctx->screen->root,
                      ctx->atoms[ATOM_NET_SUPPORTED].value, XCB_ATOM_ATOM, 32,
                      sizeof(supported_atoms) / sizeof(xcb_atom_t),
                      supported_atoms);
}

// The window manager is responsible for setting the default cursor on the root
// window, which will be used by applications that do not try to set their own
// cursor. If we do not do this, the cursor will be invisible, see b/204724669
// for details.
static void sl_initialize_cursor(struct sl_context* ctx) {
  [[maybe_unused]] xcb_generic_error_t* err;
  xcb_void_cookie_t cookie;

  // Load the "cursor" font, which is a built-in set of fonts, documented at
  // https://tronche.com/gui/x/xlib/appendix/b/.
  xcb_font_t font_id = xcb_generate_id(ctx->connection);
  cookie = xcb_open_font_checked(ctx->connection, font_id, strlen("cursor"),
                                 "cursor");
  err = xcb_request_check(ctx->connection, cookie);
  assert(!err);

  // Create the standard "left ptr" cursor. The below call is a bit technical,
  // but it means:
  //  - font_id appears twice because we use a mask (background) whose font is
  //    the same as the source.
  //  - the mask is the source + 1, because the inbuilt cursor font has
  //    even-numbered foreground glyphs and odd-numbered backgrounds.
  //  - The numbers are 16-bit RGB for the foreground and background, so this
  //    has a black foreground and a white background.
  constexpr int left_ptr_cursor_id = 68;
  xcb_cursor_t cursor_id = xcb_generate_id(ctx->connection);
  cookie = xcb_create_glyph_cursor_checked(
      ctx->connection, cursor_id, font_id, font_id, left_ptr_cursor_id,
      left_ptr_cursor_id + 1, 0, 0, 0, 65535, 65535, 65535);
  err = xcb_request_check(ctx->connection, cookie);
  assert(!err);

  // Set the cursor for the root window.
  cookie = xcb_change_window_attributes_checked(
      ctx->connection, ctx->screen->root, XCB_CW_CURSOR, &cursor_id);
  err = xcb_request_check(ctx->connection, cookie);
  assert(!err);

  // Free the cursor and the fonts, since we no-longer need them.
  xcb_free_cursor(ctx->connection, cursor_id);
  cookie = xcb_close_font_checked(ctx->connection, font_id);
  err = xcb_request_check(ctx->connection, cookie);
  assert(!err);
}

static void sl_connect(struct sl_context* ctx) {
  TRACE_EVENT("other", "sl_connect");
  const char wm_name[] = "Sommelier";
  const xcb_setup_t* setup;
  xcb_screen_iterator_t screen_iterator;
  uint32_t values[1];
  xcb_void_cookie_t change_attributes_cookie, redirect_subwindows_cookie;
  xcb_generic_error_t* error;
  xcb_intern_atom_reply_t* atom_reply;
  xcb_depth_iterator_t depth_iterator;
  xcb_xfixes_query_version_reply_t* xfixes_query_version_reply;
  xcb_shape_query_version_reply_t* xshape_query_version_reply;
  const xcb_query_extension_reply_t* composite_extension;
  unsigned i;

  set_xcb_shim(new XcbShim());

  ctx->connection = xcb_connect_to_fd(ctx->wm_fd, nullptr);
  assert(!xcb_connection_has_error(ctx->connection));

  xcb_prefetch_extension_data(ctx->connection, &xcb_xfixes_id);
  xcb_prefetch_extension_data(ctx->connection, &xcb_composite_id);

  // Send requests to fetch/create ("intern") all the atoms we'll need later.
  for (i = 0; i < ARRAY_SIZE(ctx->atoms); ++i) {
    const char* name = ctx->atoms[i].name;
    ctx->atoms[i].cookie =
        xcb_intern_atom(ctx->connection, 0, strlen(name), name);
  }
  xcb_intern_atom_cookie_t app_id_atom_cookie;
  if (ctx->application_id_property_name) {
    app_id_atom_cookie = xcb_intern_atom(
        ctx->connection, 0, strlen(ctx->application_id_property_name),
        ctx->application_id_property_name);
  }

  setup = xcb_get_setup(ctx->connection);
  screen_iterator = xcb_setup_roots_iterator(setup);
  ctx->screen = screen_iterator.data;

  // Select for substructure redirect.
  values[0] = XCB_EVENT_MASK_STRUCTURE_NOTIFY |
              XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
              XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
  change_attributes_cookie = xcb_change_window_attributes(
      ctx->connection, ctx->screen->root, XCB_CW_EVENT_MASK, values);

  ctx->connection_event_source.reset(wl_event_loop_add_fd(
      wl_display_get_event_loop(ctx->host_display),
      xcb_get_file_descriptor(ctx->connection), WL_EVENT_READABLE,
      &sl_handle_x_connection_event, ctx));

  ctx->xfixes_extension =
      xcb_get_extension_data(ctx->connection, &xcb_xfixes_id);
  assert(ctx->xfixes_extension->present);

  xfixes_query_version_reply = xcb_xfixes_query_version_reply(
      ctx->connection,
      xcb_xfixes_query_version(ctx->connection, XCB_XFIXES_MAJOR_VERSION,
                               XCB_XFIXES_MINOR_VERSION),
      nullptr);
  assert(xfixes_query_version_reply);
  assert(xfixes_query_version_reply->major_version >= 5);
  free(xfixes_query_version_reply);

  composite_extension =
      xcb_get_extension_data(ctx->connection, &xcb_composite_id);
  assert(composite_extension->present);
  UNUSED(composite_extension);

  if (ctx->enable_xshape) {
    xcb_prefetch_extension_data(ctx->connection, &xcb_shape_id);

    ctx->xshape_extension =
        xcb_get_extension_data(ctx->connection, &xcb_shape_id);

    xshape_query_version_reply = xcb_shape_query_version_reply(
        ctx->connection, xcb_shape_query_version(ctx->connection), nullptr);

    assert(xshape_query_version_reply);
    assert(xshape_query_version_reply->major_version >=
           XCB_SHAPE_MAJOR_VERSION);
    assert(xshape_query_version_reply->minor_version >=
           XCB_SHAPE_MINOR_VERSION);
    free(xshape_query_version_reply);
    xshape_query_version_reply = nullptr;
  }

  redirect_subwindows_cookie = xcb_composite_redirect_subwindows_checked(
      ctx->connection, ctx->screen->root, XCB_COMPOSITE_REDIRECT_MANUAL);

  // Another window manager should not be running.
  error = xcb_request_check(ctx->connection, change_attributes_cookie);
  assert(!error);

  // Redirecting subwindows of root for compositing should have succeeded.
  error = xcb_request_check(ctx->connection, redirect_subwindows_cookie);
  assert(!error);

  ctx->window = xcb_generate_id(ctx->connection);
  xcb_create_window(ctx->connection, 0, ctx->window, ctx->screen->root, 0, 0, 1,
                    1, 0, XCB_WINDOW_CLASS_INPUT_ONLY, XCB_COPY_FROM_PARENT, 0,
                    nullptr);

  // Wait on results for all the atom intern requests we sent above.
  for (i = 0; i < ARRAY_SIZE(ctx->atoms); ++i) {
    atom_reply =
        xcb_intern_atom_reply(ctx->connection, ctx->atoms[i].cookie, &error);
    assert(!error);
    ctx->atoms[i].value = atom_reply->atom;
    free(atom_reply);
  }
  if (ctx->application_id_property_name) {
    atom_reply =
        xcb_intern_atom_reply(ctx->connection, app_id_atom_cookie, &error);
    assert(!error);
    ctx->application_id_property_atom = atom_reply->atom;
    free(atom_reply);
  }

  depth_iterator = xcb_screen_allowed_depths_iterator(ctx->screen);
  while (depth_iterator.rem > 0) {
    int depth = depth_iterator.data->depth;
    if (depth == ctx->screen->root_depth) {
      ctx->visual_ids[depth] = ctx->screen->root_visual;
      ctx->colormaps[depth] = ctx->screen->default_colormap;
    } else {
      xcb_visualtype_iterator_t visualtype_iterator =
          xcb_depth_visuals_iterator(depth_iterator.data);

      ctx->visual_ids[depth] = visualtype_iterator.data->visual_id;
      ctx->colormaps[depth] = xcb_generate_id(ctx->connection);
      xcb_create_colormap(ctx->connection, XCB_COLORMAP_ALLOC_NONE,
                          ctx->colormaps[depth], ctx->screen->root,
                          ctx->visual_ids[depth]);
    }
    xcb_depth_next(&depth_iterator);
  }
  assert(ctx->visual_ids[ctx->screen->root_depth]);

  if (ctx->clipboard_manager) {
    values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE;
    ctx->selection_window = xcb_generate_id(ctx->connection);
    xcb_create_window(ctx->connection, XCB_COPY_FROM_PARENT,
                      ctx->selection_window, ctx->screen->root, 0, 0, 1, 1, 0,
                      XCB_WINDOW_CLASS_INPUT_OUTPUT, ctx->screen->root_visual,
                      XCB_CW_EVENT_MASK, values);
    xcb_set_selection_owner(ctx->connection, ctx->selection_window,
                            ctx->atoms[ATOM_CLIPBOARD_MANAGER].value,
                            XCB_CURRENT_TIME);
    xcb_xfixes_select_selection_input(
        ctx->connection, ctx->selection_window,
        ctx->atoms[ATOM_CLIPBOARD].value,
        XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
            XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
            XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE);
    sl_set_selection(ctx, nullptr);
  }

  xcb_change_property(ctx->connection, XCB_PROP_MODE_REPLACE, ctx->window,
                      ctx->atoms[ATOM_NET_SUPPORTING_WM_CHECK].value,
                      XCB_ATOM_WINDOW, 32, 1, &ctx->window);
  xcb_change_property(ctx->connection, XCB_PROP_MODE_REPLACE, ctx->window,
                      ctx->atoms[ATOM_NET_WM_NAME].value,
                      ctx->atoms[ATOM_UTF8_STRING].value, 8, strlen(wm_name),
                      wm_name);
  xcb_change_property(ctx->connection, XCB_PROP_MODE_REPLACE, ctx->screen->root,
                      ctx->atoms[ATOM_NET_SUPPORTING_WM_CHECK].value,
                      XCB_ATOM_WINDOW, 32, 1, &ctx->window);
  sl_set_supported(ctx);
  xcb_set_selection_owner(ctx->connection, ctx->window,
                          ctx->atoms[ATOM_WM_S0].value, XCB_CURRENT_TIME);

  xcb_set_input_focus(ctx->connection, XCB_INPUT_FOCUS_NONE, XCB_NONE,
                      XCB_CURRENT_TIME);
  xcb_flush(ctx->connection);

  sl_initialize_cursor(ctx);
}

static void sl_sd_notify(const char* state) {
  const char* socket_name;
  struct msghdr msghdr;
  struct iovec iovec;
  struct sockaddr_un addr;
  int fd;
  int rv;

  socket_name = getenv("NOTIFY_SOCKET");
  assert(socket_name);

  fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
  errno_assert(fd >= 0);

  memset(&addr, 0, sizeof(addr));
  addr.sun_family = AF_UNIX;
  strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path));
  // ensure path is null-terminated
  addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';

  memset(&iovec, 0, sizeof(iovec));
  // iovec is just going to be used to send data as part of a const msghdr.
  iovec.iov_base = const_cast<char*>(state);
  iovec.iov_len = strlen(state);

  memset(&msghdr, 0, sizeof(msghdr));
  msghdr.msg_name = &addr;
  msghdr.msg_namelen =
      offsetof(struct sockaddr_un, sun_path) + strlen(socket_name);
  msghdr.msg_iov = &iovec;
  msghdr.msg_iovlen = 1;

  rv = sendmsg(fd, &msghdr, MSG_NOSIGNAL);
  errno_assert(rv != -1);
}

static int sl_handle_sigchld(int signal_number, void* data) {
  struct sl_context* ctx = (struct sl_context*)data;
  int status;
  pid_t pid;

  while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
    if (pid == ctx->child_pid) {
      ctx->child_pid = -1;
      if (WIFEXITED(status) && WEXITSTATUS(status)) {
        LOG(ERROR) << "child exited with status: " << WEXITSTATUS(status);
      }
      if (ctx->exit_with_child) {
        if (ctx->xwayland_pid >= 0) {
          kill(ctx->xwayland_pid, SIGTERM);
        }
      } else {
        // Notify systemd that we are ready to accept connections now that
        // child process has finished running and all environment is ready.
        if (ctx->sd_notify) {
          sl_sd_notify(ctx->sd_notify);
        }
      }
    } else if (pid == ctx->xwayland_pid) {
      ctx->xwayland_pid = -1;
      if (WIFEXITED(status) && WEXITSTATUS(status)) {
        LOG(FATAL) << "Xwayland exited with status: " << WEXITSTATUS(status);
        exit(WEXITSTATUS(status));
      }
    }
  }

  return 1;
}

static int sl_handle_sigusr1(int signal_number, void* data) {
  struct sl_context* ctx = (struct sl_context*)data;
  LOG(INFO) << "dumping trace " << ctx->trace_filename;
  dump_trace(ctx->trace_filename);
  if (ctx->timing != nullptr) {
    ctx->timing->OutputLog();
  }
  return 1;
}

static int sl_handle_stats_timer(void* data) {
  struct sl_context* ctx = (struct sl_context*)data;
  if (ctx->frame_stats != nullptr) {
    ctx->frame_stats->OutputStats();
  }
  wl_event_source_timer_update(ctx->stats_timer_event_source.get(),
                               ctx->stats_timer_delay);
  return 1;
}

static void sl_execvp(const char* file,
                      char* const argv[],
                      int wayland_socked_fd) {
  if (wayland_socked_fd >= 0) {
    int fd;
    fd = dup(wayland_socked_fd);
    putenv(sl_xasprintf("WAYLAND_SOCKET=%d", fd));
  }

  setenv("SOMMELIER_VERSION", SOMMELIER_VERSION, 1);

  execvp(file, argv);
  perror(file);
}

static void sl_calculate_scale_for_xwayland(struct sl_context* ctx) {
  double default_scale_factor = 1.0;
  double scale = ctx->desired_scale;

  if (!ctx->use_direct_scale) {
    // Find internal output and determine preferred scale factor.
    for (auto output : ctx->host_outputs) {
      if (output->internal) {
        double preferred_scale =
            sl_output_aura_scale_factor_to_double(output->preferred_scale);

        if (ctx->aura_shell) {
          double device_scale_factor = sl_output_aura_scale_factor_to_double(
              output->device_scale_factor);

          default_scale_factor = device_scale_factor * preferred_scale;
        }
        break;
      }
    }
    // We use the default scale factor multiplied by desired scale set by the
    // user. This gives us HiDPI support by default but the user can still
    // adjust it if higher or lower density is preferred.
    scale = ctx->desired_scale * default_scale_factor;

    // Round to integer scale if wp_viewporter interface is not present.
    if (!ctx->viewporter) {
      scale = round(scale);
    }
  }

  // Clamp and set scale.
  ctx->scale = MIN(MAX_SCALE, MAX(MIN_SCALE, scale));

  // Scale affects output state. Send updated output state to xwayland.
  for (auto output : ctx->host_outputs) {
    sl_output_calculate_virtual_dimensions(output);
  }
  sl_output_update_output_x(ctx);
  for (auto output : ctx->host_outputs) {
    sl_output_send_host_output_state(output);
  }
}

// Extra connections are made to XWayland-hosting instances for IME support.
static void sl_extra_client_created_notify(struct wl_listener* listener,
                                           void* data) {
  sl_context* ctx =
      wl_container_of(listener, ctx, extra_client_created_listener);
  wl_client* client = static_cast<wl_client*>(data);

  sl_set_display_implementation(ctx, client);
}

static int sl_handle_display_ready_event(int fd, uint32_t mask, void* data) {
  TRACE_EVENT("surface", "sl_handle_display_ready_event");
  struct sl_context* ctx = (struct sl_context*)data;
  char display_name[9];
  int bytes_read = 0;
  pid_t pid;

  if (!(mask & WL_EVENT_READABLE)) {
    LOG(FATAL) << "Got error or hangup on display ready connection (mask"
               << mask << "), exiting";
    exit(EXIT_FAILURE);
  }

  display_name[0] = ':';
  do {
    int bytes_left = sizeof(display_name) - bytes_read - 1;
    int bytes;

    if (!bytes_left) {
      break;
    }

    bytes = read(fd, &display_name[bytes_read + 1], bytes_left);
    if (!bytes) {
      break;
    }

    bytes_read += bytes;
  } while (display_name[bytes_read] != '\n');

  display_name[bytes_read] = '\0';
  setenv("DISPLAY", display_name, 1);

  sl_connect(ctx);

  ctx->display_ready_event_source.reset();
  close(fd);

  // Calculate scale now that the default scale factor is known. This also
  // happens to workaround an issue in Xwayland where an output update is
  // needed for DPI to be set correctly.
  sl_calculate_scale_for_xwayland(ctx);
  wl_display_flush_clients(ctx->host_display);

  // Open wayland socket so cros_im can provide IME support to X11 apps.
  // This depends on the display number, which is only available once Xwayland
  // initialization is complete (now), so we can't create this earlier to use
  // it for the wayland connection with Xwayland.
  char* socket_name = sl_xasprintf("DISPLAY-%s-wl", display_name);
  struct sockaddr_un addr;
  int lock_fd;
  int sock_fd;
  int rv = sl_open_wayland_socket(socket_name, &addr, &lock_fd, &sock_fd);
  if (rv >= 0) {
    wl_display_add_socket_fd(ctx->host_display, sock_fd);
    ctx->extra_client_created_listener.notify = sl_extra_client_created_notify;
    wl_display_add_client_created_listener(ctx->host_display,
                                           &ctx->extra_client_created_listener);
  } else {
    LOG(WARNING) << "unable to open wayland socket for cros_im";
  }
  free(socket_name);

  putenv(sl_xasprintf("XCURSOR_SIZE=%d",
                      static_cast<int>(XCURSOR_SIZE_BASE * ctx->scale + 0.5)));

  pid = fork();
  errno_assert(pid >= 0);
  if (pid == 0) {
    // Set WAYLAND_DISPLAY to a value that is guaranteed to not point to a
    // valid wayland compositor socket name. Unsetting WAYLAND_DISPLAY is
    // insufficient as some clients may attempt to connect to wayland-0 as a
    // default fallback.
    setenv("WAYLAND_DISPLAY", ".", 1);
    sl_execvp(ctx->runprog[0], ctx->runprog, -1);
    _exit(EXIT_FAILURE);
  }

  ctx->child_pid = pid;

  return 1;
}

static void sl_sigchld_handler(int signal) {
  while (waitpid(-1, nullptr, WNOHANG) > 0) {
    continue;
  }
}

static void sl_client_destroy_notify(struct wl_listener* listener, void* data) {
  exit(0);
}

// Break |str| into a sequence of zero or more nonempty arguments. No more
// than |argc| arguments will be added to |argv|. Returns the total number of
// argments found in |str|.
static int sl_parse_cmd_prefix(char* str, int argc, char const** argv) {
  char* s = str;
  int n = 0;
  int delim = 0;

  do {
    // Look for ending delimiter if |delim| is set.
    if (delim) {
      if (*s == delim) {
        delim = 0;
        *s = '\0';
      }
      ++s;
    } else {
      // Skip forward to first non-space character.
      while (*s == ' ' && *s != '\0') {
        ++s;
      }

      // Check for quote delimiter.
      if (*s == '"') {
        delim = '"';
        ++s;
      } else {
        delim = ' ';
      }

      // Add string to arguments if there's room.
      if (n < argc) {
        argv[n] = s;
      }

      ++n;
    }
  } while (*s != '\0');

  return n;
}

static void sl_print_usage() {
  printf(
      "usage: sommelier [options] [program] [args...]\n\n"
      "options:\n"
      "  -h, --help\t\t\tPrint this help\n"
      "  -X\t\t\t\tEnable X11 forwarding\n"
      "  --log-level=LEVEL\t\tSet minimum log level to be processed\n"
      "\t(allowed range: -1 to 3; lower is more verbose))\n"
      "  --parent\t\t\tRun as parent and spawn child processes\n"
      "  --socket=SOCKET\t\tName of socket to listen on\n"
      "  --display=DISPLAY\t\tWayland display to connect to\n"
      "  --scale=SCALE\t\t\tScale factor for contents\n"
      "  --dpi=[DPI[,DPI...]]\t\tDPI buckets\n"
      "  --peer-cmd-prefix=PREFIX\tPeer process command line prefix\n"
      "  --accelerators=ACCELERATORS\tList of keyboard accelerators\n"
      "  --windowed_accelerators=ACCELERATORS\tList of keyboard accelerators\n"
      "\tonly while windowed\n"
      "  --application-id=ID\t\tForced application ID for all X11 windows\n"
      "  --vm-identifier=NAME\t\tName of the VM, used to identify X11 "
      "windows.\n"
      "\t\t\t\tIgnored if --application-id is set.\n"
      "  --application-id-x11-property=PROPERTY\n"
      "\tA cardinal window property used to identify X11 windows, as follows:\n"
      "\t  org.chromium.<vm-identifier>.xprop.<application-id-x11-property>\n"
      "\tIgnored if --application-id is set.\n"
      "  --x-display=DISPLAY\t\tX11 display to listen on\n"
      "  --xwayland-path=PATH\t\tPath to Xwayland executable\n"
      "  --xwayland-gl-driver-path=PATH\tPath to GL drivers for Xwayland\n"
      "  --xwayland-cmd-prefix=PREFIX\tXwayland command line prefix\n"
      "  --enable-linux-dmabuf\t\tEnable client-facing zwp_linux_dmabuf_v1 "
      "extension support\n"
      "  --enable-xshape\t\tEnable X11 XShape extension support\n"
      "  --enable-x11-move-windows\t\tLet X11 apps control window position,\n"
      "\tif the host compositor supports the aura_shell protocol.\n"
      "  --no-exit-with-child\t\tKeep process alive after child exists\n"
      "  --no-clipboard-manager\tDisable X11 clipboard manager\n"
      "  --frame-color=COLOR\t\tWindow frame color for X11 clients\n"
      "  --no-support-damage-buffer\t"
      "Disable wl_surface::damage_buffer support.\n"
      "  --force-drm-device=DEVICE\tDRM device to use\n"
      "  --glamor\t\t\tUse glamor to accelerate X11 clients\n"
      "  --timing-filename=PATH\tPath to timing output log\n"
      "  --direct-scale\t\tEnable direct scaling mode\n"
      "  --viewport-resize\t\tUse viewport to resize unresizable windows.\n"
#ifdef PERFETTO_TRACING
      "  --trace-filename=PATH\t\tPath to Perfetto trace filename\n"
      "  --trace-system\t\tPerfetto trace to system daemon\n"
#endif
#ifdef QUIRKS_SUPPORT
      "  --quirks-config=PATH[,PATH...]\tOne or more 'quirks' config files.\n"
      "  --print-enabled-features=STEAM_GAME_ID\tPrint features enabled via "
      "quirks for the game specified, then exit.\n"
#endif
      "  --stats-summary=PATH\t\tPath for recent frame timing stats "
      "(rewrites)\n"
      "  --stats-log=PATH\t\t\tPath to log/append frame timing stats "
      "(appends)\n"
      "\tThe two previous arguments log the same data for different usages.\n"
      "\tThe summary is the most recent entries for the metrics collector,\n"
      "\twhile the log will grow infinitely and is intended for debugging\n"
      "\tor development purposes.\n"
      "  --stats-timer=SECS\t\tNumber of seconds between stats dumps\n"
      "  --fullscreen-mode=MODE\tDefault fullscreen behavior (immersive,"
      " plain)\n"
      "  --virtgpu-channel\t\tUse virtgpu cross-domain context as virtual"
      " wayland channel\n"
      "  --noop-driver\t\t\tPass through to existing Wayland server"
      " without virtualization\n");
}

static const char* sl_arg_value(const char* arg) {
  assert(arg != nullptr);

  const char* s = strchr(arg, '=');
  if (!s) {
    sl_print_usage();
    printf("\n");
    LOG(FATAL) << "failed to extract value from arg '" << arg
               << "'. expected form is " << arg << "=value";
    exit(EXIT_FAILURE);
  }
  return s + 1;
}

// attempts to both split "--argname=argval" and parse "argval" signed integer,
// or exits the program with a fatal error if detecting any non-integer
// characters or is out-of-bounds.
static int64_t sl_arg_parse_int_checked(const char* arg) {
  assert(arg != nullptr);
  const char* argval = sl_arg_value(arg);

  // Use strtoll() because atoi() fails with UB, not error signaling.
  // Note, that both parse and out-of-range failures are detected here,
  // unlike atoi() (which implicitly succeeds with return value 0);
  //
  // e.g. atoi() parses "blah8" as '0' and "8blah" as '8', while this procedure
  // detects invalid input in both cases and signals a fatality.
  char* str_end;
  int64_t res = strtoll(argval, &str_end, 10);

  const bool has_non_numerical = (str_end == argval || *str_end != '\0');
  const bool out_of_bounds =
      (res == LLONG_MAX || res == LLONG_MIN) && errno == ERANGE;
  if (has_non_numerical || out_of_bounds) {
    LOG(FATAL) << "failed to convert string '" << argval
               << "' to int while parsing argument '" << arg << "'";
    exit(EXIT_FAILURE);
  }
  return res;
}

// Parse the list of accelerators that should be reserved by the
// compositor. Format is "|MODIFIERS|KEYSYM", where MODIFIERS is a
// list of modifier names (E.g. <Control><Alt>) and KEYSYM is an
// XKB key symbol name (E.g Delete).
// Sommelier will exit with EXIT_FAILURE if this returns false.
// TODO(b/237946069) Confirm accelerator handling works with i18n.
static bool sl_parse_accelerators(
    std::vector<struct sl_accelerator*>& accelerator_list,
    const char* accelerators) {
  if (accelerators) {
    uint32_t modifiers = 0;

    while (*accelerators) {
      if (*accelerators == ',') {
        accelerators++;
      } else if (*accelerators == '<') {
        if (strncmp(accelerators, "<Control>", 9) == 0) {
          modifiers |= CONTROL_MASK;
          accelerators += 9;
        } else if (strncmp(accelerators, "<Alt>", 5) == 0) {
          modifiers |= ALT_MASK;
          accelerators += 5;
        } else if (strncmp(accelerators, "<Shift>", 7) == 0) {
          modifiers |= SHIFT_MASK;
          accelerators += 7;
        } else {
          LOG(ERROR) << "invalid modifier";
          return false;
        }
      } else {
        const char* end = strchrnul(accelerators, ',');
        char* name = strndup(accelerators, end - accelerators);

        struct sl_accelerator* accelerator =
            static_cast<sl_accelerator*>(malloc(sizeof(*accelerator)));
        accelerator->modifiers = modifiers;
        accelerator->symbol =
            xkb_keysym_from_name(name, XKB_KEYSYM_CASE_INSENSITIVE);
        if (accelerator->symbol == XKB_KEY_NoSymbol) {
          LOG(ERROR) << "invalid key symbol";
          return false;
        }

        accelerator_list.push_back(accelerator);

        modifiers = 0;
        accelerators = end;
        free(name);
      }
    }
  }
  return true;
}

// Takes the lock and then opens the socket for wayland clients to connect to.
// Returns a negative value on error. |addr|, |lock_fd| and |sock_fd| will be
// populated on success.
int sl_open_wayland_socket(const char* socket_name,
                           struct sockaddr_un* addr,
                           int* lock_fd,
                           int* sock_fd) {
  int rv;

  const char* runtime_dir = getenv("XDG_RUNTIME_DIR");
  if (!runtime_dir) {
    LOG(ERROR) << "XDG_RUNTIME_DIR not set in the environment";
    return -1;
  }

  addr->sun_family = AF_LOCAL;
  snprintf(addr->sun_path, sizeof(addr->sun_path), "%s/%s", runtime_dir,
           socket_name);

  char* lock_addr = sl_xasprintf("%s%s", addr->sun_path, LOCK_SUFFIX);

  *lock_fd = open(lock_addr, O_CREAT | O_CLOEXEC,
                  (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
  errno_assert(*lock_fd >= 0);

  rv = flock(*lock_fd, LOCK_EX | LOCK_NB);
  if (rv < 0) {
    LOG(ERROR) << "error: unable to lock " << lock_addr
               << ", is another compositor running?";
    return rv;
  }
  free(lock_addr);

  struct stat sock_stat;
  rv = stat(addr->sun_path, &sock_stat);
  if (rv >= 0) {
    if (sock_stat.st_mode & (S_IWUSR | S_IWGRP)) {
      unlink(addr->sun_path);
    }
  } else {
    errno_assert(errno == ENOENT);
  }

  *sock_fd = socket(PF_LOCAL, SOCK_STREAM, 0);
  errno_assert(*sock_fd >= 0);

  rv = bind(*sock_fd, (struct sockaddr*)addr, sizeof(*addr));
  errno_assert(rv >= 0);

  rv = listen(*sock_fd, 128);
  errno_assert(rv >= 0);

  return 0;
}

int sl_run_parent(int argc,
                  char** argv,
                  sl_context* ctx,
                  const char* socket_name,
                  const char* peer_cmd_prefix) {
  struct sockaddr_un addr;
  int lock_fd;
  int sock_fd;
  int rv;

  rv = sl_open_wayland_socket(socket_name, &addr, &lock_fd, &sock_fd);
  if (rv < 0) {
    return EXIT_FAILURE;
  }

  // Spawn optional child process before we notify systemd that we're ready
  // to accept connections. WAYLAND_DISPLAY will be set but any attempt to
  // connect to this socket at this time will fail.
  if (ctx->runprog && ctx->runprog[0]) {
    int pid = fork();
    errno_assert(pid != -1);
    if (pid == 0) {
      setenv("WAYLAND_DISPLAY", socket_name, 1);
      sl_execvp(ctx->runprog[0], ctx->runprog, -1);
      _exit(EXIT_FAILURE);
    }
    while (waitpid(-1, nullptr, WNOHANG) != pid) {
      continue;
    }
  }

  if (ctx->sd_notify) {
    sl_sd_notify(ctx->sd_notify);
  }

  struct sigaction sa;
  sa.sa_handler = sl_sigchld_handler;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = SA_RESTART;
  rv = sigaction(SIGCHLD, &sa, nullptr);
  errno_assert(rv >= 0);

  while (true) {
    struct ucred ucred;
    socklen_t length = sizeof(addr);

    int client_fd = accept(sock_fd, (struct sockaddr*)&addr, &length);
    if (client_fd < 0) {
      LOG(ERROR) << "failed to accept: " << strerror(errno);
      continue;
    }

    ucred.pid = -1;
    length = sizeof(ucred);
    rv = getsockopt(client_fd, SOL_SOCKET, SO_PEERCRED, &ucred, &length);

    int pid = fork();
    errno_assert(pid != -1);
    if (pid == 0) {
      char* client_fd_str;
      char* peer_pid_str;
      char* peer_cmd_prefix_str;
      char const* args[64];
      int i = 0;

      close(sock_fd);
      close(lock_fd);

      if (peer_cmd_prefix) {
        peer_cmd_prefix_str = sl_xasprintf("%s", peer_cmd_prefix);

        i = sl_parse_cmd_prefix(peer_cmd_prefix_str, 32, args);
        if (i > 32) {
          LOG(ERROR) << "too many arguments in cmd prefix: " << i;
          i = 0;
        }
      }

      args[i++] = argv[0];
      peer_pid_str = sl_xasprintf("--peer-pid=%d", ucred.pid);
      args[i++] = peer_pid_str;
      client_fd_str = sl_xasprintf("--client-fd=%d", client_fd);
      args[i++] = client_fd_str;

      // forward some flags.
      for (int j = 1; j < argc; ++j) {
        char* arg = argv[j];
        if (strstr(arg, "--display") == arg || strstr(arg, "--scale") == arg ||
            strstr(arg, "--direct-scale") == arg ||
            strstr(arg, "--accelerators") == arg ||
            strstr(arg, "--windowed-accelerators") == arg ||
            strstr(arg, "--drm-device") == arg ||
            strstr(arg, "--support-damage-buffer") == arg ||
            strstr(arg, "--vm-identififer") == arg ||
            strstr(arg, "--trace-system") == arg ||
            strstr(arg, "--virtgpu-channel") == arg ||
            strstr(arg, "--enable-linux-dmabuf") == arg) {
          args[i++] = arg;
        }
      }

      args[i++] = nullptr;

      execvp(args[0], const_cast<char* const*>(args));
      _exit(EXIT_FAILURE);
    }
    close(client_fd);
  }

  // Control should never reach here.
  assert(false);
}

void sl_spawn_xwayland(sl_context* ctx,
                       wl_event_loop* event_loop,
                       int wayland_socket_fd,
                       const char* xwayland_cmd_prefix,
                       const char* xwayland_path,
                       int xdisplay,
                       const char* xauth_path,
                       const char* xfont_path,
                       const char* xwayland_gl_driver_path,
                       const char* glamor) {
  int ds[2];
  int rv;
  // Xwayland display ready socket.
  rv = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ds);
  errno_assert(!rv);

  ctx->display_ready_event_source.reset(
      wl_event_loop_add_fd(event_loop, ds[0], WL_EVENT_READABLE,
                           sl_handle_display_ready_event, ctx));

  int wm[2];
  // X connection to Xwayland.
  rv = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wm);
  errno_assert(!rv);

  ctx->wm_fd = wm[0];

  int pid = fork();
  errno_assert(pid != -1);
  if (pid == 0) {
    char const* args[64];
    int i = 0;

    if (xwayland_cmd_prefix) {
      char* xwayland_cmd_prefix_str = sl_xasprintf("%s", xwayland_cmd_prefix);

      i = sl_parse_cmd_prefix(xwayland_cmd_prefix_str, 32, args);
      if (i > 32) {
        LOG(ERROR) << "too many arguments in cmd prefix: " << i;
        i = 0;
      }
    }

    args[i++] = sl_xasprintf("%s", xwayland_path ?: XWAYLAND_PATH);

    int fd = dup(ds[1]);
    char* display_fd_str = sl_xasprintf("%d", fd);
    fd = dup(wm[1]);
    char* wm_fd_str = sl_xasprintf("%d", fd);

    if (xdisplay > 0) {
      args[i++] = sl_xasprintf(":%d", xdisplay);
    }
    args[i++] = "-nolisten";
    args[i++] = "tcp";
    args[i++] = "-rootless";
    // Use software rendering unless we have a DRM device and glamor is
    // enabled.
    if (!ctx->drm_device || !glamor || !strcmp(glamor, "0")) {
      args[i++] = "-shm";
    }
    args[i++] = "-displayfd";
    args[i++] = display_fd_str;
    args[i++] = "-wm";
    args[i++] = wm_fd_str;
    if (xauth_path) {
      args[i++] = "-auth";
      args[i++] = sl_xasprintf("%s", xauth_path);
    }
    if (xfont_path) {
      args[i++] = "-fp";
      args[i++] = sl_xasprintf("%s", xfont_path);
    }
    args[i++] = nullptr;

    // If a path is explicitly specified via command line or environment
    // use that instead of the compiled in default.  In either case, only
    // set the environment variable if the value specified is non-empty.
    if (xwayland_gl_driver_path) {
      if (*xwayland_gl_driver_path) {
        setenv("LIBGL_DRIVERS_PATH", xwayland_gl_driver_path, 1);
      }
    } else if (XWAYLAND_GL_DRIVER_PATH && *XWAYLAND_GL_DRIVER_PATH) {
      setenv("LIBGL_DRIVERS_PATH", XWAYLAND_GL_DRIVER_PATH, 1);
    }

    sl_execvp(args[0], const_cast<char* const*>(args), wayland_socket_fd);
    _exit(EXIT_FAILURE);
  }
  close(wm[1]);
  ctx->xwayland_pid = pid;
}

void create_shims() {
  // xdg-shell shims.
  set_xdg_positioner_shim(new XdgPositionerShim());
  set_xdg_popup_shim(new XdgPopupShim());
  set_xdg_toplevel_shim(new XdgToplevelShim());
  set_xdg_surface_shim(new XdgSurfaceShim());
  set_xdg_wm_base_shim(new XdgWmBaseShim());
  set_wp_viewport_shim(new WpViewportShim());

#ifdef GAMEPAD_SUPPORT
  Libevdev::Set(new LibevdevShim());
#endif
}

static WaylandChannel* try_wayland_channel_init(
    WaylandChannel* channel, const char* channel_description) {
  if (channel) {
    int ret = channel->init();
    if (ret) {
      LOG(VERBOSE) << "WaylandChannel init for candidate '"
                   << channel_description << "' failed: " << strerror(-ret);
      delete channel;
      channel = nullptr;
    } else {
      LOG(VERBOSE) << "WaylandChannel init for candidate '"
                   << channel_description << "' succeeded.";
    }
  }
  return channel;
}

WaylandChannel* sl_create_wayland_channel(bool try_virtgpu_channel) {
  // defines a preferred channel ordering and attempt early init so we can
  // fallback if necessary.
  WaylandChannel* channel = nullptr;
  if (try_virtgpu_channel) {
    channel = try_wayland_channel_init(new VirtGpuChannel(), "VirtGpuChannel");
  }
  if (!channel) {
    channel = try_wayland_channel_init(new VirtWaylandChannel(),
                                       "VirtWaylandChannel");
  }
  if (!channel) {
    LOG(ERROR) << "WaylandChannel init failed for all candidate backends";
  }
  return channel;
}

int real_main(int argc, char** argv) {
  struct sl_context ctx;
  sl_context_init_default(&ctx);

  create_shims();

  const char* display = getenv("SOMMELIER_DISPLAY");
  const char* scale = getenv("SOMMELIER_SCALE");
  const char* dpi = getenv("SOMMELIER_DPI");
  const char* clipboard_manager = getenv("SOMMELIER_CLIPBOARD_MANAGER");
  const char* frame_color = getenv("SOMMELIER_FRAME_COLOR");
  const char* dark_frame_color = getenv("SOMMELIER_DARK_FRAME_COLOR");
  const char* support_damage_buffer = getenv("SOMMELIER_SUPPORT_DAMAGE_BUFFER");
  const char* force_drm_device = nullptr;
  const char* glamor = getenv("SOMMELIER_GLAMOR");
  const char* fullscreen_mode = getenv("SOMMELIER_FULLSCREEN_MODE");
  const char* peer_cmd_prefix = getenv("SOMMELIER_PEER_CMD_PREFIX");
  const char* xwayland_cmd_prefix = getenv("SOMMELIER_XWAYLAND_CMD_PREFIX");
  const char* accelerators = getenv("SOMMELIER_ACCELERATORS");
  const char* windowed_accelerators = getenv("SOMMELIER_WINDOWED_ACCELERATORS");
  const char* xwayland_path = getenv("SOMMELIER_XWAYLAND_PATH");
  const char* xwayland_gl_driver_path =
      getenv("SOMMELIER_XWAYLAND_GL_DRIVER_PATH");
  const char* xauth_path = getenv("SOMMELIER_XAUTH_PATH");
  const char* xfont_path = getenv("SOMMELIER_XFONT_PATH");
  const char* vm_id = getenv("SOMMELIER_VM_IDENTIFIER");
#ifdef QUIRKS_SUPPORT
  const char* quirks_paths = getenv("SOMMELIER_QUIRKS_CONFIG");
#endif
  const char* socket_name = "wayland-0";
  bool noop_driver = false;
  struct wl_listener client_destroy_listener = {};
  client_destroy_listener.notify = sl_client_destroy_notify;
  int sv[2];
  pid_t pid;
  int xdisplay = -1;
  int parent = 0;
  int client_fd = -1;
  int i;
  const char* stats_summary = nullptr;
  const char* stats_log = nullptr;
  bool use_virtgpu_channel = false;

  // Ignore SIGUSR1 (used for trace dumping) in all child processes.
  signal(SIGUSR1, SIG_IGN);

  for (i = 1; i < argc; ++i) {
    const char* arg = argv[i];
    if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0 ||
        strcmp(arg, "-?") == 0) {
      sl_print_usage();
      return EXIT_SUCCESS;
    }
    if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
      printf("Version: %s\n", SOMMELIER_VERSION);
      return EXIT_SUCCESS;
    }
#ifdef QUIRKS_SUPPORT
    if (strstr(arg, "--print-enabled-features") == arg) {
      if (!quirks_paths) {
        LOG(FATAL) << "Env var SOMMELIER_QUIRKS_CONFIG must be set to quirks "
                      "textproto path";
        return EXIT_FAILURE;
      }
      Quirks quirks;
      quirks.LoadFromCommaSeparatedFiles(quirks_paths);

      int64_t steam_game_id = sl_arg_parse_int_checked(arg);
      if (steam_game_id <= 0) {
        LOG(FATAL) << "invalid value for arg '" << arg << "': " << steam_game_id
                   << " (expected positive integer)";
        return EXIT_FAILURE;
      }
      quirks.PrintFeaturesEnabled(steam_game_id);
      return EXIT_SUCCESS;
    }
#endif

    if (strstr(arg, "--parent") == arg) {
      parent = 1;
    } else if (strstr(arg, "--log-level") == arg) {
      const int64_t log_level = sl_arg_parse_int_checked(arg);
      logging::set_min_log_level(log_level);
    } else if (strstr(arg, "--socket") == arg) {
      socket_name = sl_arg_value(arg);
    } else if (strstr(arg, "--display") == arg) {
      display = sl_arg_value(arg);
    } else if (strstr(arg, "--peer-pid") == arg) {
      ctx.peer_pid = atoi(sl_arg_value(arg));
    } else if (strstr(arg, "--peer-cmd-prefix") == arg) {
      peer_cmd_prefix = sl_arg_value(arg);
    } else if (strstr(arg, "--xwayland-cmd-prefix") == arg) {
      xwayland_cmd_prefix = sl_arg_value(arg);
    } else if (strstr(arg, "--client-fd") == arg) {
      client_fd = atoi(sl_arg_value(arg));
    } else if (strstr(arg, "--direct-scale") == arg) {
      ctx.use_direct_scale = true;
    } else if (strstr(arg, "--scale") == arg) {
      scale = sl_arg_value(arg);
    } else if (strstr(arg, "--dpi") == arg) {
      dpi = sl_arg_value(arg);
    } else if (strstr(arg, "--accelerators") == arg) {
      accelerators = sl_arg_value(arg);
    } else if (strstr(arg, "--windowed-accelerators") == arg) {
      windowed_accelerators = sl_arg_value(arg);
    } else if (strstr(arg, "--vm-identifier") == arg) {
      vm_id = sl_arg_value(arg);
    } else if (strstr(arg, "--application-id-x11-property") == arg) {
      // NB: Must be parsed before --application-id.
      ctx.application_id_property_name = sl_arg_value(arg);
    } else if (strstr(arg, "--application-id") == arg) {
      ctx.application_id = sl_arg_value(arg);
    } else if (strstr(arg, "-X") == arg) {
      ctx.xwayland = 1;
    } else if (strstr(arg, "--x-display") == arg) {
      xdisplay = atoi(sl_arg_value(arg));
      // Automatically enable X forwarding if X display is specified.
      ctx.xwayland = 1;
    } else if (strstr(arg, "--xwayland-path") == arg) {
      xwayland_path = sl_arg_value(arg);
    } else if (strstr(arg, "--xwayland-gl-driver-path") == arg) {
      xwayland_gl_driver_path = sl_arg_value(arg);
    } else if (strstr(arg, "--no-exit-with-child") == arg) {
      ctx.exit_with_child = 0;
    } else if (strstr(arg, "--sd-notify") == arg) {
      ctx.sd_notify = sl_arg_value(arg);
    } else if (strstr(arg, "--no-clipboard-manager") == arg) {
      clipboard_manager = "0";
    } else if (strstr(arg, "--frame-color") == arg) {
      frame_color = sl_arg_value(arg);
    } else if (strstr(arg, "--dark-frame-color") == arg) {
      dark_frame_color = sl_arg_value(arg);
    } else if (strstr(arg, "--force-drm-device") == arg) {
      force_drm_device = sl_arg_value(arg);
    } else if (strstr(arg, "--no-support-damage-buffer") == arg) {
      support_damage_buffer = "0";
    } else if (strstr(arg, "--glamor") == arg) {
      glamor = "1";
    } else if (strstr(arg, "--fullscreen-mode") == arg) {
      fullscreen_mode = sl_arg_value(arg);
    } else if (strstr(arg, "--x-auth") == arg) {
      xauth_path = sl_arg_value(arg);
    } else if (strstr(arg, "--x-font-path") == arg) {
      xfont_path = sl_arg_value(arg);
    } else if (strstr(arg, "--timing-filename") == arg) {
      ctx.timing = new Timing(sl_arg_value(arg));
    } else if (strstr(arg, "--explicit-fence") == arg) {
      ctx.use_explicit_fence = true;
    } else if (strstr(arg, "--enable-linux-dmabuf") == arg) {
      ctx.enable_linux_dmabuf = true;
    } else if (strstr(arg, "--enable-xshape") == arg) {
      ctx.enable_xshape = true;
    } else if (strstr(arg, "--enable-x11-move-windows") == arg) {
      ctx.enable_x11_move_windows = true;
    } else if (strstr(arg, "--virtgpu-channel") == arg) {
      use_virtgpu_channel = true;
    } else if (strstr(arg, "--noop-driver") == arg) {
      noop_driver = true;
    } else if (strstr(arg, "--stable-scaling") == arg) {
      ctx.stable_scaling = true;
    } else if (strstr(arg, "--viewport-resize") == arg) {
      ctx.viewport_resize = true;
    } else if (strstr(arg, "--allow-xwayland-emulate-screen-pos-size") == arg) {
      ctx.allow_xwayland_emulate_screen_pos_size = true;
    } else if (strstr(arg, "--ignore-stateless-toplevel-configure") == arg) {
      ctx.ignore_stateless_toplevel_configure = true;
    } else if (strstr(arg, "--only-client-can-exit-fullscreen") == arg) {
      ctx.only_client_can_exit_fullscreen = true;
#ifdef PERFETTO_TRACING
    } else if (strstr(arg, "--trace-filename") == arg) {
      ctx.trace_filename = sl_arg_value(arg);
    } else if (strstr(arg, "--trace-system") == arg) {
      ctx.trace_system = true;
#endif
#ifdef QUIRKS_SUPPORT
    } else if (strstr(arg, "--quirks-config") == arg) {
      quirks_paths = sl_arg_value(arg);
#endif
    } else if (strstr(arg, "--stats-summary") == arg) {
      stats_summary = sl_arg_value(arg);
    } else if (strstr(arg, "--stats-log") == arg) {
      stats_log = sl_arg_value(arg);
    } else if (strstr(arg, "--stats-timer") == arg) {
      ctx.stats_timer_delay = atoi(sl_arg_value(arg)) * 1000;
    } else if (arg[0] == '-') {
      if (strcmp(arg, "--") == 0) {
        ctx.runprog = &argv[i + 1];
        break;
      }
      // Don't exit on unknown options so we can have forward compatibility
      // with new flags introduced.
      LOG(WARNING) << "option '" << arg << "' is unknown, ignoring";
    } else {
      ctx.runprog = &argv[i];
      break;
    }
  }

  if (vm_id && strlen(vm_id)) {
    // Some GuestOS instances of sommelier will be started with vm_id set to a
    // container_token from /dev/.container_token.
    // The vm_id may be empty if the token or file does not yet exist.
    // Keep the vm_id as default (termina) if this occurs.
    ctx.vm_id = vm_id;
  }

  if (ctx.application_id && ctx.vm_id) {
    LOG(WARNING) << "--application-id overrides --vm-identifier";
  }
  if (ctx.application_id && ctx.application_id_property_name) {
    LOG(WARNING) << "--application-id overrides --application-id-x11-property";
  }

  if (parent) {
    return sl_run_parent(argc, argv, &ctx, socket_name, peer_cmd_prefix);
  }

  if (client_fd == -1) {
    if (!ctx.runprog || !ctx.runprog[0]) {
      sl_print_usage();
      return EXIT_FAILURE;
    }
  }

  if (ctx.xwayland) {
    assert(client_fd == -1);

    ctx.clipboard_manager = 1;
    if (clipboard_manager) {
      ctx.clipboard_manager = !!strcmp(clipboard_manager, "0");
    }
  }

  if (scale) {
    ctx.desired_scale = atof(scale);
    // Round to integer scale until we detect wp_viewporter support.
    // In direct scale mode, take the scale value as is.

    if (ctx.use_direct_scale) {
      ctx.scale = ctx.desired_scale;
    } else {
      ctx.scale = MIN(MAX_SCALE, MAX(MIN_SCALE, round(ctx.desired_scale)));
    }
  }

  if (!frame_color) {
    frame_color = FRAME_COLOR;
  }

  if (frame_color) {
    int r, g, b;
    if (sscanf(frame_color, "#%02x%02x%02x", &r, &g, &b) == 3) {
      ctx.frame_color = 0xff000000 | (r << 16) | (g << 8) | (b << 0);
    }
  }

  if (!dark_frame_color) {
    dark_frame_color = DARK_FRAME_COLOR;
  }

  if (dark_frame_color) {
    int r, g, b;
    if (sscanf(dark_frame_color, "#%02x%02x%02x", &r, &g, &b) == 3) {
      ctx.dark_frame_color = 0xff000000 | (r << 16) | (g << 8) | (b << 0);
    }
  }

  ctx.support_damage_buffer = support_damage_buffer == nullptr ||
                              strcmp(support_damage_buffer, "1") == 0;

#ifdef QUIRKS_SUPPORT
  if (quirks_paths) {
    ctx.quirks.LoadFromCommaSeparatedFiles(quirks_paths);
  }
#endif

  if (fullscreen_mode) {
    if (strcmp(fullscreen_mode, "immersive") == 0) {
      ctx.fullscreen_mode = ZAURA_SURFACE_FULLSCREEN_MODE_IMMERSIVE;
    } else if (strcmp(fullscreen_mode, "plain") == 0) {
      ctx.fullscreen_mode = ZAURA_SURFACE_FULLSCREEN_MODE_PLAIN;
    } else {
      LOG(FATAL) << "unrecognised --fullscreen-mode";
      sl_print_usage();
      return EXIT_FAILURE;
    }
  }

  // Handle broken pipes without signals that kill the entire process.
  signal(SIGPIPE, SIG_IGN);

  wl_event_loop* event_loop = nullptr;
  {
    ScopeTimer timer("configure event loop");
    // We use a wayland virtual context unless display name was explicitly
    // specified.
    const bool use_virtual_context = !display;

    WaylandChannel* wayland_channel = nullptr;
    if (!noop_driver) {
      wayland_channel = sl_create_wayland_channel(use_virtgpu_channel);
      if (!wayland_channel) {
        LOG(FATAL) << "failed to initialize wayland channel.";
        return EXIT_FAILURE;
      }
    } else if (use_virtual_context) {
      LOG(FATAL) << "Must either provide a wayland display (--display=<name>) "
                    "or use a virtual wayland channel (remove --noop-driver).";
      return EXIT_FAILURE;
    }

    event_loop = sl_context_configure_event_loop(&ctx, wayland_channel,
                                                 use_virtual_context);
    if (!event_loop) {
      return EXIT_FAILURE;
    }
  }

  {
    ScopeTimer timer("drm device");
    int drm_fd = -1;
    char* drm_device = nullptr;
    if (force_drm_device != nullptr) {
      // Use DRM device specified on the command line.
      drm_fd = open(force_drm_device, O_RDWR | O_CLOEXEC);
      if (drm_fd == -1) {
        LOG(FATAL) << "could not open " << force_drm_device << ": "
                   << strerror(errno);
        return EXIT_FAILURE;
      }
      drm_device = strdup(force_drm_device);
    } else {
      // Enumerate render nodes to find the virtio_gpu device.
      drm_fd = open_virtgpu(&drm_device);
    }
    if (drm_fd >= 0) {
      ctx.gbm = gbm_create_device(drm_fd);
      if (!ctx.gbm) {
        LOG(FATAL) << "couldn't get display device";
        return EXIT_FAILURE;
      }

      ctx.drm_device = drm_device;
    }
  }

  wl_array_init(&ctx.dpi);
  if (dpi) {
    char* str = strdup(dpi);
    char* token = strtok(str, ",");  // NOLINT(runtime/threadsafe_fn)
    int* p;

    while (token) {
      p = static_cast<int*>(wl_array_add(&ctx.dpi, sizeof *p));
      assert(p);
      *p = MAX(MIN_DPI, MIN(atoi(token), MAX_DPI));
      token = strtok(nullptr, ",");  // NOLINT(runtime/threadsafe_fn)
    }
    free(str);
  }

  // The success of this depends on xkb-data being installed.
  ctx.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
  if (!ctx.xkb_context) {
    LOG(FATAL) << "xkb_context_new failed. xkb-data missing?";
    return EXIT_FAILURE;
  }

  {
    ScopeTimer timer("connect display");
    if (ctx.virtwl_display_fd != -1) {
      ctx.display = wl_display_connect_to_fd(ctx.virtwl_display_fd);
    } else {
      if (display == nullptr) {
        display = getenv("WAYLAND_DISPLAY");
      }
      if (display == nullptr) {
        display = "wayland-0";
      }

      ctx.display = wl_display_connect(display);
    }

    if (!ctx.display) {
      LOG(FATAL) << "failed to connect to " << display;
      return EXIT_FAILURE;
    }

    if (!sl_parse_accelerators(ctx.accelerators, accelerators)) {
      return EXIT_FAILURE;
    }
    if (!sl_parse_accelerators(ctx.windowed_accelerators,
                               windowed_accelerators)) {
      return EXIT_FAILURE;
    }

    ctx.display_event_source.reset(
        wl_event_loop_add_fd(event_loop, wl_display_get_fd(ctx.display),
                             WL_EVENT_READABLE, sl_handle_event, &ctx));

    wl_registry_add_listener(wl_display_get_registry(ctx.display),
                             &sl_registry_listener, &ctx);
  }

  {
    ScopeTimer timer("client create");
    if (ctx.runprog || ctx.xwayland) {
      // Wayland connection from client.
      int rv = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv);
      errno_assert(!rv);
      client_fd = sv[0];
    }

    ctx.client = wl_client_create(ctx.host_display, client_fd);
  }

  {
    ScopeTimer timer("display implementation");
    // Replace the core display implementation. This is needed in order to
    // implement sync handler properly.
    sl_set_display_implementation(&ctx, ctx.client);
  }

  {
    ScopeTimer timer("spawn xwayland");
    if (ctx.runprog || ctx.xwayland) {
      ctx.sigchld_event_source.reset(wl_event_loop_add_signal(
          event_loop, SIGCHLD, sl_handle_sigchld, &ctx));

      if (ctx.xwayland) {
        sl_spawn_xwayland(&ctx, event_loop, sv[1], xwayland_cmd_prefix,
                          xwayland_path, xdisplay, xauth_path, xfont_path,
                          xwayland_gl_driver_path, glamor);
      } else {
        pid = fork();
        errno_assert(pid != -1);
        if (pid == 0) {
          // Unset DISPLAY to prevent X clients from connecting to an existing X
          // server when X forwarding is not enabled.
          unsetenv("DISPLAY");
          sl_execvp(ctx.runprog[0], ctx.runprog, sv[1]);
          _exit(EXIT_FAILURE);
        }
        ctx.child_pid = pid;
      }
      close(sv[1]);
    }
  }
  // Attempt to enable tracing.  This could be called earlier but would rather
  // spawn all children first.
  const bool tracing_needed = ctx.trace_filename || ctx.trace_system;
  if (tracing_needed) {
    initialize_tracing(ctx.trace_filename, ctx.trace_system);
    enable_tracing(!ctx.trace_system);
  }

  // Trigger trace and timing log dumps when USR1 signals are received
  if (tracing_needed || ctx.timing) {
    ctx.sigusr1_event_source.reset(
        wl_event_loop_add_signal(event_loop, SIGUSR1, sl_handle_sigusr1, &ctx));
  }

  // Initialize timing log values.
  if (ctx.timing) {
    ctx.timing->RecordStartTime();
  }

  if (stats_summary != nullptr || stats_log != nullptr) {
    ctx.frame_stats.reset(new FrameStats(stats_summary, stats_log));
    ctx.stats_timer_event_source.reset(
        wl_event_loop_add_timer(event_loop, sl_handle_stats_timer, &ctx));
    wl_event_source_timer_update(ctx.stats_timer_event_source.get(),
                                 ctx.stats_timer_delay);
  }

  wl_client_add_destroy_listener(ctx.client, &client_destroy_listener);

  LOG(VERBOSE) << "starting main loop";
  while (true) {
    wl_display_flush_clients(ctx.host_display);
    if (ctx.connection) {
      if (ctx.needs_set_input_focus) {
        sl_set_input_focus(&ctx, ctx.host_focus_window);
        ctx.needs_set_input_focus = 0;
      }
      xcb_flush(ctx.connection);
    }
    if (wl_display_flush(ctx.display) < 0) {
      return EXIT_FAILURE;
    }

    if (wl_event_loop_dispatch(event_loop, -1) == -1) {
      // Ignore EINTR or sommelier will exit when attached by strace or gdb.
      if (errno != EINTR) {
        return EXIT_FAILURE;
      }
    }
  }

  return EXIT_SUCCESS;
}  // NOLINT(readability/fn_size)
