// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sommelier.h"  // NOLINT(build/include_directory)

#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <wayland-client.h>
#include <wayland-util.h>

#include "keyboard-extension-unstable-v1-client-protocol.h"  // NOLINT(build/include_directory)

struct sl_host_keyboard {
  struct sl_seat* seat;
  struct wl_resource* resource;
  struct wl_keyboard* proxy;
  struct zcr_extended_keyboard_v1* extended_keyboard_proxy;
  struct wl_resource* focus_resource;
  struct wl_listener focus_resource_listener;
  uint32_t focus_serial;
  struct xkb_keymap* keymap;
  struct xkb_state* state;
  xkb_mod_mask_t control_mask;
  xkb_mod_mask_t alt_mask;
  xkb_mod_mask_t shift_mask;
  uint32_t modifiers;
  struct wl_array pressed_keys;
};

struct sl_host_touch {
  struct sl_seat* seat;
  struct wl_resource* resource;
  struct wl_touch* proxy;
  struct wl_resource* focus_resource;
  struct wl_listener focus_resource_listener;
};

static void sl_host_pointer_set_cursor(struct wl_client* client,
                                       struct wl_resource* resource,
                                       uint32_t serial,
                                       struct wl_resource* surface_resource,
                                       int32_t hotspot_x,
                                       int32_t hotspot_y) {
  struct sl_host_pointer* host =
      static_cast<sl_host_pointer*>(wl_resource_get_user_data(resource));
  struct sl_host_surface* host_surface = NULL;
  double scale = host->seat->ctx->scale;

  if (surface_resource) {
    host_surface = static_cast<sl_host_surface*>(
        wl_resource_get_user_data(surface_resource));
    host_surface->has_role = 1;
    if (host_surface->contents_width && host_surface->contents_height)
      wl_surface_commit(host_surface->proxy);
  }

  wl_pointer_set_cursor(host->proxy, serial,
                        host_surface ? host_surface->proxy : NULL,
                        hotspot_x / scale, hotspot_y / scale);
}  // NOLINT(whitespace/indent)

static void sl_host_pointer_release(struct wl_client* client,
                                    struct wl_resource* resource) {
  wl_resource_destroy(resource);
}

static const struct wl_pointer_interface sl_pointer_implementation = {
    sl_host_pointer_set_cursor, sl_host_pointer_release};

static void sl_set_last_event_serial(struct wl_resource* surface_resource,
                                     uint32_t serial) {
  struct sl_host_surface* host_surface = static_cast<sl_host_surface*>(
      wl_resource_get_user_data(surface_resource));

  host_surface->last_event_serial = serial;
}

static void sl_pointer_set_focus(struct sl_host_pointer* host,
                                 uint32_t serial,
                                 struct sl_host_surface* host_surface,
                                 wl_fixed_t x,
                                 wl_fixed_t y) {
  struct wl_resource* surface_resource =
      host_surface ? host_surface->resource : NULL;

  if (surface_resource == host->focus_resource)
    return;

  if (host->focus_resource)
    wl_pointer_send_leave(host->resource, serial, host->focus_resource);

  wl_list_remove(&host->focus_resource_listener.link);
  wl_list_init(&host->focus_resource_listener.link);
  host->focus_resource = surface_resource;
  host->focus_serial = serial;

  if (surface_resource) {
    double scale = host->seat->ctx->scale;

    if (host->seat->ctx->xwayland) {
      // Make sure focus surface is on top before sending enter event.
      sl_restack_windows(host->seat->ctx, wl_resource_get_id(surface_resource));
      sl_roundtrip(host->seat->ctx);
    }

    wl_resource_add_destroy_listener(surface_resource,
                                     &host->focus_resource_listener);

    wl_pointer_send_enter(host->resource, serial, surface_resource, x * scale,
                          y * scale);
  }
}

