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

// This file was automatically generated with:
// ../../ui/gfx/x/gen_xproto.py \
//    ../../third_party/xcbproto/src \
//    gen/ui/gfx/x \
//    bigreq \
//    composite \
//    damage \
//    dpms \
//    dri2 \
//    dri3 \
//    ge \
//    glx \
//    present \
//    randr \
//    record \
//    render \
//    res \
//    screensaver \
//    shape \
//    shm \
//    sync \
//    xc_misc \
//    xevie \
//    xf86dri \
//    xf86vidmode \
//    xfixes \
//    xinerama \
//    xinput \
//    xkb \
//    xprint \
//    xproto \
//    xselinux \
//    xtest \
//    xv \
//    xvmc

#include "render.h"

#include <xcb/xcb.h>
#include <xcb/xcbext.h>

#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "ui/gfx/x/xproto_internal.h"

namespace x11 {

Render::Render(Connection* connection, const x11::QueryExtensionReply& info)
    : connection_(connection), info_(info) {}

std::string Render::PictFormatError::ToString() const {
  std::stringstream ss_;
  ss_ << "Render::PictFormatError{";
  ss_ << ".sequence = " << static_cast<uint64_t>(sequence);
  ss_ << "}";
  return ss_.str();
}

template <>
void ReadError<Render::PictFormatError>(Render::PictFormatError* error_,
                                        ReadBuffer* buffer) {
  auto& buf = *buffer;

  auto& sequence = (*error_).sequence;

  // response_type
  uint8_t response_type;
  Read(&response_type, &buf);

  // error_code
  uint8_t error_code;
  Read(&error_code, &buf);

  // sequence
  Read(&sequence, &buf);

  DCHECK_LE(buf.offset, 32ul);
}
std::string Render::PictureError::ToString() const {
  std::stringstream ss_;
  ss_ << "Render::PictureError{";
  ss_ << ".sequence = " << static_cast<uint64_t>(sequence);
  ss_ << "}";
  return ss_.str();
}

template <>
void ReadError<Render::PictureError>(Render::PictureError* error_,
                                     ReadBuffer* buffer) {
  auto& buf = *buffer;

  auto& sequence = (*error_).sequence;

  // response_type
  uint8_t response_type;
  Read(&response_type, &buf);

  // error_code
  uint8_t error_code;
  Read(&error_code, &buf);

  // sequence
  Read(&sequence, &buf);

  DCHECK_LE(buf.offset, 32ul);
}
std::string Render::PictOpError::ToString() const {
  std::stringstream ss_;
  ss_ << "Render::PictOpError{";
  ss_ << ".sequence = " << static_cast<uint64_t>(sequence);
  ss_ << "}";
  return ss_.str();
}

template <>
void ReadError<Render::PictOpError>(Render::PictOpError* error_,
                                    ReadBuffer* buffer) {
  auto& buf = *buffer;

  auto& sequence = (*error_).sequence;

  // response_type
  uint8_t response_type;
  Read(&response_type, &buf);

  // error_code
  uint8_t error_code;
  Read(&error_code, &buf);

  // sequence
  Read(&sequence, &buf);

  DCHECK_LE(buf.offset, 32ul);
}
std::string Render::GlyphSetError::ToString() const {
  std::stringstream ss_;
  ss_ << "Render::GlyphSetError{";
  ss_ << ".sequence = " << static_cast<uint64_t>(sequence);
  ss_ << "}";
  return ss_.str();
}

template <>
void ReadError<Render::GlyphSetError>(Render::GlyphSetError* error_,
                                      ReadBuffer* buffer) {
  auto& buf = *buffer;

  auto& sequence = (*error_).sequence;

  // response_type
  uint8_t response_type;
  Read(&response_type, &buf);

  // error_code
  uint8_t error_code;
  Read(&error_code, &buf);

  // sequence
  Read(&sequence, &buf);

  DCHECK_LE(buf.offset, 32ul);
}
std::string Render::GlyphError::ToString() const {
  std::stringstream ss_;
  ss_ << "Render::GlyphError{";
  ss_ << ".sequence = " << static_cast<uint64_t>(sequence);
  ss_ << "}";
  return ss_.str();
}

template <>
void ReadError<Render::GlyphError>(Render::GlyphError* error_,
                                   ReadBuffer* buffer) {
  auto& buf = *buffer;

  auto& sequence = (*error_).sequence;

  // response_type
  uint8_t response_type;
  Read(&response_type, &buf);

  // error_code
  uint8_t error_code;
  Read(&error_code, &buf);

  // sequence
  Read(&sequence, &buf);

  DCHECK_LE(buf.offset, 32ul);
}
Future<Render::QueryVersionReply> Render::QueryVersion(
    const Render::QueryVersionRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& client_major_version = request.client_major_version;
  auto& client_minor_version = request.client_minor_version;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 0;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // client_major_version
  buf.Write(&client_major_version);

  // client_minor_version
  buf.Write(&client_minor_version);

  Align(&buf, 4);

  return connection_->SendRequest<Render::QueryVersionReply>(
      &buf, "Render::QueryVersion", false);
}

Future<Render::QueryVersionReply> Render::QueryVersion(
    const uint32_t& client_major_version,
    const uint32_t& client_minor_version) {
  return Render::QueryVersion(
      Render::QueryVersionRequest{client_major_version, client_minor_version});
}

template <>
COMPONENT_EXPORT(X11)
std::unique_ptr<Render::QueryVersionReply> detail::ReadReply<
    Render::QueryVersionReply>(ReadBuffer* buffer) {
  auto& buf = *buffer;
  auto reply = std::make_unique<Render::QueryVersionReply>();

  auto& sequence = (*reply).sequence;
  auto& major_version = (*reply).major_version;
  auto& minor_version = (*reply).minor_version;

  // response_type
  uint8_t response_type;
  Read(&response_type, &buf);

  // pad0
  Pad(&buf, 1);

  // sequence
  Read(&sequence, &buf);

  // length
  uint32_t length;
  Read(&length, &buf);

  // major_version
  Read(&major_version, &buf);

  // minor_version
  Read(&minor_version, &buf);

  // pad1
  Pad(&buf, 16);

  Align(&buf, 4);
  DCHECK_EQ(buf.offset < 32 ? 0 : buf.offset - 32, 4 * length);

  return reply;
}

Future<Render::QueryPictFormatsReply> Render::QueryPictFormats(
    const Render::QueryPictFormatsRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 1;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  Align(&buf, 4);

  return connection_->SendRequest<Render::QueryPictFormatsReply>(
      &buf, "Render::QueryPictFormats", false);
}

Future<Render::QueryPictFormatsReply> Render::QueryPictFormats() {
  return Render::QueryPictFormats(Render::QueryPictFormatsRequest{});
}

template <>
COMPONENT_EXPORT(X11)
std::unique_ptr<Render::QueryPictFormatsReply> detail::ReadReply<
    Render::QueryPictFormatsReply>(ReadBuffer* buffer) {
  auto& buf = *buffer;
  auto reply = std::make_unique<Render::QueryPictFormatsReply>();

  auto& sequence = (*reply).sequence;
  uint32_t num_formats{};
  uint32_t num_screens{};
  auto& num_depths = (*reply).num_depths;
  auto& num_visuals = (*reply).num_visuals;
  uint32_t num_subpixel{};
  auto& formats = (*reply).formats;
  size_t formats_len = formats.size();
  auto& screens = (*reply).screens;
  size_t screens_len = screens.size();
  auto& subpixels = (*reply).subpixels;
  size_t subpixels_len = subpixels.size();

  // response_type
  uint8_t response_type;
  Read(&response_type, &buf);

  // pad0
  Pad(&buf, 1);

  // sequence
  Read(&sequence, &buf);

  // length
  uint32_t length;
  Read(&length, &buf);

  // num_formats
  Read(&num_formats, &buf);

  // num_screens
  Read(&num_screens, &buf);

  // num_depths
  Read(&num_depths, &buf);

  // num_visuals
  Read(&num_visuals, &buf);

  // num_subpixel
  Read(&num_subpixel, &buf);

  // pad1
  Pad(&buf, 4);

  // formats
  formats.resize(num_formats);
  for (auto& formats_elem : formats) {
    // formats_elem
    {
      auto& id = formats_elem.id;
      auto& type = formats_elem.type;
      auto& depth = formats_elem.depth;
      auto& direct = formats_elem.direct;
      auto& colormap = formats_elem.colormap;

      // id
      Read(&id, &buf);

      // type
      uint8_t tmp0;
      Read(&tmp0, &buf);
      type = static_cast<Render::PictType>(tmp0);

      // depth
      Read(&depth, &buf);

      // pad0
      Pad(&buf, 2);

      // direct
      {
        auto& red_shift = direct.red_shift;
        auto& red_mask = direct.red_mask;
        auto& green_shift = direct.green_shift;
        auto& green_mask = direct.green_mask;
        auto& blue_shift = direct.blue_shift;
        auto& blue_mask = direct.blue_mask;
        auto& alpha_shift = direct.alpha_shift;
        auto& alpha_mask = direct.alpha_mask;

        // red_shift
        Read(&red_shift, &buf);

        // red_mask
        Read(&red_mask, &buf);

        // green_shift
        Read(&green_shift, &buf);

        // green_mask
        Read(&green_mask, &buf);

        // blue_shift
        Read(&blue_shift, &buf);

        // blue_mask
        Read(&blue_mask, &buf);

        // alpha_shift
        Read(&alpha_shift, &buf);

        // alpha_mask
        Read(&alpha_mask, &buf);
      }

      // colormap
      Read(&colormap, &buf);
    }
  }

  // screens
  screens.resize(num_screens);
  for (auto& screens_elem : screens) {
    // screens_elem
    {
      uint32_t num_depths{};
      auto& fallback = screens_elem.fallback;
      auto& depths = screens_elem.depths;
      size_t depths_len = depths.size();

      // num_depths
      Read(&num_depths, &buf);

      // fallback
      Read(&fallback, &buf);

      // depths
      depths.resize(num_depths);
      for (auto& depths_elem : depths) {
        // depths_elem
        {
          auto& depth = depths_elem.depth;
          uint16_t num_visuals{};
          auto& visuals = depths_elem.visuals;
          size_t visuals_len = visuals.size();

          // depth
          Read(&depth, &buf);

          // pad0
          Pad(&buf, 1);

          // num_visuals
          Read(&num_visuals, &buf);

          // pad1
          Pad(&buf, 4);

          // visuals
          visuals.resize(num_visuals);
          for (auto& visuals_elem : visuals) {
            // visuals_elem
            {
              auto& visual = visuals_elem.visual;
              auto& format = visuals_elem.format;

              // visual
              Read(&visual, &buf);

              // format
              Read(&format, &buf);
            }
          }
        }
      }
    }
  }

  // subpixels
  subpixels.resize(num_subpixel);
  for (auto& subpixels_elem : subpixels) {
    // subpixels_elem
    uint32_t tmp1;
    Read(&tmp1, &buf);
    subpixels_elem = static_cast<Render::SubPixel>(tmp1);
  }

  Align(&buf, 4);
  DCHECK_EQ(buf.offset < 32 ? 0 : buf.offset - 32, 4 * length);

  return reply;
}

Future<Render::QueryPictIndexValuesReply> Render::QueryPictIndexValues(
    const Render::QueryPictIndexValuesRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& format = request.format;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 2;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // format
  buf.Write(&format);

  Align(&buf, 4);

  return connection_->SendRequest<Render::QueryPictIndexValuesReply>(
      &buf, "Render::QueryPictIndexValues", false);
}

Future<Render::QueryPictIndexValuesReply> Render::QueryPictIndexValues(
    const PictFormat& format) {
  return Render::QueryPictIndexValues(
      Render::QueryPictIndexValuesRequest{format});
}

template <>
COMPONENT_EXPORT(X11)
std::unique_ptr<Render::QueryPictIndexValuesReply> detail::ReadReply<
    Render::QueryPictIndexValuesReply>(ReadBuffer* buffer) {
  auto& buf = *buffer;
  auto reply = std::make_unique<Render::QueryPictIndexValuesReply>();

  auto& sequence = (*reply).sequence;
  uint32_t num_values{};
  auto& values = (*reply).values;
  size_t values_len = values.size();

  // response_type
  uint8_t response_type;
  Read(&response_type, &buf);

  // pad0
  Pad(&buf, 1);

  // sequence
  Read(&sequence, &buf);

  // length
  uint32_t length;
  Read(&length, &buf);

  // num_values
  Read(&num_values, &buf);

  // pad1
  Pad(&buf, 20);

  // values
  values.resize(num_values);
  for (auto& values_elem : values) {
    // values_elem
    {
      auto& pixel = values_elem.pixel;
      auto& red = values_elem.red;
      auto& green = values_elem.green;
      auto& blue = values_elem.blue;
      auto& alpha = values_elem.alpha;

      // pixel
      Read(&pixel, &buf);

      // red
      Read(&red, &buf);

      // green
      Read(&green, &buf);

      // blue
      Read(&blue, &buf);

      // alpha
      Read(&alpha, &buf);
    }
  }

  Align(&buf, 4);
  DCHECK_EQ(buf.offset < 32 ? 0 : buf.offset - 32, 4 * length);

  return reply;
}

Future<void> Render::CreatePicture(
    const Render::CreatePictureRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& pid = request.pid;
  auto& drawable = request.drawable;
  auto& format = request.format;
  CreatePictureAttribute value_mask{};
  auto& value_list = request;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 4;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // pid
  buf.Write(&pid);

  // drawable
  buf.Write(&drawable);

  // format
  buf.Write(&format);

  // value_mask
  SwitchVar(CreatePictureAttribute::Repeat, value_list.repeat.has_value(), true,
            &value_mask);
  SwitchVar(CreatePictureAttribute::AlphaMap, value_list.alphamap.has_value(),
            true, &value_mask);
  SwitchVar(CreatePictureAttribute::AlphaXOrigin,
            value_list.alphaxorigin.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::AlphaYOrigin,
            value_list.alphayorigin.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::ClipXOrigin,
            value_list.clipxorigin.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::ClipYOrigin,
            value_list.clipyorigin.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::ClipMask, value_list.clipmask.has_value(),
            true, &value_mask);
  SwitchVar(CreatePictureAttribute::GraphicsExposure,
            value_list.graphicsexposure.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::SubwindowMode,
            value_list.subwindowmode.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::PolyEdge, value_list.polyedge.has_value(),
            true, &value_mask);
  SwitchVar(CreatePictureAttribute::PolyMode, value_list.polymode.has_value(),
            true, &value_mask);
  SwitchVar(CreatePictureAttribute::Dither, value_list.dither.has_value(), true,
            &value_mask);
  SwitchVar(CreatePictureAttribute::ComponentAlpha,
            value_list.componentalpha.has_value(), true, &value_mask);
  uint32_t tmp2;
  tmp2 = static_cast<uint32_t>(value_mask);
  buf.Write(&tmp2);

  // value_list
  auto value_list_expr = value_mask;
  if (CaseAnd(value_list_expr, CreatePictureAttribute::Repeat)) {
    auto& repeat = *value_list.repeat;

    // repeat
    uint32_t tmp3;
    tmp3 = static_cast<uint32_t>(repeat);
    buf.Write(&tmp3);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::AlphaMap)) {
    auto& alphamap = *value_list.alphamap;

    // alphamap
    buf.Write(&alphamap);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::AlphaXOrigin)) {
    auto& alphaxorigin = *value_list.alphaxorigin;

    // alphaxorigin
    buf.Write(&alphaxorigin);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::AlphaYOrigin)) {
    auto& alphayorigin = *value_list.alphayorigin;

    // alphayorigin
    buf.Write(&alphayorigin);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::ClipXOrigin)) {
    auto& clipxorigin = *value_list.clipxorigin;

    // clipxorigin
    buf.Write(&clipxorigin);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::ClipYOrigin)) {
    auto& clipyorigin = *value_list.clipyorigin;

    // clipyorigin
    buf.Write(&clipyorigin);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::ClipMask)) {
    auto& clipmask = *value_list.clipmask;

    // clipmask
    buf.Write(&clipmask);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::GraphicsExposure)) {
    auto& graphicsexposure = *value_list.graphicsexposure;

    // graphicsexposure
    buf.Write(&graphicsexposure);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::SubwindowMode)) {
    auto& subwindowmode = *value_list.subwindowmode;

    // subwindowmode
    uint32_t tmp4;
    tmp4 = static_cast<uint32_t>(subwindowmode);
    buf.Write(&tmp4);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::PolyEdge)) {
    auto& polyedge = *value_list.polyedge;

    // polyedge
    uint32_t tmp5;
    tmp5 = static_cast<uint32_t>(polyedge);
    buf.Write(&tmp5);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::PolyMode)) {
    auto& polymode = *value_list.polymode;

    // polymode
    uint32_t tmp6;
    tmp6 = static_cast<uint32_t>(polymode);
    buf.Write(&tmp6);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::Dither)) {
    auto& dither = *value_list.dither;

    // dither
    buf.Write(&dither);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::ComponentAlpha)) {
    auto& componentalpha = *value_list.componentalpha;

    // componentalpha
    buf.Write(&componentalpha);
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::CreatePicture", false);
}