static void sl_pointer_enter(void* data,
                             struct wl_pointer* pointer,
                             uint32_t serial,
                             struct wl_surface* surface,
                             wl_fixed_t x,
                             wl_fixed_t y) {
  struct sl_host_pointer* host =
      static_cast<sl_host_pointer*>(wl_pointer_get_user_data(pointer));
  struct sl_host_surface* host_surface =
      surface ? static_cast<sl_host_surface*>(wl_surface_get_user_data(surface))
              : NULL;

  if (!host_surface)
    return;

  sl_pointer_set_focus(host, serial, host_surface, x, y);

  if (host->focus_resource)
    sl_set_last_event_serial(host->focus_resource, serial);
  host->seat->last_serial = serial;
}  // NOLINT(whitespace/indent)

static void sl_pointer_leave(void* data,
                             struct wl_pointer* pointer,
                             uint32_t serial,
                             struct wl_surface* surface) {
  struct sl_host_pointer* host =
      static_cast<sl_host_pointer*>(wl_pointer_get_user_data(pointer));

  sl_pointer_set_focus(host, serial, NULL, 0, 0);
}

static void sl_pointer_motion(void* data,
                              struct wl_pointer* pointer,
                              uint32_t time,
                              wl_fixed_t x,
                              wl_fixed_t y) {
  struct sl_host_pointer* host =
      static_cast<sl_host_pointer*>(wl_pointer_get_user_data(pointer));
  double scale = host->seat->ctx->scale;

  wl_pointer_send_motion(host->resource, time, x * scale, y * scale);
}

static void sl_pointer_button(void* data,
                              struct wl_pointer* pointer,
                              uint32_t serial,
                              uint32_t time,
                              uint32_t button,
                              uint32_t state) {
  struct sl_host_pointer* host =
      static_cast<sl_host_pointer*>(wl_pointer_get_user_data(pointer));

  wl_pointer_send_button(host->resource, serial, time, button, state);

  if (host->focus_resource)
    sl_set_last_event_serial(host->focus_resource, serial);
  host->seat->last_serial = serial;
}

static void sl_pointer_axis(void* data,
                            struct wl_pointer* pointer,
                            uint32_t time,
                            uint32_t axis,
                            wl_fixed_t value) {
  struct sl_host_pointer* host =
      static_cast<sl_host_pointer*>(wl_pointer_get_user_data(pointer));
  double scale = host->seat->ctx->scale;

  host->time = time;
  host->axis_delta[axis] += value * scale;
}

static void sl_pointer_frame(void* data, struct wl_pointer* pointer) {
  struct sl_host_pointer* host =
      static_cast<sl_host_pointer*>(wl_pointer_get_user_data(pointer));

  // Many X apps (e.g. VS Code, Firefox, Chromium) only allow scrolls to happen
  // in multiples of 5 units. This value comes from the smooth scrolling
  // extension of X, which says that 5 smooth scroll units is equal to 1 tick of
  // discrete scrolling.
  //
  // To avoid the experience of scrolling and seeing nothing happen, we replace
  // scroll amounts < 5 with 5 units, for discrete scrolls for X apps
  // only. Other clients should continue to see smaller scrolls as they can
  // handle them correctly, and for non-discrete scrolling (such as touch-pads)
  // we don't want to do this because it would lead to erratic jumps.
  const int kDiscreteScrollUnit = 5;

  for (int axis = 0; axis < 2; axis++) {
    if (host->axis_discrete[axis] != 0) {
      wl_pointer_send_axis_discrete(host->resource, axis,
                                    host->axis_discrete[axis]);

      double axis_delta = wl_fixed_to_double(host->axis_delta[axis]);
      if (fabs(axis_delta) < kDiscreteScrollUnit && host->seat->ctx->xwayland) {
        axis_delta = copysign(kDiscreteScrollUnit, axis_delta);
        host->axis_delta[axis] = wl_fixed_from_double(axis_delta);
      }
    }
    if (host->axis_delta[axis] != 0) {
      wl_pointer_send_axis(host->resource, host->time, axis,
                           host->axis_delta[axis]);
    }

    host->axis_delta[axis] = wl_fixed_from_int(0);
    host->axis_discrete[axis] = 0;
  }

  wl_pointer_send_frame(host->resource);
}

void sl_pointer_axis_source(void* data,
                            struct wl_pointer* pointer,
                            uint32_t axis_source) {
  struct sl_host_pointer* host =
      static_cast<sl_host_pointer*>(wl_pointer_get_user_data(pointer));

  wl_pointer_send_axis_source(host->resource, axis_source);
}

static void sl_pointer_axis_stop(void* data,
                                 struct wl_pointer* pointer,
                                 uint32_t time,
                                 uint32_t axis) {
  struct sl_host_pointer* host =
      static_cast<sl_host_pointer*>(wl_pointer_get_user_data(pointer));

  wl_pointer_send_axis_stop(host->resource, time, axis);
}

static void sl_pointer_axis_discrete(void* data,
                                     struct wl_pointer* pointer,
                                     uint32_t axis,
                                     int32_t discrete) {
  struct sl_host_pointer* host =
      static_cast<sl_host_pointer*>(wl_pointer_get_user_data(pointer));

  host->axis_discrete[axis] += discrete;
}

static const struct wl_pointer_listener sl_pointer_listener = {
    sl_pointer_enter,       sl_pointer_leave,     sl_pointer_motion,
    sl_pointer_button,      sl_pointer_axis,      sl_pointer_frame,
    sl_pointer_axis_source, sl_pointer_axis_stop, sl_pointer_axis_discrete};

static void sl_host_keyboard_release(struct wl_client* client,
                                     struct wl_resource* resource) {
  wl_resource_destroy(resource);
}

static const struct wl_keyboard_interface sl_keyboard_implementation = {
    sl_host_keyboard_release};

static void sl_keyboard_keymap(void* data,
                               struct wl_keyboard* keyboard,
                               uint32_t format,
                               int32_t fd,
                               uint32_t size) {
  struct sl_host_keyboard* host =
      static_cast<sl_host_keyboard*>(wl_keyboard_get_user_data(keyboard));

  wl_keyboard_send_keymap(host->resource, format, fd, size);

  if (format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
    void* data = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);

    assert(data != MAP_FAILED);

    if (host->keymap)
      xkb_keymap_unref(host->keymap);

    host->keymap = xkb_keymap_new_from_string(
        host->seat->ctx->xkb_context, static_cast<char*>(data),
        XKB_KEYMAP_FORMAT_TEXT_V1,
        static_cast<xkb_keymap_compile_flags>(XKB_KEYMAP_COMPILE_NO_FLAGS));
    assert(host->keymap);

    munmap(data, size);

    if (host->state)
      xkb_state_unref(host->state);
    host->state = xkb_state_new(host->keymap);
    assert(host->state);

    host->control_mask = 1 << xkb_keymap_mod_get_index(host->keymap, "Control");
    host->alt_mask = 1 << xkb_keymap_mod_get_index(host->keymap, "Mod1");
    host->shift_mask = 1 << xkb_keymap_mod_get_index(host->keymap, "Shift");
  }

  close(fd);
}

static void sl_keyboard_set_focus(struct sl_host_keyboard* host,
                                  uint32_t serial,
                                  struct sl_host_surface* host_surface,
                                  struct wl_array* keys) {
  struct wl_resource* surface_resource =
      host_surface ? host_surface->resource : NULL;

  if (surface_resource == host->focus_resource)
    return;

  if (host->focus_resource)
    wl_keyboard_send_leave(host->resource, serial, host->focus_resource);

  wl_list_remove(&host->focus_resource_listener.link);
  wl_list_init(&host->focus_resource_listener.link);
  host->focus_resource = surface_resource;
  host->focus_serial = serial;

  if (surface_resource) {
    wl_resource_add_destroy_listener(surface_resource,
                                     &host->focus_resource_listener);
    wl_keyboard_send_enter(host->resource, serial, surface_resource, keys);
  }

  host->seat->last_serial = serial;
}