Future<void> Render::CreatePicture(
    const Picture& pid,
    const Drawable& drawable,
    const PictFormat& format,
    const absl::optional<Repeat>& repeat,
    const absl::optional<Picture>& alphamap,
    const absl::optional<int32_t>& alphaxorigin,
    const absl::optional<int32_t>& alphayorigin,
    const absl::optional<int32_t>& clipxorigin,
    const absl::optional<int32_t>& clipyorigin,
    const absl::optional<Pixmap>& clipmask,
    const absl::optional<uint32_t>& graphicsexposure,
    const absl::optional<SubwindowMode>& subwindowmode,
    const absl::optional<PolyEdge>& polyedge,
    const absl::optional<PolyMode>& polymode,
    const absl::optional<Atom>& dither,
    const absl::optional<uint32_t>& componentalpha) {
  return Render::CreatePicture(Render::CreatePictureRequest{
      pid, drawable, format, repeat, alphamap, alphaxorigin, alphayorigin,
      clipxorigin, clipyorigin, clipmask, graphicsexposure, subwindowmode,
      polyedge, polymode, dither, componentalpha});
}

Future<void> Render::ChangePicture(
    const Render::ChangePictureRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& picture = request.picture;
  CreatePictureAttribute value_mask{};
  auto& value_list = request;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 5;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // picture
  buf.Write(&picture);

  // value_mask
  SwitchVar(CreatePictureAttribute::Repeat, value_list.repeat.has_value(), true,
            &value_mask);
  SwitchVar(CreatePictureAttribute::AlphaMap, value_list.alphamap.has_value(),
            true, &value_mask);
  SwitchVar(CreatePictureAttribute::AlphaXOrigin,
            value_list.alphaxorigin.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::AlphaYOrigin,
            value_list.alphayorigin.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::ClipXOrigin,
            value_list.clipxorigin.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::ClipYOrigin,
            value_list.clipyorigin.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::ClipMask, value_list.clipmask.has_value(),
            true, &value_mask);
  SwitchVar(CreatePictureAttribute::GraphicsExposure,
            value_list.graphicsexposure.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::SubwindowMode,
            value_list.subwindowmode.has_value(), true, &value_mask);
  SwitchVar(CreatePictureAttribute::PolyEdge, value_list.polyedge.has_value(),
            true, &value_mask);
  SwitchVar(CreatePictureAttribute::PolyMode, value_list.polymode.has_value(),
            true, &value_mask);
  SwitchVar(CreatePictureAttribute::Dither, value_list.dither.has_value(), true,
            &value_mask);
  SwitchVar(CreatePictureAttribute::ComponentAlpha,
            value_list.componentalpha.has_value(), true, &value_mask);
  uint32_t tmp7;
  tmp7 = static_cast<uint32_t>(value_mask);
  buf.Write(&tmp7);

  // value_list
  auto value_list_expr = value_mask;
  if (CaseAnd(value_list_expr, CreatePictureAttribute::Repeat)) {
    auto& repeat = *value_list.repeat;

    // repeat
    uint32_t tmp8;
    tmp8 = static_cast<uint32_t>(repeat);
    buf.Write(&tmp8);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::AlphaMap)) {
    auto& alphamap = *value_list.alphamap;

    // alphamap
    buf.Write(&alphamap);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::AlphaXOrigin)) {
    auto& alphaxorigin = *value_list.alphaxorigin;

    // alphaxorigin
    buf.Write(&alphaxorigin);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::AlphaYOrigin)) {
    auto& alphayorigin = *value_list.alphayorigin;

    // alphayorigin
    buf.Write(&alphayorigin);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::ClipXOrigin)) {
    auto& clipxorigin = *value_list.clipxorigin;

    // clipxorigin
    buf.Write(&clipxorigin);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::ClipYOrigin)) {
    auto& clipyorigin = *value_list.clipyorigin;

    // clipyorigin
    buf.Write(&clipyorigin);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::ClipMask)) {
    auto& clipmask = *value_list.clipmask;

    // clipmask
    buf.Write(&clipmask);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::GraphicsExposure)) {
    auto& graphicsexposure = *value_list.graphicsexposure;

    // graphicsexposure
    buf.Write(&graphicsexposure);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::SubwindowMode)) {
    auto& subwindowmode = *value_list.subwindowmode;

    // subwindowmode
    uint32_t tmp9;
    tmp9 = static_cast<uint32_t>(subwindowmode);
    buf.Write(&tmp9);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::PolyEdge)) {
    auto& polyedge = *value_list.polyedge;

    // polyedge
    uint32_t tmp10;
    tmp10 = static_cast<uint32_t>(polyedge);
    buf.Write(&tmp10);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::PolyMode)) {
    auto& polymode = *value_list.polymode;

    // polymode
    uint32_t tmp11;
    tmp11 = static_cast<uint32_t>(polymode);
    buf.Write(&tmp11);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::Dither)) {
    auto& dither = *value_list.dither;

    // dither
    buf.Write(&dither);
  }
  if (CaseAnd(value_list_expr, CreatePictureAttribute::ComponentAlpha)) {
    auto& componentalpha = *value_list.componentalpha;

    // componentalpha
    buf.Write(&componentalpha);
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::ChangePicture", false);
}