static void sl_keyboard_enter(void* data,
                              struct wl_keyboard* keyboard,
                              uint32_t serial,
                              struct wl_surface* surface,
                              struct wl_array* keys) {
  struct sl_host_keyboard* host =
      static_cast<sl_host_keyboard*>(wl_keyboard_get_user_data(keyboard));
  struct sl_host_surface* host_surface =
      surface ? static_cast<sl_host_surface*>(wl_surface_get_user_data(surface))
              : NULL;

  if (!host_surface)
    return;

  wl_array_copy(&host->pressed_keys, keys);
  sl_keyboard_set_focus(host, serial, host_surface, keys);

  host->seat->last_serial = serial;
}  // NOLINT(whitespace/indent)

static void sl_keyboard_leave(void* data,
                              struct wl_keyboard* keyboard,
                              uint32_t serial,
                              struct wl_surface* surface) {
  struct sl_host_keyboard* host =
      static_cast<sl_host_keyboard*>(wl_keyboard_get_user_data(keyboard));
  struct wl_array array;

  wl_array_init(&array);
  sl_keyboard_set_focus(host, serial, NULL, &array);
}

static int sl_array_set_add(struct wl_array* array, uint32_t key) {
  uint32_t* k;

  sl_array_for_each(k, array) {
    if (*k == key)
      return 0;
  }
  k = static_cast<uint32_t*>(wl_array_add(array, sizeof(key)));
  assert(k);
  *k = key;
  return 1;
}

static int sl_array_set_remove(struct wl_array* array, uint32_t key) {
  uint32_t* k;

  sl_array_for_each(k, array) {
    if (*k == key) {
      uint32_t* end = reinterpret_cast<uint32_t*>(
          reinterpret_cast<char*>(array->data) + array->size);

      *k = *(end - 1);
      array->size -= sizeof(*k);
      return 1;
    }
  }
  return 0;
}

static void sl_keyboard_key(void* data,
                            struct wl_keyboard* keyboard,
                            uint32_t serial,
                            uint32_t time,
                            uint32_t key,
                            uint32_t state) {
  struct sl_host_keyboard* host =
      static_cast<sl_host_keyboard*>(wl_keyboard_get_user_data(keyboard));
  int handled = 1;

  if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
    if (host->state) {
      const xkb_keysym_t* symbols;
      uint32_t num_symbols;
      xkb_keysym_t symbol = XKB_KEY_NoSymbol;
      uint32_t code = key + 8;
      struct sl_accelerator* accelerator;

      num_symbols = xkb_state_key_get_syms(host->state, code, &symbols);
      if (num_symbols == 1)
        symbol = symbols[0];

      wl_list_for_each(accelerator, &host->seat->ctx->accelerators, link) {
        if (host->modifiers != accelerator->modifiers)
          continue;
        if (symbol != accelerator->symbol)
          continue;

        handled = 0;
        break;
      }
    }

    // Forward key pressed event if it should be handled and not
    // already pressed.
    if (handled) {
      if (sl_array_set_add(&host->pressed_keys, key))
        wl_keyboard_send_key(host->resource, serial, time, key, state);
    }
  } else {
    // Forward key release event if currently pressed.
    handled = sl_array_set_remove(&host->pressed_keys, key);
    if (handled)
      wl_keyboard_send_key(host->resource, serial, time, key, state);
  }

  if (host->focus_resource)
    sl_set_last_event_serial(host->focus_resource, serial);
  host->seat->last_serial = serial;

  if (host->extended_keyboard_proxy) {
    zcr_extended_keyboard_v1_ack_key(
        host->extended_keyboard_proxy, serial,
        handled ? ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_HANDLED
                : ZCR_EXTENDED_KEYBOARD_V1_HANDLED_STATE_NOT_HANDLED);
  }
}

static void sl_keyboard_modifiers(void* data,
                                  struct wl_keyboard* keyboard,
                                  uint32_t serial,
                                  uint32_t mods_depressed,
                                  uint32_t mods_latched,
                                  uint32_t mods_locked,
                                  uint32_t group) {
  struct sl_host_keyboard* host =
      static_cast<sl_host_keyboard*>(wl_keyboard_get_user_data(keyboard));
  xkb_mod_mask_t mask;

  wl_keyboard_send_modifiers(host->resource, serial, mods_depressed,
                             mods_latched, mods_locked, group);

  if (host->focus_resource)
    sl_set_last_event_serial(host->focus_resource, serial);
  host->seat->last_serial = serial;

  if (!host->keymap)
    return;

  xkb_state_update_mask(host->state, mods_depressed, mods_latched, mods_locked,
                        0, 0, group);
  mask = xkb_state_serialize_mods(
      host->state, static_cast<xkb_state_component>(XKB_STATE_MODS_DEPRESSED |
                                                    XKB_STATE_MODS_LATCHED));
  host->modifiers = 0;
  if (mask & host->control_mask)
    host->modifiers |= CONTROL_MASK;
  if (mask & host->alt_mask)
    host->modifiers |= ALT_MASK;
  if (mask & host->shift_mask)
    host->modifiers |= SHIFT_MASK;
}

static void sl_keyboard_repeat_info(void* data,
                                    struct wl_keyboard* keyboard,
                                    int32_t rate,
                                    int32_t delay) {
  struct sl_host_keyboard* host =
      static_cast<sl_host_keyboard*>(wl_keyboard_get_user_data(keyboard));

  wl_keyboard_send_repeat_info(host->resource, rate, delay);
}

static const struct wl_keyboard_listener sl_keyboard_listener = {
    sl_keyboard_keymap, sl_keyboard_enter,     sl_keyboard_leave,
    sl_keyboard_key,    sl_keyboard_modifiers, sl_keyboard_repeat_info};

static void sl_host_touch_release(struct wl_client* client,
                                  struct wl_resource* resource) {
  wl_resource_destroy(resource);
}

static const struct wl_touch_interface sl_touch_implementation = {
    sl_host_touch_release};

static void sl_host_touch_down(void* data,
                               struct wl_touch* touch,
                               uint32_t serial,
                               uint32_t time,
                               struct wl_surface* surface,
                               int32_t id,
                               wl_fixed_t x,
                               wl_fixed_t y) {
  struct sl_host_touch* host =
      static_cast<sl_host_touch*>(wl_touch_get_user_data(touch));
  struct sl_host_surface* host_surface =
      surface ? static_cast<sl_host_surface*>(wl_surface_get_user_data(surface))
              : NULL;
  double scale = host->seat->ctx->scale;

  if (!host_surface)
    return;

  if (host_surface->resource != host->focus_resource) {
    wl_list_remove(&host->focus_resource_listener.link);
    wl_list_init(&host->focus_resource_listener.link);
    host->focus_resource = host_surface->resource;
    wl_resource_add_destroy_listener(host_surface->resource,
                                     &host->focus_resource_listener);
  }

  if (host->seat->ctx->xwayland) {
    // Make sure focus surface is on top before sending down event.
    sl_restack_windows(host->seat->ctx,
                       wl_resource_get_id(host_surface->resource));
    sl_roundtrip(host->seat->ctx);
  }

  wl_touch_send_down(host->resource, serial, time, host_surface->resource, id,
                     x * scale, y * scale);

  if (host->focus_resource)
    sl_set_last_event_serial(host->focus_resource, serial);
  host->seat->last_serial = serial;
}  // NOLINT(whitespace/indent)

static void sl_host_touch_up(void* data,
                             struct wl_touch* touch,
                             uint32_t serial,
                             uint32_t time,
                             int32_t id) {
  struct sl_host_touch* host =
      static_cast<sl_host_touch*>(wl_touch_get_user_data(touch));

  wl_list_remove(&host->focus_resource_listener.link);
  wl_list_init(&host->focus_resource_listener.link);
  host->focus_resource = NULL;

  wl_touch_send_up(host->resource, serial, time, id);

  if (host->focus_resource)
    sl_set_last_event_serial(host->focus_resource, serial);
  host->seat->last_serial = serial;
}