Future<void> Render::ChangePicture(
    const Picture& picture,
    const absl::optional<Repeat>& repeat,
    const absl::optional<Picture>& alphamap,
    const absl::optional<int32_t>& alphaxorigin,
    const absl::optional<int32_t>& alphayorigin,
    const absl::optional<int32_t>& clipxorigin,
    const absl::optional<int32_t>& clipyorigin,
    const absl::optional<Pixmap>& clipmask,
    const absl::optional<uint32_t>& graphicsexposure,
    const absl::optional<SubwindowMode>& subwindowmode,
    const absl::optional<PolyEdge>& polyedge,
    const absl::optional<PolyMode>& polymode,
    const absl::optional<Atom>& dither,
    const absl::optional<uint32_t>& componentalpha) {
  return Render::ChangePicture(Render::ChangePictureRequest{
      picture, repeat, alphamap, alphaxorigin, alphayorigin, clipxorigin,
      clipyorigin, clipmask, graphicsexposure, subwindowmode, polyedge,
      polymode, dither, componentalpha});
}

Future<void> Render::SetPictureClipRectangles(
    const Render::SetPictureClipRectanglesRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& picture = request.picture;
  auto& clip_x_origin = request.clip_x_origin;
  auto& clip_y_origin = request.clip_y_origin;
  auto& rectangles = request.rectangles;
  size_t rectangles_len = rectangles.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 6;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // picture
  buf.Write(&picture);

  // clip_x_origin
  buf.Write(&clip_x_origin);

  // clip_y_origin
  buf.Write(&clip_y_origin);

  // rectangles
  DCHECK_EQ(static_cast<size_t>(rectangles_len), rectangles.size());
  for (auto& rectangles_elem : rectangles) {
    // rectangles_elem
    {
      auto& x = rectangles_elem.x;
      auto& y = rectangles_elem.y;
      auto& width = rectangles_elem.width;
      auto& height = rectangles_elem.height;

      // x
      buf.Write(&x);

      // y
      buf.Write(&y);

      // width
      buf.Write(&width);

      // height
      buf.Write(&height);
    }
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(
      &buf, "Render::SetPictureClipRectangles", false);
}

Future<void> Render::SetPictureClipRectangles(
    const Picture& picture,
    const int16_t& clip_x_origin,
    const int16_t& clip_y_origin,
    const std::vector<Rectangle>& rectangles) {
  return Render::SetPictureClipRectangles(
      Render::SetPictureClipRectanglesRequest{picture, clip_x_origin,
                                              clip_y_origin, rectangles});
}

Future<void> Render::FreePicture(const Render::FreePictureRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& picture = request.picture;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 7;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // picture
  buf.Write(&picture);

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::FreePicture", false);
}

Future<void> Render::FreePicture(const Picture& picture) {
  return Render::FreePicture(Render::FreePictureRequest{picture});
}

Future<void> Render::Composite(const Render::CompositeRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& op = request.op;
  auto& src = request.src;
  auto& mask = request.mask;
  auto& dst = request.dst;
  auto& src_x = request.src_x;
  auto& src_y = request.src_y;
  auto& mask_x = request.mask_x;
  auto& mask_y = request.mask_y;
  auto& dst_x = request.dst_x;
  auto& dst_y = request.dst_y;
  auto& width = request.width;
  auto& height = request.height;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 8;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // op
  uint8_t tmp12;
  tmp12 = static_cast<uint8_t>(op);
  buf.Write(&tmp12);

  // pad0
  Pad(&buf, 3);

  // src
  buf.Write(&src);

  // mask
  buf.Write(&mask);

  // dst
  buf.Write(&dst);

  // src_x
  buf.Write(&src_x);

  // src_y
  buf.Write(&src_y);

  // mask_x
  buf.Write(&mask_x);

  // mask_y
  buf.Write(&mask_y);

  // dst_x
  buf.Write(&dst_x);

  // dst_y
  buf.Write(&dst_y);

  // width
  buf.Write(&width);

  // height
  buf.Write(&height);

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::Composite", false);
}

Future<void> Render::Composite(const PictOp& op,
                               const Picture& src,
                               const Picture& mask,
                               const Picture& dst,
                               const int16_t& src_x,
                               const int16_t& src_y,
                               const int16_t& mask_x,
                               const int16_t& mask_y,
                               const int16_t& dst_x,
                               const int16_t& dst_y,
                               const uint16_t& width,
                               const uint16_t& height) {
  return Render::Composite(
      Render::CompositeRequest{op, src, mask, dst, src_x, src_y, mask_x, mask_y,
                               dst_x, dst_y, width, height});
}

Future<void> Render::Trapezoids(const Render::TrapezoidsRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& op = request.op;
  auto& src = request.src;
  auto& dst = request.dst;
  auto& mask_format = request.mask_format;
  auto& src_x = request.src_x;
  auto& src_y = request.src_y;
  auto& traps = request.traps;
  size_t traps_len = traps.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 10;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // op
  uint8_t tmp13;
  tmp13 = static_cast<uint8_t>(op);
  buf.Write(&tmp13);

  // pad0
  Pad(&buf, 3);

  // src
  buf.Write(&src);

  // dst
  buf.Write(&dst);

  // mask_format
  buf.Write(&mask_format);

  // src_x
  buf.Write(&src_x);

  // src_y
  buf.Write(&src_y);

  // traps
  DCHECK_EQ(static_cast<size_t>(traps_len), traps.size());
  for (auto& traps_elem : traps) {
    // traps_elem
    {
      auto& top = traps_elem.top;
      auto& bottom = traps_elem.bottom;
      auto& left = traps_elem.left;
      auto& right = traps_elem.right;

      // top
      buf.Write(&top);

      // bottom
      buf.Write(&bottom);

      // left
      {
        auto& p1 = left.p1;
        auto& p2 = left.p2;

        // p1
        {
          auto& x = p1.x;
          auto& y = p1.y;

          // x
          buf.Write(&x);

          // y
          buf.Write(&y);
        }

        // p2
        {
          auto& x = p2.x;
          auto& y = p2.y;

          // x
          buf.Write(&x);

          // y
          buf.Write(&y);
        }
      }

      // right
      {
        auto& p1 = right.p1;
        auto& p2 = right.p2;

        // p1
        {
          auto& x = p1.x;
          auto& y = p1.y;

          // x
          buf.Write(&x);

          // y
          buf.Write(&y);
        }

        // p2
        {
          auto& x = p2.x;
          auto& y = p2.y;

          // x
          buf.Write(&x);

          // y
          buf.Write(&y);
        }
      }
    }
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::Trapezoids", false);
}

Future<void> Render::Trapezoids(const PictOp& op,
                                const Picture& src,
                                const Picture& dst,
                                const PictFormat& mask_format,
                                const int16_t& src_x,
                                const int16_t& src_y,
                                const std::vector<Trapezoid>& traps) {
  return Render::Trapezoids(Render::TrapezoidsRequest{op, src, dst, mask_format,
                                                      src_x, src_y, traps});
}

Future<void> Render::Triangles(const Render::TrianglesRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& op = request.op;
  auto& src = request.src;
  auto& dst = request.dst;
  auto& mask_format = request.mask_format;
  auto& src_x = request.src_x;
  auto& src_y = request.src_y;
  auto& triangles = request.triangles;
  size_t triangles_len = triangles.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 11;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // op
  uint8_t tmp14;
  tmp14 = static_cast<uint8_t>(op);
  buf.Write(&tmp14);

  // pad0
  Pad(&buf, 3);

  // src
  buf.Write(&src);

  // dst
  buf.Write(&dst);

  // mask_format
  buf.Write(&mask_format);

  // src_x
  buf.Write(&src_x);

  // src_y
  buf.Write(&src_y);

  // triangles
  DCHECK_EQ(static_cast<size_t>(triangles_len), triangles.size());
  for (auto& triangles_elem : triangles) {
    // triangles_elem
    {
      auto& p1 = triangles_elem.p1;
      auto& p2 = triangles_elem.p2;
      auto& p3 = triangles_elem.p3;

      // p1
      {
        auto& x = p1.x;
        auto& y = p1.y;

        // x
        buf.Write(&x);

        // y
        buf.Write(&y);
      }

      // p2
      {
        auto& x = p2.x;
        auto& y = p2.y;

        // x
        buf.Write(&x);

        // y
        buf.Write(&y);
      }

      // p3
      {
        auto& x = p3.x;
        auto& y = p3.y;

        // x
        buf.Write(&x);

        // y
        buf.Write(&y);
      }
    }
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::Triangles", false);
}

Future<void> Render::Triangles(const PictOp& op,
                               const Picture& src,
                               const Picture& dst,
                               const PictFormat& mask_format,
                               const int16_t& src_x,
                               const int16_t& src_y,
                               const std::vector<Triangle>& triangles) {
  return Render::Triangles(Render::TrianglesRequest{op, src, dst, mask_format,
                                                    src_x, src_y, triangles});
}

Future<void> Render::TriStrip(const Render::TriStripRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& op = request.op;
  auto& src = request.src;
  auto& dst = request.dst;
  auto& mask_format = request.mask_format;
  auto& src_x = request.src_x;
  auto& src_y = request.src_y;
  auto& points = request.points;
  size_t points_len = points.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 12;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // op
  uint8_t tmp15;
  tmp15 = static_cast<uint8_t>(op);
  buf.Write(&tmp15);

  // pad0
  Pad(&buf, 3);

  // src
  buf.Write(&src);

  // dst
  buf.Write(&dst);

  // mask_format
  buf.Write(&mask_format);

  // src_x
  buf.Write(&src_x);

  // src_y
  buf.Write(&src_y);

  // points
  DCHECK_EQ(static_cast<size_t>(points_len), points.size());
  for (auto& points_elem : points) {
    // points_elem
    {
      auto& x = points_elem.x;
      auto& y = points_elem.y;

      // x
      buf.Write(&x);

      // y
      buf.Write(&y);
    }
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::TriStrip", false);
}

Future<void> Render::TriStrip(const PictOp& op,
                              const Picture& src,
                              const Picture& dst,
                              const PictFormat& mask_format,
                              const int16_t& src_x,
                              const int16_t& src_y,
                              const std::vector<PointFix>& points) {
  return Render::TriStrip(
      Render::TriStripRequest{op, src, dst, mask_format, src_x, src_y, points});
}

Future<void> Render::TriFan(const Render::TriFanRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& op = request.op;
  auto& src = request.src;
  auto& dst = request.dst;
  auto& mask_format = request.mask_format;
  auto& src_x = request.src_x;
  auto& src_y = request.src_y;
  auto& points = request.points;
  size_t points_len = points.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 13;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // op
  uint8_t tmp16;
  tmp16 = static_cast<uint8_t>(op);
  buf.Write(&tmp16);

  // pad0
  Pad(&buf, 3);

  // src
  buf.Write(&src);

  // dst
  buf.Write(&dst);

  // mask_format
  buf.Write(&mask_format);

  // src_x
  buf.Write(&src_x);

  // src_y
  buf.Write(&src_y);

  // points
  DCHECK_EQ(static_cast<size_t>(points_len), points.size());
  for (auto& points_elem : points) {
    // points_elem
    {
      auto& x = points_elem.x;
      auto& y = points_elem.y;

      // x
      buf.Write(&x);

      // y
      buf.Write(&y);
    }
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::TriFan", false);
}

Future<void> Render::TriFan(const PictOp& op,
                            const Picture& src,
                            const Picture& dst,
                            const PictFormat& mask_format,
                            const int16_t& src_x,
                            const int16_t& src_y,
                            const std::vector<PointFix>& points) {
  return Render::TriFan(
      Render::TriFanRequest{op, src, dst, mask_format, src_x, src_y, points});
}

Future<void> Render::CreateGlyphSet(
    const Render::CreateGlyphSetRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& gsid = request.gsid;
  auto& format = request.format;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 17;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // gsid
  buf.Write(&gsid);

  // format
  buf.Write(&format);

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::CreateGlyphSet", false);
}

Future<void> Render::CreateGlyphSet(const GlyphSet& gsid,
                                    const PictFormat& format) {
  return Render::CreateGlyphSet(Render::CreateGlyphSetRequest{gsid, format});
}

Future<void> Render::ReferenceGlyphSet(
    const Render::ReferenceGlyphSetRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& gsid = request.gsid;
  auto& existing = request.existing;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 18;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // gsid
  buf.Write(&gsid);

  // existing
  buf.Write(&existing);

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::ReferenceGlyphSet",
                                        false);
}

Future<void> Render::ReferenceGlyphSet(const GlyphSet& gsid,
                                       const GlyphSet& existing) {
  return Render::ReferenceGlyphSet(
      Render::ReferenceGlyphSetRequest{gsid, existing});
}

Future<void> Render::FreeGlyphSet(const Render::FreeGlyphSetRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& glyphset = request.glyphset;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 19;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // glyphset
  buf.Write(&glyphset);

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::FreeGlyphSet", false);
}

Future<void> Render::FreeGlyphSet(const GlyphSet& glyphset) {
  return Render::FreeGlyphSet(Render::FreeGlyphSetRequest{glyphset});
}

Future<void> Render::AddGlyphs(const Render::AddGlyphsRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& glyphset = request.glyphset;
  uint32_t glyphs_len{};
  auto& glyphids = request.glyphids;
  size_t glyphids_len = glyphids.size();
  auto& glyphs = request.glyphs;
  auto& data = request.data;
  size_t data_len = data.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 20;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // glyphset
  buf.Write(&glyphset);

  // glyphs_len
  glyphs_len = glyphs.size();
  buf.Write(&glyphs_len);

  // glyphids
  DCHECK_EQ(static_cast<size_t>(glyphs_len), glyphids.size());
  for (auto& glyphids_elem : glyphids) {
    // glyphids_elem
    buf.Write(&glyphids_elem);
  }

  // glyphs
  DCHECK_EQ(static_cast<size_t>(glyphs_len), glyphs.size());
  for (auto& glyphs_elem : glyphs) {
    // glyphs_elem
    {
      auto& width = glyphs_elem.width;
      auto& height = glyphs_elem.height;
      auto& x = glyphs_elem.x;
      auto& y = glyphs_elem.y;
      auto& x_off = glyphs_elem.x_off;
      auto& y_off = glyphs_elem.y_off;

      // width
      buf.Write(&width);

      // height
      buf.Write(&height);

      // x
      buf.Write(&x);

      // y
      buf.Write(&y);

      // x_off
      buf.Write(&x_off);

      // y_off
      buf.Write(&y_off);
    }
  }

  // data
  DCHECK_EQ(static_cast<size_t>(data_len), data.size());
  for (auto& data_elem : data) {
    // data_elem
    buf.Write(&data_elem);
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::AddGlyphs", false);
}

Future<void> Render::AddGlyphs(const GlyphSet& glyphset,
                               const std::vector<uint32_t>& glyphids,
                               const std::vector<GlyphInfo>& glyphs,
                               const std::vector<uint8_t>& data) {
  return Render::AddGlyphs(
      Render::AddGlyphsRequest{glyphset, glyphids, glyphs, data});
}

Future<void> Render::FreeGlyphs(const Render::FreeGlyphsRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& glyphset = request.glyphset;
  auto& glyphs = request.glyphs;
  size_t glyphs_len = glyphs.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 22;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // glyphset
  buf.Write(&glyphset);

  // glyphs
  DCHECK_EQ(static_cast<size_t>(glyphs_len), glyphs.size());
  for (auto& glyphs_elem : glyphs) {
    // glyphs_elem
    buf.Write(&glyphs_elem);
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::FreeGlyphs", false);
}

Future<void> Render::FreeGlyphs(const GlyphSet& glyphset,
                                const std::vector<Glyph>& glyphs) {
  return Render::FreeGlyphs(Render::FreeGlyphsRequest{glyphset, glyphs});
}

Future<void> Render::CompositeGlyphs8(
    const Render::CompositeGlyphs8Request& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& op = request.op;
  auto& src = request.src;
  auto& dst = request.dst;
  auto& mask_format = request.mask_format;
  auto& glyphset = request.glyphset;
  auto& src_x = request.src_x;
  auto& src_y = request.src_y;
  auto& glyphcmds = request.glyphcmds;
  size_t glyphcmds_len = glyphcmds.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 23;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // op
  uint8_t tmp17;
  tmp17 = static_cast<uint8_t>(op);
  buf.Write(&tmp17);

  // pad0
  Pad(&buf, 3);

  // src
  buf.Write(&src);

  // dst
  buf.Write(&dst);

  // mask_format
  buf.Write(&mask_format);

  // glyphset
  buf.Write(&glyphset);

  // src_x
  buf.Write(&src_x);

  // src_y
  buf.Write(&src_y);

  // glyphcmds
  DCHECK_EQ(static_cast<size_t>(glyphcmds_len), glyphcmds.size());
  for (auto& glyphcmds_elem : glyphcmds) {
    // glyphcmds_elem
    buf.Write(&glyphcmds_elem);
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::CompositeGlyphs8",
                                        false);
}

Future<void> Render::CompositeGlyphs8(const PictOp& op,
                                      const Picture& src,
                                      const Picture& dst,
                                      const PictFormat& mask_format,
                                      const GlyphSet& glyphset,
                                      const int16_t& src_x,
                                      const int16_t& src_y,
                                      const std::vector<uint8_t>& glyphcmds) {
  return Render::CompositeGlyphs8(Render::CompositeGlyphs8Request{
      op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds});
}

Future<void> Render::CompositeGlyphs16(
    const Render::CompositeGlyphs16Request& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& op = request.op;
  auto& src = request.src;
  auto& dst = request.dst;
  auto& mask_format = request.mask_format;
  auto& glyphset = request.glyphset;
  auto& src_x = request.src_x;
  auto& src_y = request.src_y;
  auto& glyphcmds = request.glyphcmds;
  size_t glyphcmds_len = glyphcmds.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 24;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // op
  uint8_t tmp18;
  tmp18 = static_cast<uint8_t>(op);
  buf.Write(&tmp18);

  // pad0
  Pad(&buf, 3);

  // src
  buf.Write(&src);

  // dst
  buf.Write(&dst);

  // mask_format
  buf.Write(&mask_format);

  // glyphset
  buf.Write(&glyphset);

  // src_x
  buf.Write(&src_x);

  // src_y
  buf.Write(&src_y);

  // glyphcmds
  DCHECK_EQ(static_cast<size_t>(glyphcmds_len), glyphcmds.size());
  for (auto& glyphcmds_elem : glyphcmds) {
    // glyphcmds_elem
    buf.Write(&glyphcmds_elem);
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::CompositeGlyphs16",
                                        false);
}

Future<void> Render::CompositeGlyphs16(const PictOp& op,
                                       const Picture& src,
                                       const Picture& dst,
                                       const PictFormat& mask_format,
                                       const GlyphSet& glyphset,
                                       const int16_t& src_x,
                                       const int16_t& src_y,
                                       const std::vector<uint8_t>& glyphcmds) {
  return Render::CompositeGlyphs16(Render::CompositeGlyphs16Request{
      op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds});
}

Future<void> Render::CompositeGlyphs32(
    const Render::CompositeGlyphs32Request& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& op = request.op;
  auto& src = request.src;
  auto& dst = request.dst;
  auto& mask_format = request.mask_format;
  auto& glyphset = request.glyphset;
  auto& src_x = request.src_x;
  auto& src_y = request.src_y;
  auto& glyphcmds = request.glyphcmds;
  size_t glyphcmds_len = glyphcmds.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 25;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // op
  uint8_t tmp19;
  tmp19 = static_cast<uint8_t>(op);
  buf.Write(&tmp19);

  // pad0
  Pad(&buf, 3);

  // src
  buf.Write(&src);

  // dst
  buf.Write(&dst);

  // mask_format
  buf.Write(&mask_format);

  // glyphset
  buf.Write(&glyphset);

  // src_x
  buf.Write(&src_x);

  // src_y
  buf.Write(&src_y);

  // glyphcmds
  DCHECK_EQ(static_cast<size_t>(glyphcmds_len), glyphcmds.size());
  for (auto& glyphcmds_elem : glyphcmds) {
    // glyphcmds_elem
    buf.Write(&glyphcmds_elem);
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::CompositeGlyphs32",
                                        false);
}

Future<void> Render::CompositeGlyphs32(const PictOp& op,
                                       const Picture& src,
                                       const Picture& dst,
                                       const PictFormat& mask_format,
                                       const GlyphSet& glyphset,
                                       const int16_t& src_x,
                                       const int16_t& src_y,
                                       const std::vector<uint8_t>& glyphcmds) {
  return Render::CompositeGlyphs32(Render::CompositeGlyphs32Request{
      op, src, dst, mask_format, glyphset, src_x, src_y, glyphcmds});
}

Future<void> Render::FillRectangles(
    const Render::FillRectanglesRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& op = request.op;
  auto& dst = request.dst;
  auto& color = request.color;
  auto& rects = request.rects;
  size_t rects_len = rects.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 26;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // op
  uint8_t tmp20;
  tmp20 = static_cast<uint8_t>(op);
  buf.Write(&tmp20);

  // pad0
  Pad(&buf, 3);

  // dst
  buf.Write(&dst);

  // color
  {
    auto& red = color.red;
    auto& green = color.green;
    auto& blue = color.blue;
    auto& alpha = color.alpha;

    // red
    buf.Write(&red);

    // green
    buf.Write(&green);

    // blue
    buf.Write(&blue);

    // alpha
    buf.Write(&alpha);
  }

  // rects
  DCHECK_EQ(static_cast<size_t>(rects_len), rects.size());
  for (auto& rects_elem : rects) {
    // rects_elem
    {
      auto& x = rects_elem.x;
      auto& y = rects_elem.y;
      auto& width = rects_elem.width;
      auto& height = rects_elem.height;

      // x
      buf.Write(&x);

      // y
      buf.Write(&y);

      // width
      buf.Write(&width);

      // height
      buf.Write(&height);
    }
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::FillRectangles", false);
}

Future<void> Render::FillRectangles(const PictOp& op,
                                    const Picture& dst,
                                    const Color& color,
                                    const std::vector<Rectangle>& rects) {
  return Render::FillRectangles(
      Render::FillRectanglesRequest{op, dst, color, rects});
}

Future<void> Render::CreateCursor(const Render::CreateCursorRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& cid = request.cid;
  auto& source = request.source;
  auto& x = request.x;
  auto& y = request.y;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 27;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // cid
  buf.Write(&cid);

  // source
  buf.Write(&source);

  // x
  buf.Write(&x);

  // y
  buf.Write(&y);

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::CreateCursor", false);
}

Future<void> Render::CreateCursor(const Cursor& cid,
                                  const Picture& source,
                                  const uint16_t& x,
                                  const uint16_t& y) {
  return Render::CreateCursor(Render::CreateCursorRequest{cid, source, x, y});
}

Future<void> Render::SetPictureTransform(
    const Render::SetPictureTransformRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& picture = request.picture;
  auto& transform = request.transform;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 28;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // picture
  buf.Write(&picture);

  // transform
  {
    auto& matrix11 = transform.matrix11;
    auto& matrix12 = transform.matrix12;
    auto& matrix13 = transform.matrix13;
    auto& matrix21 = transform.matrix21;
    auto& matrix22 = transform.matrix22;
    auto& matrix23 = transform.matrix23;
    auto& matrix31 = transform.matrix31;
    auto& matrix32 = transform.matrix32;
    auto& matrix33 = transform.matrix33;

    // matrix11
    buf.Write(&matrix11);

    // matrix12
    buf.Write(&matrix12);

    // matrix13
    buf.Write(&matrix13);

    // matrix21
    buf.Write(&matrix21);

    // matrix22
    buf.Write(&matrix22);

    // matrix23
    buf.Write(&matrix23);

    // matrix31
    buf.Write(&matrix31);

    // matrix32
    buf.Write(&matrix32);

    // matrix33
    buf.Write(&matrix33);
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::SetPictureTransform",
                                        false);
}

Future<void> Render::SetPictureTransform(const Picture& picture,
                                         const Transform& transform) {
  return Render::SetPictureTransform(
      Render::SetPictureTransformRequest{picture, transform});
}

Future<Render::QueryFiltersReply> Render::QueryFilters(
    const Render::QueryFiltersRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& drawable = request.drawable;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 29;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // drawable
  buf.Write(&drawable);

  Align(&buf, 4);

  return connection_->SendRequest<Render::QueryFiltersReply>(
      &buf, "Render::QueryFilters", false);
}

Future<Render::QueryFiltersReply> Render::QueryFilters(
    const Drawable& drawable) {
  return Render::QueryFilters(Render::QueryFiltersRequest{drawable});
}

template <>
COMPONENT_EXPORT(X11)
std::unique_ptr<Render::QueryFiltersReply> detail::ReadReply<
    Render::QueryFiltersReply>(ReadBuffer* buffer) {
  auto& buf = *buffer;
  auto reply = std::make_unique<Render::QueryFiltersReply>();

  auto& sequence = (*reply).sequence;
  uint32_t num_aliases{};
  uint32_t num_filters{};
  auto& aliases = (*reply).aliases;
  size_t aliases_len = aliases.size();
  auto& filters = (*reply).filters;
  size_t filters_len = filters.size();

  // response_type
  uint8_t response_type;
  Read(&response_type, &buf);

  // pad0
  Pad(&buf, 1);

  // sequence
  Read(&sequence, &buf);

  // length
  uint32_t length;
  Read(&length, &buf);

  // num_aliases
  Read(&num_aliases, &buf);

  // num_filters
  Read(&num_filters, &buf);

  // pad1
  Pad(&buf, 16);

  // aliases
  aliases.resize(num_aliases);
  for (auto& aliases_elem : aliases) {
    // aliases_elem
    Read(&aliases_elem, &buf);
  }

  // filters
  filters.resize(num_filters);
  for (auto& filters_elem : filters) {
    // filters_elem
    {
      uint8_t name_len{};
      auto& name = filters_elem.name;

      // name_len
      Read(&name_len, &buf);

      // name
      name.resize(name_len);
      for (auto& name_elem : name) {
        // name_elem
        Read(&name_elem, &buf);
      }
    }
  }

  Align(&buf, 4);
  DCHECK_EQ(buf.offset < 32 ? 0 : buf.offset - 32, 4 * length);

  return reply;
}

Future<void> Render::SetPictureFilter(
    const Render::SetPictureFilterRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& picture = request.picture;
  uint16_t filter_len{};
  auto& filter = request.filter;
  auto& values = request.values;
  size_t values_len = values.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 30;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // picture
  buf.Write(&picture);

  // filter_len
  filter_len = filter.size();
  buf.Write(&filter_len);

  // pad0
  Pad(&buf, 2);

  // filter
  DCHECK_EQ(static_cast<size_t>(filter_len), filter.size());
  for (auto& filter_elem : filter) {
    // filter_elem
    buf.Write(&filter_elem);
  }

  // pad1
  Align(&buf, 4);

  // values
  DCHECK_EQ(static_cast<size_t>(values_len), values.size());
  for (auto& values_elem : values) {
    // values_elem
    buf.Write(&values_elem);
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::SetPictureFilter",
                                        false);
}

Future<void> Render::SetPictureFilter(const Picture& picture,
                                      const std::string& filter,
                                      const std::vector<Fixed>& values) {
  return Render::SetPictureFilter(
      Render::SetPictureFilterRequest{picture, filter, values});
}

Future<void> Render::CreateAnimCursor(
    const Render::CreateAnimCursorRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& cid = request.cid;
  auto& cursors = request.cursors;
  size_t cursors_len = cursors.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 31;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // cid
  buf.Write(&cid);

  // cursors
  DCHECK_EQ(static_cast<size_t>(cursors_len), cursors.size());
  for (auto& cursors_elem : cursors) {
    // cursors_elem
    {
      auto& cursor = cursors_elem.cursor;
      auto& delay = cursors_elem.delay;

      // cursor
      buf.Write(&cursor);

      // delay
      buf.Write(&delay);
    }
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::CreateAnimCursor",
                                        false);
}

Future<void> Render::CreateAnimCursor(
    const Cursor& cid,
    const std::vector<AnimationCursorElement>& cursors) {
  return Render::CreateAnimCursor(
      Render::CreateAnimCursorRequest{cid, cursors});
}

Future<void> Render::AddTraps(const Render::AddTrapsRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& picture = request.picture;
  auto& x_off = request.x_off;
  auto& y_off = request.y_off;
  auto& traps = request.traps;
  size_t traps_len = traps.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 32;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // picture
  buf.Write(&picture);

  // x_off
  buf.Write(&x_off);

  // y_off
  buf.Write(&y_off);

  // traps
  DCHECK_EQ(static_cast<size_t>(traps_len), traps.size());
  for (auto& traps_elem : traps) {
    // traps_elem
    {
      auto& top = traps_elem.top;
      auto& bot = traps_elem.bot;

      // top
      {
        auto& l = top.l;
        auto& r = top.r;
        auto& y = top.y;

        // l
        buf.Write(&l);

        // r
        buf.Write(&r);

        // y
        buf.Write(&y);
      }

      // bot
      {
        auto& l = bot.l;
        auto& r = bot.r;
        auto& y = bot.y;

        // l
        buf.Write(&l);

        // r
        buf.Write(&r);

        // y
        buf.Write(&y);
      }
    }
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::AddTraps", false);
}

Future<void> Render::AddTraps(const Picture& picture,
                              const int16_t& x_off,
                              const int16_t& y_off,
                              const std::vector<Trap>& traps) {
  return Render::AddTraps(
      Render::AddTrapsRequest{picture, x_off, y_off, traps});
}

Future<void> Render::CreateSolidFill(
    const Render::CreateSolidFillRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& picture = request.picture;
  auto& color = request.color;

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 33;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // picture
  buf.Write(&picture);

  // color
  {
    auto& red = color.red;
    auto& green = color.green;
    auto& blue = color.blue;
    auto& alpha = color.alpha;

    // red
    buf.Write(&red);

    // green
    buf.Write(&green);

    // blue
    buf.Write(&blue);

    // alpha
    buf.Write(&alpha);
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::CreateSolidFill", false);
}

Future<void> Render::CreateSolidFill(const Picture& picture,
                                     const Color& color) {
  return Render::CreateSolidFill(
      Render::CreateSolidFillRequest{picture, color});
}

Future<void> Render::CreateLinearGradient(
    const Render::CreateLinearGradientRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& picture = request.picture;
  auto& p1 = request.p1;
  auto& p2 = request.p2;
  uint32_t num_stops{};
  auto& stops = request.stops;
  size_t stops_len = stops.size();
  auto& colors = request.colors;
  size_t colors_len = colors.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 34;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // picture
  buf.Write(&picture);

  // p1
  {
    auto& x = p1.x;
    auto& y = p1.y;

    // x
    buf.Write(&x);

    // y
    buf.Write(&y);
  }

  // p2
  {
    auto& x = p2.x;
    auto& y = p2.y;

    // x
    buf.Write(&x);

    // y
    buf.Write(&y);
  }

  // num_stops
  num_stops = stops.size();
  buf.Write(&num_stops);

  // stops
  DCHECK_EQ(static_cast<size_t>(num_stops), stops.size());
  for (auto& stops_elem : stops) {
    // stops_elem
    buf.Write(&stops_elem);
  }

  // colors
  DCHECK_EQ(static_cast<size_t>(num_stops), colors.size());
  for (auto& colors_elem : colors) {
    // colors_elem
    {
      auto& red = colors_elem.red;
      auto& green = colors_elem.green;
      auto& blue = colors_elem.blue;
      auto& alpha = colors_elem.alpha;

      // red
      buf.Write(&red);

      // green
      buf.Write(&green);

      // blue
      buf.Write(&blue);

      // alpha
      buf.Write(&alpha);
    }
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::CreateLinearGradient",
                                        false);
}

Future<void> Render::CreateLinearGradient(const Picture& picture,
                                          const PointFix& p1,
                                          const PointFix& p2,
                                          const std::vector<Fixed>& stops,
                                          const std::vector<Color>& colors) {
  return Render::CreateLinearGradient(
      Render::CreateLinearGradientRequest{picture, p1, p2, stops, colors});
}

Future<void> Render::CreateRadialGradient(
    const Render::CreateRadialGradientRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& picture = request.picture;
  auto& inner = request.inner;
  auto& outer = request.outer;
  auto& inner_radius = request.inner_radius;
  auto& outer_radius = request.outer_radius;
  uint32_t num_stops{};
  auto& stops = request.stops;
  size_t stops_len = stops.size();
  auto& colors = request.colors;
  size_t colors_len = colors.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 35;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // picture
  buf.Write(&picture);

  // inner
  {
    auto& x = inner.x;
    auto& y = inner.y;

    // x
    buf.Write(&x);

    // y
    buf.Write(&y);
  }

  // outer
  {
    auto& x = outer.x;
    auto& y = outer.y;

    // x
    buf.Write(&x);

    // y
    buf.Write(&y);
  }

  // inner_radius
  buf.Write(&inner_radius);

  // outer_radius
  buf.Write(&outer_radius);

  // num_stops
  num_stops = stops.size();
  buf.Write(&num_stops);

  // stops
  DCHECK_EQ(static_cast<size_t>(num_stops), stops.size());
  for (auto& stops_elem : stops) {
    // stops_elem
    buf.Write(&stops_elem);
  }

  // colors
  DCHECK_EQ(static_cast<size_t>(num_stops), colors.size());
  for (auto& colors_elem : colors) {
    // colors_elem
    {
      auto& red = colors_elem.red;
      auto& green = colors_elem.green;
      auto& blue = colors_elem.blue;
      auto& alpha = colors_elem.alpha;

      // red
      buf.Write(&red);

      // green
      buf.Write(&green);

      // blue
      buf.Write(&blue);

      // alpha
      buf.Write(&alpha);
    }
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::CreateRadialGradient",
                                        false);
}

Future<void> Render::CreateRadialGradient(const Picture& picture,
                                          const PointFix& inner,
                                          const PointFix& outer,
                                          const Fixed& inner_radius,
                                          const Fixed& outer_radius,
                                          const std::vector<Fixed>& stops,
                                          const std::vector<Color>& colors) {
  return Render::CreateRadialGradient(Render::CreateRadialGradientRequest{
      picture, inner, outer, inner_radius, outer_radius, stops, colors});
}

Future<void> Render::CreateConicalGradient(
    const Render::CreateConicalGradientRequest& request) {
  if (!connection_->Ready() || !present())
    return {};

  WriteBuffer buf;

  auto& picture = request.picture;
  auto& center = request.center;
  auto& angle = request.angle;
  uint32_t num_stops{};
  auto& stops = request.stops;
  size_t stops_len = stops.size();
  auto& colors = request.colors;
  size_t colors_len = colors.size();

  // major_opcode
  uint8_t major_opcode = info_.major_opcode;
  buf.Write(&major_opcode);

  // minor_opcode
  uint8_t minor_opcode = 36;
  buf.Write(&minor_opcode);

  // length
  // Caller fills in length for writes.
  Pad(&buf, sizeof(uint16_t));

  // picture
  buf.Write(&picture);

  // center
  {
    auto& x = center.x;
    auto& y = center.y;

    // x
    buf.Write(&x);

    // y
    buf.Write(&y);
  }

  // angle
  buf.Write(&angle);

  // num_stops
  num_stops = stops.size();
  buf.Write(&num_stops);

  // stops
  DCHECK_EQ(static_cast<size_t>(num_stops), stops.size());
  for (auto& stops_elem : stops) {
    // stops_elem
    buf.Write(&stops_elem);
  }

  // colors
  DCHECK_EQ(static_cast<size_t>(num_stops), colors.size());
  for (auto& colors_elem : colors) {
    // colors_elem
    {
      auto& red = colors_elem.red;
      auto& green = colors_elem.green;
      auto& blue = colors_elem.blue;
      auto& alpha = colors_elem.alpha;

      // red
      buf.Write(&red);

      // green
      buf.Write(&green);

      // blue
      buf.Write(&blue);

      // alpha
      buf.Write(&alpha);
    }
  }

  Align(&buf, 4);

  return connection_->SendRequest<void>(&buf, "Render::CreateConicalGradient",
                                        false);
}

Future<void> Render::CreateConicalGradient(const Picture& picture,
                                           const PointFix& center,
                                           const Fixed& angle,
                                           const std::vector<Fixed>& stops,
                                           const std::vector<Color>& colors) {
  return Render::CreateConicalGradient(Render::CreateConicalGradientRequest{
      picture, center, angle, stops, colors});
}

}  // namespace x11