static void sl_host_touch_motion(void* data,
                                 struct wl_touch* touch,
                                 uint32_t time,
                                 int32_t id,
                                 wl_fixed_t x,
                                 wl_fixed_t y) {
  struct sl_host_touch* host =
      static_cast<sl_host_touch*>(wl_touch_get_user_data(touch));
  double scale = host->seat->ctx->scale;

  wl_touch_send_motion(host->resource, time, id, x * scale, y * scale);
}

static void sl_host_touch_frame(void* data, struct wl_touch* touch) {
  struct sl_host_touch* host =
      static_cast<sl_host_touch*>(wl_touch_get_user_data(touch));

  wl_touch_send_frame(host->resource);
}

static void sl_host_touch_cancel(void* data, struct wl_touch* touch) {
  struct sl_host_touch* host =
      static_cast<sl_host_touch*>(wl_touch_get_user_data(touch));

  wl_touch_send_cancel(host->resource);
}

static const struct wl_touch_listener sl_touch_listener = {
    sl_host_touch_down, sl_host_touch_up, sl_host_touch_motion,
    sl_host_touch_frame, sl_host_touch_cancel};

static void sl_destroy_host_pointer(struct wl_resource* resource) {
  struct sl_host_pointer* host =
      static_cast<sl_host_pointer*>(wl_resource_get_user_data(resource));

  if (wl_pointer_get_version(host->proxy) >= WL_POINTER_RELEASE_SINCE_VERSION) {
    wl_pointer_release(host->proxy);
  } else {
    wl_pointer_destroy(host->proxy);
  }
  wl_list_remove(&host->focus_resource_listener.link);
  wl_resource_set_user_data(resource, NULL);
  free(host);
}

static void sl_pointer_focus_resource_destroyed(struct wl_listener* listener,
                                                void* data) {
  struct sl_host_pointer* host;

  host = wl_container_of(listener, host, focus_resource_listener);
  sl_pointer_set_focus(host, host->focus_serial, NULL, 0, 0);
}

static void sl_host_seat_get_host_pointer(struct wl_client* client,
                                          struct wl_resource* resource,
                                          uint32_t id) {
  struct sl_host_seat* host =
      static_cast<sl_host_seat*>(wl_resource_get_user_data(resource));
  struct sl_host_pointer* host_pointer =
      static_cast<sl_host_pointer*>(malloc(sizeof(*host_pointer)));
  assert(host_pointer);

  host_pointer->seat = host->seat;
  host_pointer->resource = wl_resource_create(
      client, &wl_pointer_interface, wl_resource_get_version(resource), id);
  wl_resource_set_implementation(host_pointer->resource,
                                 &sl_pointer_implementation, host_pointer,
                                 sl_destroy_host_pointer);
  host_pointer->proxy = wl_seat_get_pointer(host->proxy);
  wl_pointer_set_user_data(host_pointer->proxy, host_pointer);
  wl_pointer_add_listener(host_pointer->proxy, &sl_pointer_listener,
                          host_pointer);
  wl_list_init(&host_pointer->focus_resource_listener.link);
  host_pointer->focus_resource_listener.notify =
      sl_pointer_focus_resource_destroyed;
  host_pointer->focus_resource = NULL;
  host_pointer->focus_serial = 0;
  host_pointer->time = 0;
  host_pointer->axis_delta[0] = wl_fixed_from_int(0);
  host_pointer->axis_delta[1] = wl_fixed_from_int(0);
  host_pointer->axis_discrete[0] = 0;
  host_pointer->axis_discrete[1] = 0;
}

static void sl_destroy_host_keyboard(struct wl_resource* resource) {
  struct sl_host_keyboard* host =
      static_cast<sl_host_keyboard*>(wl_resource_get_user_data(resource));

  if (host->extended_keyboard_proxy)
    zcr_extended_keyboard_v1_destroy(host->extended_keyboard_proxy);

  wl_array_release(&host->pressed_keys);
  if (host->keymap)
    xkb_keymap_unref(host->keymap);
  if (host->state)
    xkb_state_unref(host->state);

  if (wl_keyboard_get_version(host->proxy) >=
      WL_KEYBOARD_RELEASE_SINCE_VERSION) {
    wl_keyboard_release(host->proxy);
  } else {
    wl_keyboard_destroy(host->proxy);
  }

  wl_list_remove(&host->focus_resource_listener.link);
  wl_resource_set_user_data(resource, NULL);
  free(host);
}

static void sl_keyboard_focus_resource_destroyed(struct wl_listener* listener,
                                                 void* data) {
  struct sl_host_keyboard* host;
  struct wl_array array;

  host = wl_container_of(listener, host, focus_resource_listener);
  wl_array_init(&array);
  sl_keyboard_set_focus(host, host->focus_serial, NULL, &array);
}

static void sl_host_seat_get_host_keyboard(struct wl_client* client,
                                           struct wl_resource* resource,
                                           uint32_t id) {
  struct sl_host_seat* host =
      static_cast<sl_host_seat*>(wl_resource_get_user_data(resource));
  struct sl_host_keyboard* host_keyboard =
      static_cast<sl_host_keyboard*>(malloc(sizeof(*host_keyboard)));
  assert(host_keyboard);

  host_keyboard->seat = host->seat;
  host_keyboard->resource = wl_resource_create(
      client, &wl_keyboard_interface, wl_resource_get_version(resource), id);
  wl_resource_set_implementation(host_keyboard->resource,
                                 &sl_keyboard_implementation, host_keyboard,
                                 sl_destroy_host_keyboard);
  host_keyboard->proxy = wl_seat_get_keyboard(host->proxy);
  wl_keyboard_set_user_data(host_keyboard->proxy, host_keyboard);
  wl_keyboard_add_listener(host_keyboard->proxy, &sl_keyboard_listener,
                           host_keyboard);
  wl_list_init(&host_keyboard->focus_resource_listener.link);
  host_keyboard->focus_resource_listener.notify =
      sl_keyboard_focus_resource_destroyed;
  host_keyboard->focus_resource = NULL;
  host_keyboard->focus_serial = 0;
  host_keyboard->keymap = NULL;
  host_keyboard->state = NULL;
  host_keyboard->control_mask = 0;
  host_keyboard->alt_mask = 0;
  host_keyboard->shift_mask = 0;
  host_keyboard->modifiers = 0;
  wl_array_init(&host_keyboard->pressed_keys);

  if (host->seat->ctx->keyboard_extension) {
    host_keyboard->extended_keyboard_proxy =
        zcr_keyboard_extension_v1_get_extended_keyboard(
            host->seat->ctx->keyboard_extension->internal,
            host_keyboard->proxy);
  } else {
    host_keyboard->extended_keyboard_proxy = NULL;
  }
}

static void sl_destroy_host_touch(struct wl_resource* resource) {
  struct sl_host_touch* host =
      static_cast<sl_host_touch*>(wl_resource_get_user_data(resource));

  if (wl_touch_get_version(host->proxy) >= WL_TOUCH_RELEASE_SINCE_VERSION) {
    wl_touch_release(host->proxy);
  } else {
    wl_touch_destroy(host->proxy);
  }
  wl_resource_set_user_data(resource, NULL);
  free(host);
}

static void sl_touch_focus_resource_destroyed(struct wl_listener* listener,
                                              void* data) {
  struct sl_host_touch* host;

  host = wl_container_of(listener, host, focus_resource_listener);
  wl_list_remove(&host->focus_resource_listener.link);
  wl_list_init(&host->focus_resource_listener.link);
  host->focus_resource = NULL;
}

static void sl_host_seat_get_host_touch(struct wl_client* client,
                                        struct wl_resource* resource,
                                        uint32_t id) {
  struct sl_host_seat* host =
      static_cast<sl_host_seat*>(wl_resource_get_user_data(resource));
  struct sl_host_touch* host_touch =
      static_cast<sl_host_touch*>(malloc(sizeof(*host_touch)));
  assert(host_touch);

  host_touch->seat = host->seat;
  host_touch->resource = wl_resource_create(
      client, &wl_touch_interface, wl_resource_get_version(resource), id);
  wl_resource_set_implementation(host_touch->resource, &sl_touch_implementation,
                                 host_touch, sl_destroy_host_touch);
  host_touch->proxy = wl_seat_get_touch(host->proxy);
  wl_touch_set_user_data(host_touch->proxy, host_touch);
  wl_touch_add_listener(host_touch->proxy, &sl_touch_listener, host_touch);
  wl_list_init(&host_touch->focus_resource_listener.link);
  host_touch->focus_resource_listener.notify =
      sl_touch_focus_resource_destroyed;
  host_touch->focus_resource = NULL;
}

static void sl_host_seat_release(struct wl_client* client,
                                 struct wl_resource* resource) {
  struct sl_host_seat* host =
      static_cast<sl_host_seat*>(wl_resource_get_user_data(resource));

  wl_seat_release(host->proxy);
}

static const struct wl_seat_interface sl_seat_implementation = {
    sl_host_seat_get_host_pointer, sl_host_seat_get_host_keyboard,
    sl_host_seat_get_host_touch, sl_host_seat_release};

static void sl_seat_capabilities(void* data,
                                 struct wl_seat* seat,
                                 uint32_t capabilities) {
  struct sl_host_seat* host =
      static_cast<sl_host_seat*>(wl_seat_get_user_data(seat));

  wl_seat_send_capabilities(host->resource, capabilities);
}

static void sl_seat_name(void* data, struct wl_seat* seat, const char* name) {
  struct sl_host_seat* host =
      static_cast<sl_host_seat*>(wl_seat_get_user_data(seat));

  if (wl_resource_get_version(host->resource) >= WL_SEAT_NAME_SINCE_VERSION)
    wl_seat_send_name(host->resource, name);
}

static const struct wl_seat_listener sl_seat_listener = {sl_seat_capabilities,
                                                         sl_seat_name};

static void sl_destroy_host_seat(struct wl_resource* resource) {
  struct sl_host_seat* host =
      static_cast<sl_host_seat*>(wl_resource_get_user_data(resource));

  sl_host_seat_removed(host);

  if (wl_seat_get_version(host->proxy) >= WL_SEAT_RELEASE_SINCE_VERSION)
    wl_seat_release(host->proxy);
  else
    wl_seat_destroy(host->proxy);
  wl_resource_set_user_data(resource, NULL);
  free(host);
}

static void sl_bind_host_seat(struct wl_client* client,
                              void* data,
                              uint32_t version,
                              uint32_t id) {
  struct sl_seat* seat = (struct sl_seat*)data;
  struct sl_host_seat* host = static_cast<sl_host_seat*>(malloc(sizeof(*host)));
  assert(host);
  host->seat = seat;
  host->resource = wl_resource_create(client, &wl_seat_interface,
                                      MIN(version, seat->version), id);
  wl_resource_set_implementation(host->resource, &sl_seat_implementation, host,
                                 sl_destroy_host_seat);
  host->proxy = static_cast<wl_seat*>(wl_registry_bind(
      wl_display_get_registry(seat->ctx->display), seat->id, &wl_seat_interface,
      wl_resource_get_version(host->resource)));
  wl_seat_set_user_data(host->proxy, host);
  wl_seat_add_listener(host->proxy, &sl_seat_listener, host);

  sl_host_seat_added(host);
}

struct sl_global* sl_seat_global_create(struct sl_seat* seat) {
  return sl_global_create(seat->ctx, &wl_seat_interface, seat->version, seat,
                          sl_bind_host_seat);
}
