diff --git a/shiny/driver/x11driver/buffer.go b/shiny/driver/x11driver/buffer.go
index c49cbfd..c2ae264 100644
--- a/shiny/driver/x11driver/buffer.go
+++ b/shiny/driver/x11driver/buffer.go
@@ -12,10 +12,10 @@
 	"sync"
 	"unsafe"
 
-	"golang.org/x/exp/shiny/internal/xgb"
-	"golang.org/x/exp/shiny/internal/xgb/render"
-	"golang.org/x/exp/shiny/internal/xgb/shm"
-	"golang.org/x/exp/shiny/internal/xgb/xproto"
+	"github.com/jezek/xgb"
+	"github.com/jezek/xgb/render"
+	"github.com/jezek/xgb/shm"
+	"github.com/jezek/xgb/xproto"
 
 	"golang.org/x/exp/shiny/driver/internal/swizzle"
 )
diff --git a/shiny/driver/x11driver/buffer_fallback.go b/shiny/driver/x11driver/buffer_fallback.go
index e8545f1..fbf9483 100644
--- a/shiny/driver/x11driver/buffer_fallback.go
+++ b/shiny/driver/x11driver/buffer_fallback.go
@@ -8,8 +8,8 @@
 	"image"
 	"sync"
 
-	"golang.org/x/exp/shiny/internal/xgb"
-	"golang.org/x/exp/shiny/internal/xgb/xproto"
+	"github.com/jezek/xgb"
+	"github.com/jezek/xgb/xproto"
 
 	"golang.org/x/exp/shiny/driver/internal/swizzle"
 )
diff --git a/shiny/driver/x11driver/screen.go b/shiny/driver/x11driver/screen.go
index e62d86a..c0dc9a4 100644
--- a/shiny/driver/x11driver/screen.go
+++ b/shiny/driver/x11driver/screen.go
@@ -12,10 +12,10 @@
 	"log"
 	"sync"
 
-	"golang.org/x/exp/shiny/internal/xgb"
-	"golang.org/x/exp/shiny/internal/xgb/render"
-	"golang.org/x/exp/shiny/internal/xgb/shm"
-	"golang.org/x/exp/shiny/internal/xgb/xproto"
+	"github.com/jezek/xgb"
+	"github.com/jezek/xgb/render"
+	"github.com/jezek/xgb/shm"
+	"github.com/jezek/xgb/xproto"
 
 	"golang.org/x/exp/shiny/driver/internal/x11key"
 	"golang.org/x/exp/shiny/screen"
diff --git a/shiny/driver/x11driver/texture.go b/shiny/driver/x11driver/texture.go
index 96212b3..ac4cd01 100644
--- a/shiny/driver/x11driver/texture.go
+++ b/shiny/driver/x11driver/texture.go
@@ -11,8 +11,8 @@
 	"math"
 	"sync"
 
-	"golang.org/x/exp/shiny/internal/xgb/render"
-	"golang.org/x/exp/shiny/internal/xgb/xproto"
+	"github.com/jezek/xgb/render"
+	"github.com/jezek/xgb/xproto"
 
 	"golang.org/x/exp/shiny/screen"
 	"golang.org/x/image/math/f64"
diff --git a/shiny/driver/x11driver/window.go b/shiny/driver/x11driver/window.go
index 12ac215..68b6d99 100644
--- a/shiny/driver/x11driver/window.go
+++ b/shiny/driver/x11driver/window.go
@@ -12,9 +12,9 @@
 	"image/draw"
 	"sync"
 
-	"golang.org/x/exp/shiny/internal/xgb"
-	"golang.org/x/exp/shiny/internal/xgb/render"
-	"golang.org/x/exp/shiny/internal/xgb/xproto"
+	"github.com/jezek/xgb"
+	"github.com/jezek/xgb/render"
+	"github.com/jezek/xgb/xproto"
 
 	"golang.org/x/exp/shiny/driver/internal/drawer"
 	"golang.org/x/exp/shiny/driver/internal/event"
diff --git a/shiny/driver/x11driver/x11driver.go b/shiny/driver/x11driver/x11driver.go
index e8c60a6..f0f6d48 100644
--- a/shiny/driver/x11driver/x11driver.go
+++ b/shiny/driver/x11driver/x11driver.go
@@ -13,9 +13,9 @@
 import (
 	"fmt"
 
-	"golang.org/x/exp/shiny/internal/xgb"
-	"golang.org/x/exp/shiny/internal/xgb/render"
-	"golang.org/x/exp/shiny/internal/xgb/shm"
+	"github.com/jezek/xgb"
+	"github.com/jezek/xgb/render"
+	"github.com/jezek/xgb/shm"
 
 	"golang.org/x/exp/shiny/driver/internal/errscreen"
 	"golang.org/x/exp/shiny/screen"
diff --git a/shiny/go.mod b/shiny/go.mod
index ae1f22c..1907acd 100644
--- a/shiny/go.mod
+++ b/shiny/go.mod
@@ -5,6 +5,7 @@
 require (
 	dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037
 	github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4
+	github.com/jezek/xgb v1.0.0
 	golang.org/x/image v0.0.0-20190802002840-cff245a6509b
 	golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f
 	golang.org/x/sys v0.0.0-20211019181941-9d821ace8654
diff --git a/shiny/go.sum b/shiny/go.sum
index 3139081..e82b1bf 100644
--- a/shiny/go.sum
+++ b/shiny/go.sum
@@ -3,6 +3,8 @@
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/jezek/xgb v1.0.0 h1:s2rRzAV8KQRlpsYA7Uyxoidv1nodMF0m6dIG6FhhVLQ=
+github.com/jezek/xgb v1.0.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
diff --git a/shiny/internal/xgb/AUTHORS b/shiny/internal/xgb/AUTHORS
deleted file mode 100644
index 08fc0cd..0000000
--- a/shiny/internal/xgb/AUTHORS
+++ /dev/null
@@ -1,18 +0,0 @@
-Andrew Gallant is the maintainer of this fork. What follows is the original
-list of authors for the x-go-binding.
-
-# This is the official list of XGB authors for copyright purposes.
-# This file is distinct from the CONTRIBUTORS files.
-# See the latter for an explanation.
-
-# Names should be added to this file as
-#	Name or Organization <email address>
-# The email address is not required for organizations.
-
-# Please keep the list sorted.
-
-Anthony Martin <ality@pbrane.org>
-Firmansyah Adiputra <frm.adiputra@gmail.com>
-Google Inc.
-Scott Lawrence <bytbox@gmail.com>
-Tor Andersson <tor.andersson@gmail.com>
diff --git a/shiny/internal/xgb/CONTRIBUTORS b/shiny/internal/xgb/CONTRIBUTORS
deleted file mode 100644
index 46dc4b0..0000000
--- a/shiny/internal/xgb/CONTRIBUTORS
+++ /dev/null
@@ -1,39 +0,0 @@
-Andrew Gallant is the maintainer of this fork. What follows is the original
-list of contributors for the x-go-binding.
-
-# This is the official list of people who can contribute
-# (and typically have contributed) code to the XGB repository.
-# The AUTHORS file lists the copyright holders; this file
-# lists people.  For example, Google employees are listed here
-# but not in AUTHORS, because Google holds the copyright.
-#
-# The submission process automatically checks to make sure
-# that people submitting code are listed in this file (by email address).
-#
-# Names should be added to this file only after verifying that
-# the individual or the individual's organization has agreed to
-# the appropriate Contributor License Agreement, found here:
-#
-#     http://code.google.com/legal/individual-cla-v1.0.html
-#     http://code.google.com/legal/corporate-cla-v1.0.html
-#
-# The agreement for individuals can be filled out on the web.
-#
-# When adding J Random Contributor's name to this file,
-# either J's name or J's organization's name should be
-# added to the AUTHORS file, depending on whether the
-# individual or corporate CLA was used.
-
-# Names should be added to this file like so:
-#     Name <email address>
-
-# Please keep the list sorted.
-
-Anthony Martin <ality@pbrane.org>
-Firmansyah Adiputra <frm.adiputra@gmail.com>
-Ian Lance Taylor <iant@golang.org>
-Nigel Tao <nigeltao@golang.org>
-Robert Griesemer <gri@golang.org>
-Russ Cox <rsc@golang.org>
-Scott Lawrence <bytbox@gmail.com>
-Tor Andersson <tor.andersson@gmail.com>
diff --git a/shiny/internal/xgb/LICENSE b/shiny/internal/xgb/LICENSE
deleted file mode 100644
index d99cd90..0000000
--- a/shiny/internal/xgb/LICENSE
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2009 The XGB Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Subject to the terms and conditions of this License, Google hereby
-// grants to You a perpetual, worldwide, non-exclusive, no-charge,
-// royalty-free, irrevocable (except as stated in this section) patent
-// license to make, have made, use, offer to sell, sell, import, and
-// otherwise transfer this implementation of XGB, where such license
-// applies only to those patent claims licensable by Google that are
-// necessarily infringed by use of this implementation of XGB. If You
-// institute patent litigation against any entity (including a
-// cross-claim or counterclaim in a lawsuit) alleging that this
-// implementation of XGB or a Contribution incorporated within this
-// implementation of XGB constitutes direct or contributory patent
-// infringement, then any patent licenses granted to You under this
-// License for this implementation of XGB shall terminate as of the date
-// such litigation is filed.
diff --git a/shiny/internal/xgb/README b/shiny/internal/xgb/README
deleted file mode 100644
index c96a5fb..0000000
--- a/shiny/internal/xgb/README
+++ /dev/null
@@ -1,54 +0,0 @@
-XGB is the X Go Binding, which is a low-level API to communicate with the
-core X protocol and many of the X extensions. It is closely modeled after
-XCB and xpyb.
-
-It is thread safe and gets immediate improvement from parallelism when
-GOMAXPROCS > 1. (See the benchmarks in xproto/xproto_test.go for evidence.)
-
-Please see doc.go for more info.
-
-Note that unless you know you need XGB, you can probably make your life
-easier by using a slightly higher level library: xgbutil.
-
-Quick Usage
-===========
-go get github.com/BurntSushi/xgb
-go run go/path/src/github.com/BurntSushi/xgb/examples/create-window/main.go
-
-BurntSushi's Fork
-=================
-I've forked the XGB repository from Google Code due to inactivty upstream.
-
-Godoc documentation can be found here:
-http://godoc.burntsushi.net/pkg/github.com/BurntSushi/xgb/
-
-Much of the code has been rewritten in an effort to support thread safety
-and multiple extensions. Namely, go_client.py has been thrown away in favor
-of an xgbgen package.
-
-The biggest parts that *haven't* been rewritten by me are the connection and
-authentication handshakes. They're inherently messy, and there's really no
-reason to re-work them. The rest of XGB has been completely rewritten.
-
-I like to release my code under the WTFPL, but since I'm starting with someone
-else's work, I'm leaving the original license/contributor/author information
-in tact.
-
-I suppose I can legitimately release xgbgen under the WTFPL. To be fair, it is
-at least as complex as XGB itself. *sigh*
-
-What follows is the original README:
-
-XGB README
-==========
-XGB is the X protocol Go language Binding.
-
-It is the Go equivalent of XCB, the X protocol C-language Binding
-(http://xcb.freedesktop.org/).
-
-Unless otherwise noted, the XGB source files are distributed
-under the BSD-style license found in the LICENSE file.
-
-Contributions should follow the same procedure as for the Go project:
-http://golang.org/doc/contribute.html
-
diff --git a/shiny/internal/xgb/README.vendor b/shiny/internal/xgb/README.vendor
deleted file mode 100644
index 13a13a5..0000000
--- a/shiny/internal/xgb/README.vendor
+++ /dev/null
@@ -1,21 +0,0 @@
-This is a fork-and-subset of github.com/BurntSushi/xgb at git revision
-3ac861bb (2015-04-26), plus additional manual patches (see below).
-
-The subset consists of these directories:
-github.com/BurntSushi/xgb
-github.com/BurntSushi/xgb/render
-github.com/BurntSushi/xgb/shm
-github.com/BurntSushi/xgb/xproto
-
-Other directories in the original github.com/BurntSushi/xgb repository are not
-used by golang.org/x/exp/shiny, and were not copied to the vendor tree here:
-github.com/BurntSushi/xgb/bigreq
-github.com/BurntSushi/xgb/composite
-etc
-github.com/BurntSushi/xgb/xvmc
-
-Additional manual patches:
-https://go-review.googlesource.com/#/c/12765/
-edits:
-xproto/xproto_test.go
-to skip tests that fail on Darwin.
diff --git a/shiny/internal/xgb/auth.go b/shiny/internal/xgb/auth.go
deleted file mode 100644
index a6fad90..0000000
--- a/shiny/internal/xgb/auth.go
+++ /dev/null
@@ -1,105 +0,0 @@
-package xgb
-
-/*
-auth.go contains functions to facilitate the parsing of .Xauthority files.
-
-It is largely unmodified from the original XGB package that I forked.
-*/
-
-import (
-	"encoding/binary"
-	"errors"
-	"io"
-	"os"
-)
-
-// readAuthority reads the X authority file for the DISPLAY.
-// If hostname == "" or hostname == "localhost",
-// then use the system's hostname (as returned by os.Hostname) instead.
-func readAuthority(hostname, display string) (
-	name string, data []byte, err error) {
-
-	// b is a scratch buffer to use and should be at least 256 bytes long
-	// (i.e. it should be able to hold a hostname).
-	b := make([]byte, 256)
-
-	// As per /usr/include/X11/Xauth.h.
-	const familyLocal = 256
-
-	if len(hostname) == 0 || hostname == "localhost" {
-		hostname, err = os.Hostname()
-		if err != nil {
-			return "", nil, err
-		}
-	}
-
-	fname := os.Getenv("XAUTHORITY")
-	if len(fname) == 0 {
-		home := os.Getenv("HOME")
-		if len(home) == 0 {
-			err = errors.New("Xauthority not found: $XAUTHORITY, $HOME not set")
-			return "", nil, err
-		}
-		fname = home + "/.Xauthority"
-	}
-
-	r, err := os.Open(fname)
-	if err != nil {
-		return "", nil, err
-	}
-	defer r.Close()
-
-	for {
-		var family uint16
-		if err := binary.Read(r, binary.BigEndian, &family); err != nil {
-			return "", nil, err
-		}
-
-		addr, err := getString(r, b)
-		if err != nil {
-			return "", nil, err
-		}
-
-		disp, err := getString(r, b)
-		if err != nil {
-			return "", nil, err
-		}
-
-		name0, err := getString(r, b)
-		if err != nil {
-			return "", nil, err
-		}
-
-		data0, err := getBytes(r, b)
-		if err != nil {
-			return "", nil, err
-		}
-
-		if family == familyLocal && addr == hostname && disp == display {
-			return name0, data0, nil
-		}
-	}
-	panic("unreachable")
-}
-
-func getBytes(r io.Reader, b []byte) ([]byte, error) {
-	var n uint16
-	if err := binary.Read(r, binary.BigEndian, &n); err != nil {
-		return nil, err
-	} else if n > uint16(len(b)) {
-		return nil, errors.New("bytes too long for buffer")
-	}
-
-	if _, err := io.ReadFull(r, b[0:n]); err != nil {
-		return nil, err
-	}
-	return b[0:n], nil
-}
-
-func getString(r io.Reader, b []byte) (string, error) {
-	b, err := getBytes(r, b)
-	if err != nil {
-		return "", err
-	}
-	return string(b), nil
-}
diff --git a/shiny/internal/xgb/conn.go b/shiny/internal/xgb/conn.go
deleted file mode 100644
index 1b7d838..0000000
--- a/shiny/internal/xgb/conn.go
+++ /dev/null
@@ -1,185 +0,0 @@
-package xgb
-
-/*
-conn.go contains a couple of functions that do some real dirty work related
-to the initial connection handshake with X.
-
-This code is largely unmodified from the original XGB package that I forked.
-*/
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"net"
-	"os"
-	"strconv"
-	"strings"
-)
-
-// connect connects to the X server given in the 'display' string,
-// and does all the necessary setup handshaking.
-// If 'display' is empty it will be taken from os.Getenv("DISPLAY").
-// Note that you should read and understand the "Connection Setup" of the
-// X Protocol Reference Manual before changing this function:
-// http://goo.gl/4zGQg
-func (c *Conn) connect(display string) error {
-	err := c.dial(display)
-	if err != nil {
-		return err
-	}
-
-	return c.postConnect()
-}
-
-// connect init from to the net.Conn,
-func (c *Conn) connectNet(netConn net.Conn) error {
-	c.conn = netConn
-	return c.postConnect()
-}
-
-// do the postConnect action after Conn get it's underly net.Conn
-func (c *Conn) postConnect() error {
-	// Get authentication data
-	authName, authData, err := readAuthority(c.host, c.display)
-	noauth := false
-	if err != nil {
-		Logger.Printf("Could not get authority info: %v", err)
-		Logger.Println("Trying connection without authority info...")
-		authName = ""
-		authData = []byte{}
-		noauth = true
-	}
-
-	// Assume that the authentication protocol is "MIT-MAGIC-COOKIE-1".
-	if !noauth && (authName != "MIT-MAGIC-COOKIE-1" || len(authData) != 16) {
-		return errors.New("unsupported auth protocol " + authName)
-	}
-
-	buf := make([]byte, 12+Pad(len(authName))+Pad(len(authData)))
-	buf[0] = 0x6c
-	buf[1] = 0
-	Put16(buf[2:], 11)
-	Put16(buf[4:], 0)
-	Put16(buf[6:], uint16(len(authName)))
-	Put16(buf[8:], uint16(len(authData)))
-	Put16(buf[10:], 0)
-	copy(buf[12:], []byte(authName))
-	copy(buf[12+Pad(len(authName)):], authData)
-	if _, err = c.conn.Write(buf); err != nil {
-		return err
-	}
-
-	head := make([]byte, 8)
-	if _, err = io.ReadFull(c.conn, head[0:8]); err != nil {
-		return err
-	}
-	code := head[0]
-	reasonLen := head[1]
-	major := Get16(head[2:])
-	minor := Get16(head[4:])
-	dataLen := Get16(head[6:])
-
-	if major != 11 || minor != 0 {
-		return fmt.Errorf("x protocol version mismatch: %d.%d", major, minor)
-	}
-
-	buf = make([]byte, int(dataLen)*4+8, int(dataLen)*4+8)
-	copy(buf, head)
-	if _, err = io.ReadFull(c.conn, buf[8:]); err != nil {
-		return err
-	}
-
-	if code == 0 {
-		reason := buf[8 : 8+reasonLen]
-		return fmt.Errorf("x protocol authentication refused: %s",
-			string(reason))
-	}
-
-	// Unfortunately, it isn't really feasible to read the setup bytes here,
-	// since the code to do so is in a different package.
-	// Users must call 'xproto.Setup(X)' to get the setup info.
-	c.SetupBytes = buf
-
-	// But also read stuff that we *need* to get started.
-	c.setupResourceIdBase = Get32(buf[12:])
-	c.setupResourceIdMask = Get32(buf[16:])
-
-	return nil
-}
-
-// dial initializes the actual net connection with X.
-func (c *Conn) dial(display string) error {
-	if len(display) == 0 {
-		display = os.Getenv("DISPLAY")
-	}
-
-	display0 := display
-	if len(display) == 0 {
-		return errors.New("empty display string")
-	}
-
-	colonIdx := strings.LastIndex(display, ":")
-	if colonIdx < 0 {
-		return errors.New("bad display string: " + display0)
-	}
-
-	var protocol, socket string
-
-	if display[0] == '/' {
-		socket = display[0:colonIdx]
-	} else {
-		slashIdx := strings.LastIndex(display, "/")
-		if slashIdx >= 0 {
-			protocol = display[0:slashIdx]
-			c.host = display[slashIdx+1 : colonIdx]
-		} else {
-			c.host = display[0:colonIdx]
-		}
-	}
-
-	display = display[colonIdx+1 : len(display)]
-	if len(display) == 0 {
-		return errors.New("bad display string: " + display0)
-	}
-
-	var scr string
-	dotIdx := strings.LastIndex(display, ".")
-	if dotIdx < 0 {
-		c.display = display[0:]
-	} else {
-		c.display = display[0:dotIdx]
-		scr = display[dotIdx+1:]
-	}
-
-	var err error
-	c.DisplayNumber, err = strconv.Atoi(c.display)
-	if err != nil || c.DisplayNumber < 0 {
-		return errors.New("bad display string: " + display0)
-	}
-
-	if len(scr) != 0 {
-		c.DefaultScreen, err = strconv.Atoi(scr)
-		if err != nil {
-			return errors.New("bad display string: " + display0)
-		}
-	}
-
-	// Connect to server
-	if len(socket) != 0 {
-		c.conn, err = net.Dial("unix", socket+":"+c.display)
-	} else if len(c.host) != 0 {
-		if protocol == "" {
-			protocol = "tcp"
-		}
-		c.conn, err = net.Dial(protocol,
-			c.host+":"+strconv.Itoa(6000+c.DisplayNumber))
-	} else {
-		c.conn, err = net.Dial("unix", "/tmp/.X11-unix/X"+c.display)
-	}
-
-	if err != nil {
-		return errors.New("cannot connect to " + display0 + ": " + err.Error())
-	}
-	return nil
-}
diff --git a/shiny/internal/xgb/cookie.go b/shiny/internal/xgb/cookie.go
deleted file mode 100644
index d5cdb29..0000000
--- a/shiny/internal/xgb/cookie.go
+++ /dev/null
@@ -1,165 +0,0 @@
-package xgb
-
-import (
-	"errors"
-)
-
-// Cookie is the internal representation of a cookie, where one is generated
-// for *every* request sent by XGB.
-// 'cookie' is most frequently used by embedding it into a more specific
-// kind of cookie, i.e., 'GetInputFocusCookie'.
-type Cookie struct {
-	conn      *Conn
-	Sequence  uint16
-	replyChan chan []byte
-	errorChan chan error
-	pingChan  chan bool
-}
-
-// NewCookie creates a new cookie with the correct channels initialized
-// depending upon the values of 'checked' and 'reply'. Together, there are
-// four different kinds of cookies. (See more detailed comments in the
-// function for more info on those.)
-// Note that a sequence number is not set until just before the request
-// corresponding to this cookie is sent over the wire.
-//
-// Unless you're building requests from bytes by hand, this method should
-// not be used.
-func (c *Conn) NewCookie(checked, reply bool) *Cookie {
-	cookie := &Cookie{
-		conn:      c,
-		Sequence:  0, // we add the sequence id just before sending a request
-		replyChan: nil,
-		errorChan: nil,
-		pingChan:  nil,
-	}
-
-	// There are four different kinds of cookies:
-	// Checked requests with replies get a reply channel and an error channel.
-	// Unchecked requests with replies get a reply channel and a ping channel.
-	// Checked requests w/o replies get a ping channel and an error channel.
-	// Unchecked requests w/o replies get no channels.
-	// The reply channel is used to send reply data.
-	// The error channel is used to send error data.
-	// The ping channel is used when one of the 'reply' or 'error' channels
-	// is missing but the other is present. The ping channel is way to force
-	// the blocking to stop and basically say "the error has been received
-	// in the main event loop" (when the ping channel is coupled with a reply
-	// channel) or "the request you made that has no reply was successful"
-	// (when the ping channel is coupled with an error channel).
-	if checked {
-		cookie.errorChan = make(chan error, 1)
-		if !reply {
-			cookie.pingChan = make(chan bool, 1)
-		}
-	}
-	if reply {
-		cookie.replyChan = make(chan []byte, 1)
-		if !checked {
-			cookie.pingChan = make(chan bool, 1)
-		}
-	}
-
-	return cookie
-}
-
-// Reply detects whether this is a checked or unchecked cookie, and calls
-// 'replyChecked' or 'replyUnchecked' appropriately.
-//
-// Unless you're building requests from bytes by hand, this method should
-// not be used.
-func (c Cookie) Reply() ([]byte, error) {
-	// checked
-	if c.errorChan != nil {
-		return c.replyChecked()
-	}
-	return c.replyUnchecked()
-}
-
-// replyChecked waits for a response on either the replyChan or errorChan
-// channels. If the former arrives, the bytes are returned with a nil error.
-// If the latter arrives, no bytes are returned (nil) and the error received
-// is returned.
-//
-// Unless you're building requests from bytes by hand, this method should
-// not be used.
-func (c Cookie) replyChecked() ([]byte, error) {
-	if c.replyChan == nil {
-		return nil, errors.New("Cannot call 'replyChecked' on a cookie that " +
-			"is not expecting a *reply* or an error.")
-	}
-	if c.errorChan == nil {
-		return nil, errors.New("Cannot call 'replyChecked' on a cookie that " +
-			"is not expecting a reply or an *error*.")
-	}
-
-	select {
-	case reply := <-c.replyChan:
-		return reply, nil
-	case err := <-c.errorChan:
-		return nil, err
-	}
-}
-
-// replyUnchecked waits for a response on either the replyChan or pingChan
-// channels. If the former arrives, the bytes are returned with a nil error.
-// If the latter arrives, no bytes are returned (nil) and a nil error
-// is returned. (In the latter case, the corresponding error can be retrieved
-// from (Wait|Poll)ForEvent asynchronously.)
-// In all honesty, you *probably* don't want to use this method.
-//
-// Unless you're building requests from bytes by hand, this method should
-// not be used.
-func (c Cookie) replyUnchecked() ([]byte, error) {
-	if c.replyChan == nil {
-		return nil, errors.New("Cannot call 'replyUnchecked' on a cookie " +
-			"that is not expecting a *reply*.")
-	}
-
-	select {
-	case reply := <-c.replyChan:
-		return reply, nil
-	case <-c.pingChan:
-		return nil, nil
-	}
-}
-
-// Check is used for checked requests that have no replies. It is a mechanism
-// by which to report "success" or "error" in a synchronous fashion. (Therefore,
-// unchecked requests without replies cannot use this method.)
-// If the request causes an error, it is sent to this cookie's errorChan.
-// If the request was successful, there is no response from the server.
-// Thus, pingChan is sent a value when the *next* reply is read.
-// If no more replies are being processed, we force a round trip request with
-// GetInputFocus.
-//
-// Unless you're building requests from bytes by hand, this method should
-// not be used.
-func (c Cookie) Check() error {
-	if c.replyChan != nil {
-		return errors.New("Cannot call 'Check' on a cookie that is " +
-			"expecting a *reply*. Use 'Reply' instead.")
-	}
-	if c.errorChan == nil {
-		return errors.New("Cannot call 'Check' on a cookie that is " +
-			"not expecting a possible *error*.")
-	}
-
-	// First do a quick non-blocking check to see if we've been pinged.
-	select {
-	case err := <-c.errorChan:
-		return err
-	case <-c.pingChan:
-		return nil
-	default:
-	}
-
-	// Now force a round trip and try again, but block this time.
-	c.conn.Sync()
-	select {
-	case err := <-c.errorChan:
-		return err
-	case <-c.pingChan:
-		return nil
-	}
-}
diff --git a/shiny/internal/xgb/doc.go b/shiny/internal/xgb/doc.go
deleted file mode 100644
index 64540e9..0000000
--- a/shiny/internal/xgb/doc.go
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-Package XGB provides the X Go Binding, which is a low-level API to communicate
-with the core X protocol and many of the X extensions.
-
-It is *very* closely modeled on XCB, so that experience with XCB (or xpyb) is
-easily translatable to XGB. That is, it uses the same cookie/reply model
-and is thread safe. There are otherwise no major differences (in the API).
-
-Most uses of XGB typically fall under the realm of window manager and GUI kit
-development, but other applications (like pagers, panels, tilers, etc.) may
-also require XGB. Moreover, it is a near certainty that if you need to work
-with X, xgbutil will be of great use to you as well:
-https://github.com/BurntSushi/xgbutil
-
-Example
-
-This is an extremely terse example that demonstrates how to connect to X,
-create a window, listen to StructureNotify events and Key{Press,Release}
-events, map the window, and print out all events received. An example with
-accompanying documentation can be found in examples/create-window.
-
-	package main
-
-	import (
-		"fmt"
-		"github.com/BurntSushi/xgb"
-		"github.com/BurntSushi/xgb/xproto"
-	)
-
-	func main() {
-		X, err := xgb.NewConn()
-		if err != nil {
-			fmt.Println(err)
-			return
-		}
-
-		wid, _ := xproto.NewWindowId(X)
-		screen := xproto.Setup(X).DefaultScreen(X)
-		xproto.CreateWindow(X, screen.RootDepth, wid, screen.Root,
-			0, 0, 500, 500, 0,
-			xproto.WindowClassInputOutput, screen.RootVisual,
-			xproto.CwBackPixel | xproto.CwEventMask,
-			[]uint32{ // values must be in the order defined by the protocol
-				0xffffffff,
-				xproto.EventMaskStructureNotify |
-				xproto.EventMaskKeyPress |
-				xproto.EventMaskKeyRelease})
-
-		xproto.MapWindow(X, wid)
-		for {
-			ev, xerr := X.WaitForEvent()
-			if ev == nil && xerr == nil {
-				fmt.Println("Both event and error are nil. Exiting...")
-				return
-			}
-
-			if ev != nil {
-				fmt.Printf("Event: %s\n", ev)
-			}
-			if xerr != nil {
-				fmt.Printf("Error: %s\n", xerr)
-			}
-		}
-	}
-
-Xinerama Example
-
-This is another small example that shows how to query Xinerama for geometry
-information of each active head. Accompanying documentation for this example
-can be found in examples/xinerama.
-
-	package main
-
-	import (
-		"fmt"
-		"log"
-		"github.com/BurntSushi/xgb"
-		"github.com/BurntSushi/xgb/xinerama"
-	)
-
-	func main() {
-		X, err := xgb.NewConn()
-		if err != nil {
-			log.Fatal(err)
-		}
-
-		// Initialize the Xinerama extension.
-		// The appropriate 'Init' function must be run for *every*
-		// extension before any of its requests can be used.
-		err = xinerama.Init(X)
-		if err != nil {
-			log.Fatal(err)
-		}
-
-		reply, err := xinerama.QueryScreens(X).Reply()
-		if err != nil {
-			log.Fatal(err)
-		}
-
-		fmt.Printf("Number of heads: %d\n", reply.Number)
-		for i, screen := range reply.ScreenInfo {
-			fmt.Printf("%d :: X: %d, Y: %d, Width: %d, Height: %d\n",
-				i, screen.XOrg, screen.YOrg, screen.Width, screen.Height)
-		}
-	}
-
-Parallelism
-
-XGB can benefit greatly from parallelism due to its concurrent design. For
-evidence of this claim, please see the benchmarks in xproto/xproto_test.go.
-
-Tests
-
-xproto/xproto_test.go contains a number of contrived tests that stress
-particular corners of XGB that I presume could be problem areas. Namely:
-requests with no replies, requests with replies, checked errors, unchecked
-errors, sequence number wrapping, cookie buffer flushing (i.e., forcing a round
-trip every N requests made that don't have a reply), getting/setting properties
-and creating a window and listening to StructureNotify events.
-
-Code Generator
-
-Both XCB and xpyb use the same Python module (xcbgen) for a code generator. XGB
-(before this fork) used the same code generator as well, but in my attempt to
-add support for more extensions, I found the code generator extremely difficult
-to work with. Therefore, I re-wrote the code generator in Go. It can be found
-in its own sub-package, xgbgen, of xgb. My design of xgbgen includes a rough
-consideration that it could be used for other languages.
-
-What works
-
-I am reasonably confident that the core X protocol is in full working form. I've
-also tested the Xinerama and RandR extensions sparingly. Many of the other
-existing extensions have Go source generated (and are compilable) and are
-included in this package, but I am currently unsure of their status. They
-*should* work.
-
-What does not work
-
-XKB is the only extension that intentionally does not work, although I suspect
-that GLX also does not work (however, there is Go source code for GLX that
-compiles, unlike XKB). I don't currently have any intention of getting XKB
-working, due to its complexity and my current mental incapacity to test it.
-
-*/
-package xgb
diff --git a/shiny/internal/xgb/help.go b/shiny/internal/xgb/help.go
deleted file mode 100644
index f692442..0000000
--- a/shiny/internal/xgb/help.go
+++ /dev/null
@@ -1,105 +0,0 @@
-package xgb
-
-/*
-help.go is meant to contain a rough hodge podge of functions that are mainly
-used in the auto generated code. Indeed, several functions here are simple
-wrappers so that the sub-packages don't need to be smart about which stdlib
-packages to import.
-
-Also, the 'Get..' and 'Put..' functions are used through the core xgb package
-too. (xgbutil uses them too.)
-*/
-
-import (
-	"fmt"
-	"strings"
-)
-
-// StringsJoin is an alias to strings.Join. It allows us to avoid having to
-// import 'strings' in each of the generated Go files.
-func StringsJoin(ss []string, sep string) string {
-	return strings.Join(ss, sep)
-}
-
-// Sprintf is so we don't need to import 'fmt' in the generated Go files.
-func Sprintf(format string, v ...interface{}) string {
-	return fmt.Sprintf(format, v...)
-}
-
-// Errorf is just a wrapper for fmt.Errorf. Exists for the same reason
-// that 'stringsJoin' and 'sprintf' exists.
-func Errorf(format string, v ...interface{}) error {
-	return fmt.Errorf(format, v...)
-}
-
-// Pad a length to align on 4 bytes.
-func Pad(n int) int {
-	return (n + 3) & ^3
-}
-
-// PopCount counts the number of bits set in a value list mask.
-func PopCount(mask0 int) int {
-	mask := uint32(mask0)
-	n := 0
-	for i := uint32(0); i < 32; i++ {
-		if mask&(1<<i) != 0 {
-			n++
-		}
-	}
-	return n
-}
-
-// Put16 takes a 16 bit integer and copies it into a byte slice.
-func Put16(buf []byte, v uint16) {
-	buf[0] = byte(v)
-	buf[1] = byte(v >> 8)
-}
-
-// Put32 takes a 32 bit integer and copies it into a byte slice.
-func Put32(buf []byte, v uint32) {
-	buf[0] = byte(v)
-	buf[1] = byte(v >> 8)
-	buf[2] = byte(v >> 16)
-	buf[3] = byte(v >> 24)
-}
-
-// Put64 takes a 64 bit integer and copies it into a byte slice.
-func Put64(buf []byte, v uint64) {
-	buf[0] = byte(v)
-	buf[1] = byte(v >> 8)
-	buf[2] = byte(v >> 16)
-	buf[3] = byte(v >> 24)
-	buf[4] = byte(v >> 32)
-	buf[5] = byte(v >> 40)
-	buf[6] = byte(v >> 48)
-	buf[7] = byte(v >> 56)
-}
-
-// Get16 constructs a 16 bit integer from the beginning of a byte slice.
-func Get16(buf []byte) uint16 {
-	v := uint16(buf[0])
-	v |= uint16(buf[1]) << 8
-	return v
-}
-
-// Get32 constructs a 32 bit integer from the beginning of a byte slice.
-func Get32(buf []byte) uint32 {
-	v := uint32(buf[0])
-	v |= uint32(buf[1]) << 8
-	v |= uint32(buf[2]) << 16
-	v |= uint32(buf[3]) << 24
-	return v
-}
-
-// Get64 constructs a 64 bit integer from the beginning of a byte slice.
-func Get64(buf []byte) uint64 {
-	v := uint64(buf[0])
-	v |= uint64(buf[1]) << 8
-	v |= uint64(buf[2]) << 16
-	v |= uint64(buf[3]) << 24
-	v |= uint64(buf[4]) << 32
-	v |= uint64(buf[5]) << 40
-	v |= uint64(buf[6]) << 48
-	v |= uint64(buf[7]) << 56
-	return v
-}
diff --git a/shiny/internal/xgb/render/render.go b/shiny/internal/xgb/render/render.go
deleted file mode 100644
index 0731c96..0000000
--- a/shiny/internal/xgb/render/render.go
+++ /dev/null
@@ -1,3864 +0,0 @@
-// Package render is the X client API for the RENDER extension.
-package render
-
-// This file is automatically generated from render.xml. Edit at your peril!
-
-import (
-	"golang.org/x/exp/shiny/internal/xgb"
-
-	"golang.org/x/exp/shiny/internal/xgb/xproto"
-)
-
-// Init must be called before using the RENDER extension.
-func Init(c *xgb.Conn) error {
-	reply, err := xproto.QueryExtension(c, 6, "RENDER").Reply()
-	switch {
-	case err != nil:
-		return err
-	case !reply.Present:
-		return xgb.Errorf("No extension named RENDER could be found on on the server.")
-	}
-
-	xgb.ExtLock.Lock()
-	c.Extensions["RENDER"] = reply.MajorOpcode
-	for evNum, fun := range xgb.NewExtEventFuncs["RENDER"] {
-		xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun
-	}
-	for errNum, fun := range xgb.NewExtErrorFuncs["RENDER"] {
-		xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun
-	}
-	xgb.ExtLock.Unlock()
-
-	return nil
-}
-
-func init() {
-	xgb.NewExtEventFuncs["RENDER"] = make(map[int]xgb.NewEventFun)
-	xgb.NewExtErrorFuncs["RENDER"] = make(map[int]xgb.NewErrorFun)
-}
-
-type Animcursorelt struct {
-	Cursor xproto.Cursor
-	Delay  uint32
-}
-
-// AnimcursoreltRead reads a byte slice into a Animcursorelt value.
-func AnimcursoreltRead(buf []byte, v *Animcursorelt) int {
-	b := 0
-
-	v.Cursor = xproto.Cursor(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Delay = xgb.Get32(buf[b:])
-	b += 4
-
-	return b
-}
-
-// AnimcursoreltReadList reads a byte slice into a list of Animcursorelt values.
-func AnimcursoreltReadList(buf []byte, dest []Animcursorelt) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Animcursorelt{}
-		b += AnimcursoreltRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Animcursorelt value to a byte slice.
-func (v Animcursorelt) Bytes() []byte {
-	buf := make([]byte, 8)
-	b := 0
-
-	xgb.Put32(buf[b:], uint32(v.Cursor))
-	b += 4
-
-	xgb.Put32(buf[b:], v.Delay)
-	b += 4
-
-	return buf[:b]
-}
-
-// AnimcursoreltListBytes writes a list of Animcursorelt values to a byte slice.
-func AnimcursoreltListBytes(buf []byte, list []Animcursorelt) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Color struct {
-	Red   uint16
-	Green uint16
-	Blue  uint16
-	Alpha uint16
-}
-
-// ColorRead reads a byte slice into a Color value.
-func ColorRead(buf []byte, v *Color) int {
-	b := 0
-
-	v.Red = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Green = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Blue = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Alpha = xgb.Get16(buf[b:])
-	b += 2
-
-	return b
-}
-
-// ColorReadList reads a byte slice into a list of Color values.
-func ColorReadList(buf []byte, dest []Color) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Color{}
-		b += ColorRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Color value to a byte slice.
-func (v Color) Bytes() []byte {
-	buf := make([]byte, 8)
-	b := 0
-
-	xgb.Put16(buf[b:], v.Red)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Green)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Blue)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Alpha)
-	b += 2
-
-	return buf[:b]
-}
-
-// ColorListBytes writes a list of Color values to a byte slice.
-func ColorListBytes(buf []byte, list []Color) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-const (
-	CpRepeat           = 1
-	CpAlphaMap         = 2
-	CpAlphaXOrigin     = 4
-	CpAlphaYOrigin     = 8
-	CpClipXOrigin      = 16
-	CpClipYOrigin      = 32
-	CpClipMask         = 64
-	CpGraphicsExposure = 128
-	CpSubwindowMode    = 256
-	CpPolyEdge         = 512
-	CpPolyMode         = 1024
-	CpDither           = 2048
-	CpComponentAlpha   = 4096
-)
-
-type Directformat struct {
-	RedShift   uint16
-	RedMask    uint16
-	GreenShift uint16
-	GreenMask  uint16
-	BlueShift  uint16
-	BlueMask   uint16
-	AlphaShift uint16
-	AlphaMask  uint16
-}
-
-// DirectformatRead reads a byte slice into a Directformat value.
-func DirectformatRead(buf []byte, v *Directformat) int {
-	b := 0
-
-	v.RedShift = xgb.Get16(buf[b:])
-	b += 2
-
-	v.RedMask = xgb.Get16(buf[b:])
-	b += 2
-
-	v.GreenShift = xgb.Get16(buf[b:])
-	b += 2
-
-	v.GreenMask = xgb.Get16(buf[b:])
-	b += 2
-
-	v.BlueShift = xgb.Get16(buf[b:])
-	b += 2
-
-	v.BlueMask = xgb.Get16(buf[b:])
-	b += 2
-
-	v.AlphaShift = xgb.Get16(buf[b:])
-	b += 2
-
-	v.AlphaMask = xgb.Get16(buf[b:])
-	b += 2
-
-	return b
-}
-
-// DirectformatReadList reads a byte slice into a list of Directformat values.
-func DirectformatReadList(buf []byte, dest []Directformat) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Directformat{}
-		b += DirectformatRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Directformat value to a byte slice.
-func (v Directformat) Bytes() []byte {
-	buf := make([]byte, 16)
-	b := 0
-
-	xgb.Put16(buf[b:], v.RedShift)
-	b += 2
-
-	xgb.Put16(buf[b:], v.RedMask)
-	b += 2
-
-	xgb.Put16(buf[b:], v.GreenShift)
-	b += 2
-
-	xgb.Put16(buf[b:], v.GreenMask)
-	b += 2
-
-	xgb.Put16(buf[b:], v.BlueShift)
-	b += 2
-
-	xgb.Put16(buf[b:], v.BlueMask)
-	b += 2
-
-	xgb.Put16(buf[b:], v.AlphaShift)
-	b += 2
-
-	xgb.Put16(buf[b:], v.AlphaMask)
-	b += 2
-
-	return buf[:b]
-}
-
-// DirectformatListBytes writes a list of Directformat values to a byte slice.
-func DirectformatListBytes(buf []byte, list []Directformat) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Fixed int32
-
-type Glyph uint32
-
-// BadGlyph is the error number for a BadGlyph.
-const BadGlyph = 4
-
-type GlyphError struct {
-	Sequence uint16
-	NiceName string
-}
-
-// GlyphErrorNew constructs a GlyphError value that implements xgb.Error from a byte slice.
-func GlyphErrorNew(buf []byte) xgb.Error {
-	v := GlyphError{}
-	v.NiceName = "Glyph"
-
-	b := 1 // skip error determinant
-	b += 1 // don't read error number
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadGlyph error.
-// This is mostly used internally.
-func (err GlyphError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadGlyph error. If no bad value exists, 0 is returned.
-func (err GlyphError) BadId() uint32 {
-	return 0
-}
-
-// Error returns a rudimentary string representation of the BadGlyph error.
-
-func (err GlyphError) Error() string {
-	fieldVals := make([]string, 0, 0)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	return "BadGlyph {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewExtErrorFuncs["RENDER"][4] = GlyphErrorNew
-}
-
-// BadGlyphSet is the error number for a BadGlyphSet.
-const BadGlyphSet = 3
-
-type GlyphSetError struct {
-	Sequence uint16
-	NiceName string
-}
-
-// GlyphSetErrorNew constructs a GlyphSetError value that implements xgb.Error from a byte slice.
-func GlyphSetErrorNew(buf []byte) xgb.Error {
-	v := GlyphSetError{}
-	v.NiceName = "GlyphSet"
-
-	b := 1 // skip error determinant
-	b += 1 // don't read error number
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadGlyphSet error.
-// This is mostly used internally.
-func (err GlyphSetError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadGlyphSet error. If no bad value exists, 0 is returned.
-func (err GlyphSetError) BadId() uint32 {
-	return 0
-}
-
-// Error returns a rudimentary string representation of the BadGlyphSet error.
-
-func (err GlyphSetError) Error() string {
-	fieldVals := make([]string, 0, 0)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	return "BadGlyphSet {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewExtErrorFuncs["RENDER"][3] = GlyphSetErrorNew
-}
-
-type Glyphinfo struct {
-	Width  uint16
-	Height uint16
-	X      int16
-	Y      int16
-	XOff   int16
-	YOff   int16
-}
-
-// GlyphinfoRead reads a byte slice into a Glyphinfo value.
-func GlyphinfoRead(buf []byte, v *Glyphinfo) int {
-	b := 0
-
-	v.Width = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Height = xgb.Get16(buf[b:])
-	b += 2
-
-	v.X = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.XOff = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.YOff = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	return b
-}
-
-// GlyphinfoReadList reads a byte slice into a list of Glyphinfo values.
-func GlyphinfoReadList(buf []byte, dest []Glyphinfo) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Glyphinfo{}
-		b += GlyphinfoRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Glyphinfo value to a byte slice.
-func (v Glyphinfo) Bytes() []byte {
-	buf := make([]byte, 12)
-	b := 0
-
-	xgb.Put16(buf[b:], v.Width)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Height)
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.XOff))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.YOff))
-	b += 2
-
-	return buf[:b]
-}
-
-// GlyphinfoListBytes writes a list of Glyphinfo values to a byte slice.
-func GlyphinfoListBytes(buf []byte, list []Glyphinfo) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Glyphset uint32
-
-func NewGlyphsetId(c *xgb.Conn) (Glyphset, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Glyphset(id), nil
-}
-
-type Indexvalue struct {
-	Pixel uint32
-	Red   uint16
-	Green uint16
-	Blue  uint16
-	Alpha uint16
-}
-
-// IndexvalueRead reads a byte slice into a Indexvalue value.
-func IndexvalueRead(buf []byte, v *Indexvalue) int {
-	b := 0
-
-	v.Pixel = xgb.Get32(buf[b:])
-	b += 4
-
-	v.Red = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Green = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Blue = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Alpha = xgb.Get16(buf[b:])
-	b += 2
-
-	return b
-}
-
-// IndexvalueReadList reads a byte slice into a list of Indexvalue values.
-func IndexvalueReadList(buf []byte, dest []Indexvalue) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Indexvalue{}
-		b += IndexvalueRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Indexvalue value to a byte slice.
-func (v Indexvalue) Bytes() []byte {
-	buf := make([]byte, 12)
-	b := 0
-
-	xgb.Put32(buf[b:], v.Pixel)
-	b += 4
-
-	xgb.Put16(buf[b:], v.Red)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Green)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Blue)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Alpha)
-	b += 2
-
-	return buf[:b]
-}
-
-// IndexvalueListBytes writes a list of Indexvalue values to a byte slice.
-func IndexvalueListBytes(buf []byte, list []Indexvalue) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Linefix struct {
-	P1 Pointfix
-	P2 Pointfix
-}
-
-// LinefixRead reads a byte slice into a Linefix value.
-func LinefixRead(buf []byte, v *Linefix) int {
-	b := 0
-
-	v.P1 = Pointfix{}
-	b += PointfixRead(buf[b:], &v.P1)
-
-	v.P2 = Pointfix{}
-	b += PointfixRead(buf[b:], &v.P2)
-
-	return b
-}
-
-// LinefixReadList reads a byte slice into a list of Linefix values.
-func LinefixReadList(buf []byte, dest []Linefix) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Linefix{}
-		b += LinefixRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Linefix value to a byte slice.
-func (v Linefix) Bytes() []byte {
-	buf := make([]byte, 16)
-	b := 0
-
-	{
-		structBytes := v.P1.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	{
-		structBytes := v.P2.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	return buf[:b]
-}
-
-// LinefixListBytes writes a list of Linefix values to a byte slice.
-func LinefixListBytes(buf []byte, list []Linefix) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// BadPictFormat is the error number for a BadPictFormat.
-const BadPictFormat = 0
-
-type PictFormatError struct {
-	Sequence uint16
-	NiceName string
-}
-
-// PictFormatErrorNew constructs a PictFormatError value that implements xgb.Error from a byte slice.
-func PictFormatErrorNew(buf []byte) xgb.Error {
-	v := PictFormatError{}
-	v.NiceName = "PictFormat"
-
-	b := 1 // skip error determinant
-	b += 1 // don't read error number
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadPictFormat error.
-// This is mostly used internally.
-func (err PictFormatError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadPictFormat error. If no bad value exists, 0 is returned.
-func (err PictFormatError) BadId() uint32 {
-	return 0
-}
-
-// Error returns a rudimentary string representation of the BadPictFormat error.
-
-func (err PictFormatError) Error() string {
-	fieldVals := make([]string, 0, 0)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	return "BadPictFormat {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewExtErrorFuncs["RENDER"][0] = PictFormatErrorNew
-}
-
-// BadPictOp is the error number for a BadPictOp.
-const BadPictOp = 2
-
-type PictOpError struct {
-	Sequence uint16
-	NiceName string
-}
-
-// PictOpErrorNew constructs a PictOpError value that implements xgb.Error from a byte slice.
-func PictOpErrorNew(buf []byte) xgb.Error {
-	v := PictOpError{}
-	v.NiceName = "PictOp"
-
-	b := 1 // skip error determinant
-	b += 1 // don't read error number
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadPictOp error.
-// This is mostly used internally.
-func (err PictOpError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadPictOp error. If no bad value exists, 0 is returned.
-func (err PictOpError) BadId() uint32 {
-	return 0
-}
-
-// Error returns a rudimentary string representation of the BadPictOp error.
-
-func (err PictOpError) Error() string {
-	fieldVals := make([]string, 0, 0)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	return "BadPictOp {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewExtErrorFuncs["RENDER"][2] = PictOpErrorNew
-}
-
-const (
-	PictOpClear               = 0
-	PictOpSrc                 = 1
-	PictOpDst                 = 2
-	PictOpOver                = 3
-	PictOpOverReverse         = 4
-	PictOpIn                  = 5
-	PictOpInReverse           = 6
-	PictOpOut                 = 7
-	PictOpOutReverse          = 8
-	PictOpAtop                = 9
-	PictOpAtopReverse         = 10
-	PictOpXor                 = 11
-	PictOpAdd                 = 12
-	PictOpSaturate            = 13
-	PictOpDisjointClear       = 16
-	PictOpDisjointSrc         = 17
-	PictOpDisjointDst         = 18
-	PictOpDisjointOver        = 19
-	PictOpDisjointOverReverse = 20
-	PictOpDisjointIn          = 21
-	PictOpDisjointInReverse   = 22
-	PictOpDisjointOut         = 23
-	PictOpDisjointOutReverse  = 24
-	PictOpDisjointAtop        = 25
-	PictOpDisjointAtopReverse = 26
-	PictOpDisjointXor         = 27
-	PictOpConjointClear       = 32
-	PictOpConjointSrc         = 33
-	PictOpConjointDst         = 34
-	PictOpConjointOver        = 35
-	PictOpConjointOverReverse = 36
-	PictOpConjointIn          = 37
-	PictOpConjointInReverse   = 38
-	PictOpConjointOut         = 39
-	PictOpConjointOutReverse  = 40
-	PictOpConjointAtop        = 41
-	PictOpConjointAtopReverse = 42
-	PictOpConjointXor         = 43
-	PictOpMultiply            = 48
-	PictOpScreen              = 49
-	PictOpOverlay             = 50
-	PictOpDarken              = 51
-	PictOpLighten             = 52
-	PictOpColorDodge          = 53
-	PictOpColorBurn           = 54
-	PictOpHardLight           = 55
-	PictOpSoftLight           = 56
-	PictOpDifference          = 57
-	PictOpExclusion           = 58
-	PictOpHSLHue              = 59
-	PictOpHSLSaturation       = 60
-	PictOpHSLColor            = 61
-	PictOpHSLLuminosity       = 62
-)
-
-const (
-	PictTypeIndexed = 0
-	PictTypeDirect  = 1
-)
-
-type Pictdepth struct {
-	Depth byte
-	// padding: 1 bytes
-	NumVisuals uint16
-	// padding: 4 bytes
-	Visuals []Pictvisual // size: xgb.Pad((int(NumVisuals) * 8))
-}
-
-// PictdepthRead reads a byte slice into a Pictdepth value.
-func PictdepthRead(buf []byte, v *Pictdepth) int {
-	b := 0
-
-	v.Depth = buf[b]
-	b += 1
-
-	b += 1 // padding
-
-	v.NumVisuals = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 4 // padding
-
-	v.Visuals = make([]Pictvisual, v.NumVisuals)
-	b += PictvisualReadList(buf[b:], v.Visuals)
-
-	return b
-}
-
-// PictdepthReadList reads a byte slice into a list of Pictdepth values.
-func PictdepthReadList(buf []byte, dest []Pictdepth) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Pictdepth{}
-		b += PictdepthRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Pictdepth value to a byte slice.
-func (v Pictdepth) Bytes() []byte {
-	buf := make([]byte, (8 + xgb.Pad((int(v.NumVisuals) * 8))))
-	b := 0
-
-	buf[b] = v.Depth
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], v.NumVisuals)
-	b += 2
-
-	b += 4 // padding
-
-	b += PictvisualListBytes(buf[b:], v.Visuals)
-
-	return buf[:b]
-}
-
-// PictdepthListBytes writes a list of Pictdepth values to a byte slice.
-func PictdepthListBytes(buf []byte, list []Pictdepth) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// PictdepthListSize computes the size (bytes) of a list of Pictdepth values.
-func PictdepthListSize(list []Pictdepth) int {
-	size := 0
-	for _, item := range list {
-		size += (8 + xgb.Pad((int(item.NumVisuals) * 8)))
-	}
-	return size
-}
-
-type Pictformat uint32
-
-func NewPictformatId(c *xgb.Conn) (Pictformat, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Pictformat(id), nil
-}
-
-type Pictforminfo struct {
-	Id    Pictformat
-	Type  byte
-	Depth byte
-	// padding: 2 bytes
-	Direct   Directformat
-	Colormap xproto.Colormap
-}
-
-// PictforminfoRead reads a byte slice into a Pictforminfo value.
-func PictforminfoRead(buf []byte, v *Pictforminfo) int {
-	b := 0
-
-	v.Id = Pictformat(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Type = buf[b]
-	b += 1
-
-	v.Depth = buf[b]
-	b += 1
-
-	b += 2 // padding
-
-	v.Direct = Directformat{}
-	b += DirectformatRead(buf[b:], &v.Direct)
-
-	v.Colormap = xproto.Colormap(xgb.Get32(buf[b:]))
-	b += 4
-
-	return b
-}
-
-// PictforminfoReadList reads a byte slice into a list of Pictforminfo values.
-func PictforminfoReadList(buf []byte, dest []Pictforminfo) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Pictforminfo{}
-		b += PictforminfoRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Pictforminfo value to a byte slice.
-func (v Pictforminfo) Bytes() []byte {
-	buf := make([]byte, 28)
-	b := 0
-
-	xgb.Put32(buf[b:], uint32(v.Id))
-	b += 4
-
-	buf[b] = v.Type
-	b += 1
-
-	buf[b] = v.Depth
-	b += 1
-
-	b += 2 // padding
-
-	{
-		structBytes := v.Direct.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	xgb.Put32(buf[b:], uint32(v.Colormap))
-	b += 4
-
-	return buf[:b]
-}
-
-// PictforminfoListBytes writes a list of Pictforminfo values to a byte slice.
-func PictforminfoListBytes(buf []byte, list []Pictforminfo) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Pictscreen struct {
-	NumDepths uint32
-	Fallback  Pictformat
-	Depths    []Pictdepth // size: PictdepthListSize(Depths)
-}
-
-// PictscreenRead reads a byte slice into a Pictscreen value.
-func PictscreenRead(buf []byte, v *Pictscreen) int {
-	b := 0
-
-	v.NumDepths = xgb.Get32(buf[b:])
-	b += 4
-
-	v.Fallback = Pictformat(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Depths = make([]Pictdepth, v.NumDepths)
-	b += PictdepthReadList(buf[b:], v.Depths)
-
-	return b
-}
-
-// PictscreenReadList reads a byte slice into a list of Pictscreen values.
-func PictscreenReadList(buf []byte, dest []Pictscreen) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Pictscreen{}
-		b += PictscreenRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Pictscreen value to a byte slice.
-func (v Pictscreen) Bytes() []byte {
-	buf := make([]byte, (8 + PictdepthListSize(v.Depths)))
-	b := 0
-
-	xgb.Put32(buf[b:], v.NumDepths)
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Fallback))
-	b += 4
-
-	b += PictdepthListBytes(buf[b:], v.Depths)
-
-	return buf[:b]
-}
-
-// PictscreenListBytes writes a list of Pictscreen values to a byte slice.
-func PictscreenListBytes(buf []byte, list []Pictscreen) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// PictscreenListSize computes the size (bytes) of a list of Pictscreen values.
-func PictscreenListSize(list []Pictscreen) int {
-	size := 0
-	for _, item := range list {
-		size += (8 + PictdepthListSize(item.Depths))
-	}
-	return size
-}
-
-type Picture uint32
-
-func NewPictureId(c *xgb.Conn) (Picture, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Picture(id), nil
-}
-
-// BadPicture is the error number for a BadPicture.
-const BadPicture = 1
-
-type PictureError struct {
-	Sequence uint16
-	NiceName string
-}
-
-// PictureErrorNew constructs a PictureError value that implements xgb.Error from a byte slice.
-func PictureErrorNew(buf []byte) xgb.Error {
-	v := PictureError{}
-	v.NiceName = "Picture"
-
-	b := 1 // skip error determinant
-	b += 1 // don't read error number
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadPicture error.
-// This is mostly used internally.
-func (err PictureError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadPicture error. If no bad value exists, 0 is returned.
-func (err PictureError) BadId() uint32 {
-	return 0
-}
-
-// Error returns a rudimentary string representation of the BadPicture error.
-
-func (err PictureError) Error() string {
-	fieldVals := make([]string, 0, 0)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	return "BadPicture {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewExtErrorFuncs["RENDER"][1] = PictureErrorNew
-}
-
-const (
-	PictureNone = 0
-)
-
-type Pictvisual struct {
-	Visual xproto.Visualid
-	Format Pictformat
-}
-
-// PictvisualRead reads a byte slice into a Pictvisual value.
-func PictvisualRead(buf []byte, v *Pictvisual) int {
-	b := 0
-
-	v.Visual = xproto.Visualid(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Format = Pictformat(xgb.Get32(buf[b:]))
-	b += 4
-
-	return b
-}
-
-// PictvisualReadList reads a byte slice into a list of Pictvisual values.
-func PictvisualReadList(buf []byte, dest []Pictvisual) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Pictvisual{}
-		b += PictvisualRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Pictvisual value to a byte slice.
-func (v Pictvisual) Bytes() []byte {
-	buf := make([]byte, 8)
-	b := 0
-
-	xgb.Put32(buf[b:], uint32(v.Visual))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Format))
-	b += 4
-
-	return buf[:b]
-}
-
-// PictvisualListBytes writes a list of Pictvisual values to a byte slice.
-func PictvisualListBytes(buf []byte, list []Pictvisual) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Pointfix struct {
-	X Fixed
-	Y Fixed
-}
-
-// PointfixRead reads a byte slice into a Pointfix value.
-func PointfixRead(buf []byte, v *Pointfix) int {
-	b := 0
-
-	v.X = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Y = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	return b
-}
-
-// PointfixReadList reads a byte slice into a list of Pointfix values.
-func PointfixReadList(buf []byte, dest []Pointfix) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Pointfix{}
-		b += PointfixRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Pointfix value to a byte slice.
-func (v Pointfix) Bytes() []byte {
-	buf := make([]byte, 8)
-	b := 0
-
-	xgb.Put32(buf[b:], uint32(v.X))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Y))
-	b += 4
-
-	return buf[:b]
-}
-
-// PointfixListBytes writes a list of Pointfix values to a byte slice.
-func PointfixListBytes(buf []byte, list []Pointfix) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-const (
-	PolyEdgeSharp  = 0
-	PolyEdgeSmooth = 1
-)
-
-const (
-	PolyModePrecise   = 0
-	PolyModeImprecise = 1
-)
-
-const (
-	RepeatNone    = 0
-	RepeatNormal  = 1
-	RepeatPad     = 2
-	RepeatReflect = 3
-)
-
-type Spanfix struct {
-	L Fixed
-	R Fixed
-	Y Fixed
-}
-
-// SpanfixRead reads a byte slice into a Spanfix value.
-func SpanfixRead(buf []byte, v *Spanfix) int {
-	b := 0
-
-	v.L = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.R = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Y = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	return b
-}
-
-// SpanfixReadList reads a byte slice into a list of Spanfix values.
-func SpanfixReadList(buf []byte, dest []Spanfix) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Spanfix{}
-		b += SpanfixRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Spanfix value to a byte slice.
-func (v Spanfix) Bytes() []byte {
-	buf := make([]byte, 12)
-	b := 0
-
-	xgb.Put32(buf[b:], uint32(v.L))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.R))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Y))
-	b += 4
-
-	return buf[:b]
-}
-
-// SpanfixListBytes writes a list of Spanfix values to a byte slice.
-func SpanfixListBytes(buf []byte, list []Spanfix) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-const (
-	SubPixelUnknown       = 0
-	SubPixelHorizontalRGB = 1
-	SubPixelHorizontalBGR = 2
-	SubPixelVerticalRGB   = 3
-	SubPixelVerticalBGR   = 4
-	SubPixelNone          = 5
-)
-
-type Transform struct {
-	Matrix11 Fixed
-	Matrix12 Fixed
-	Matrix13 Fixed
-	Matrix21 Fixed
-	Matrix22 Fixed
-	Matrix23 Fixed
-	Matrix31 Fixed
-	Matrix32 Fixed
-	Matrix33 Fixed
-}
-
-// TransformRead reads a byte slice into a Transform value.
-func TransformRead(buf []byte, v *Transform) int {
-	b := 0
-
-	v.Matrix11 = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Matrix12 = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Matrix13 = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Matrix21 = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Matrix22 = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Matrix23 = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Matrix31 = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Matrix32 = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Matrix33 = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	return b
-}
-
-// TransformReadList reads a byte slice into a list of Transform values.
-func TransformReadList(buf []byte, dest []Transform) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Transform{}
-		b += TransformRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Transform value to a byte slice.
-func (v Transform) Bytes() []byte {
-	buf := make([]byte, 36)
-	b := 0
-
-	xgb.Put32(buf[b:], uint32(v.Matrix11))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Matrix12))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Matrix13))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Matrix21))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Matrix22))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Matrix23))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Matrix31))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Matrix32))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Matrix33))
-	b += 4
-
-	return buf[:b]
-}
-
-// TransformListBytes writes a list of Transform values to a byte slice.
-func TransformListBytes(buf []byte, list []Transform) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Trap struct {
-	Top Spanfix
-	Bot Spanfix
-}
-
-// TrapRead reads a byte slice into a Trap value.
-func TrapRead(buf []byte, v *Trap) int {
-	b := 0
-
-	v.Top = Spanfix{}
-	b += SpanfixRead(buf[b:], &v.Top)
-
-	v.Bot = Spanfix{}
-	b += SpanfixRead(buf[b:], &v.Bot)
-
-	return b
-}
-
-// TrapReadList reads a byte slice into a list of Trap values.
-func TrapReadList(buf []byte, dest []Trap) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Trap{}
-		b += TrapRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Trap value to a byte slice.
-func (v Trap) Bytes() []byte {
-	buf := make([]byte, 24)
-	b := 0
-
-	{
-		structBytes := v.Top.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	{
-		structBytes := v.Bot.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	return buf[:b]
-}
-
-// TrapListBytes writes a list of Trap values to a byte slice.
-func TrapListBytes(buf []byte, list []Trap) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Trapezoid struct {
-	Top    Fixed
-	Bottom Fixed
-	Left   Linefix
-	Right  Linefix
-}
-
-// TrapezoidRead reads a byte slice into a Trapezoid value.
-func TrapezoidRead(buf []byte, v *Trapezoid) int {
-	b := 0
-
-	v.Top = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Bottom = Fixed(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Left = Linefix{}
-	b += LinefixRead(buf[b:], &v.Left)
-
-	v.Right = Linefix{}
-	b += LinefixRead(buf[b:], &v.Right)
-
-	return b
-}
-
-// TrapezoidReadList reads a byte slice into a list of Trapezoid values.
-func TrapezoidReadList(buf []byte, dest []Trapezoid) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Trapezoid{}
-		b += TrapezoidRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Trapezoid value to a byte slice.
-func (v Trapezoid) Bytes() []byte {
-	buf := make([]byte, 40)
-	b := 0
-
-	xgb.Put32(buf[b:], uint32(v.Top))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Bottom))
-	b += 4
-
-	{
-		structBytes := v.Left.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	{
-		structBytes := v.Right.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	return buf[:b]
-}
-
-// TrapezoidListBytes writes a list of Trapezoid values to a byte slice.
-func TrapezoidListBytes(buf []byte, list []Trapezoid) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Triangle struct {
-	P1 Pointfix
-	P2 Pointfix
-	P3 Pointfix
-}
-
-// TriangleRead reads a byte slice into a Triangle value.
-func TriangleRead(buf []byte, v *Triangle) int {
-	b := 0
-
-	v.P1 = Pointfix{}
-	b += PointfixRead(buf[b:], &v.P1)
-
-	v.P2 = Pointfix{}
-	b += PointfixRead(buf[b:], &v.P2)
-
-	v.P3 = Pointfix{}
-	b += PointfixRead(buf[b:], &v.P3)
-
-	return b
-}
-
-// TriangleReadList reads a byte slice into a list of Triangle values.
-func TriangleReadList(buf []byte, dest []Triangle) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Triangle{}
-		b += TriangleRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Triangle value to a byte slice.
-func (v Triangle) Bytes() []byte {
-	buf := make([]byte, 24)
-	b := 0
-
-	{
-		structBytes := v.P1.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	{
-		structBytes := v.P2.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	{
-		structBytes := v.P3.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	return buf[:b]
-}
-
-// TriangleListBytes writes a list of Triangle values to a byte slice.
-func TriangleListBytes(buf []byte, list []Triangle) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// Skipping definition for base type 'Bool'
-
-// Skipping definition for base type 'Byte'
-
-// Skipping definition for base type 'Card8'
-
-// Skipping definition for base type 'Char'
-
-// Skipping definition for base type 'Void'
-
-// Skipping definition for base type 'Double'
-
-// Skipping definition for base type 'Float'
-
-// Skipping definition for base type 'Int16'
-
-// Skipping definition for base type 'Int32'
-
-// Skipping definition for base type 'Int8'
-
-// Skipping definition for base type 'Card16'
-
-// Skipping definition for base type 'Card32'
-
-// AddGlyphsCookie is a cookie used only for AddGlyphs requests.
-type AddGlyphsCookie struct {
-	*xgb.Cookie
-}
-
-// AddGlyphs sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func AddGlyphs(c *xgb.Conn, Glyphset Glyphset, GlyphsLen uint32, Glyphids []uint32, Glyphs []Glyphinfo, Data []byte) AddGlyphsCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'AddGlyphs' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(addGlyphsRequest(c, Glyphset, GlyphsLen, Glyphids, Glyphs, Data), cookie)
-	return AddGlyphsCookie{cookie}
-}
-
-// AddGlyphsChecked sends a checked request.
-// If an error occurs, it can be retrieved using AddGlyphsCookie.Check()
-func AddGlyphsChecked(c *xgb.Conn, Glyphset Glyphset, GlyphsLen uint32, Glyphids []uint32, Glyphs []Glyphinfo, Data []byte) AddGlyphsCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'AddGlyphs' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(addGlyphsRequest(c, Glyphset, GlyphsLen, Glyphids, Glyphs, Data), cookie)
-	return AddGlyphsCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook AddGlyphsCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for AddGlyphs
-// addGlyphsRequest writes a AddGlyphs request to a byte slice.
-func addGlyphsRequest(c *xgb.Conn, Glyphset Glyphset, GlyphsLen uint32, Glyphids []uint32, Glyphs []Glyphinfo, Data []byte) []byte {
-	size := xgb.Pad(((((12 + xgb.Pad((int(GlyphsLen) * 4))) + 4) + xgb.Pad((int(GlyphsLen) * 12))) + xgb.Pad((len(Data) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 20 // request opcode
-	b += 1
-
-	blen := b
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Glyphset))
-	b += 4
-
-	xgb.Put32(buf[b:], GlyphsLen)
-	b += 4
-
-	for i := 0; i < int(GlyphsLen); i++ {
-		xgb.Put32(buf[b:], Glyphids[i])
-		b += 4
-	}
-
-	b = (b + 3) & ^3 // alignment gap
-
-	b += GlyphinfoListBytes(buf[b:], Glyphs)
-
-	copy(buf[b:], Data[:len(Data)])
-	b += int(len(Data))
-
-	b = xgb.Pad(b)
-	xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units
-	return buf[:b]
-}
-
-// AddTrapsCookie is a cookie used only for AddTraps requests.
-type AddTrapsCookie struct {
-	*xgb.Cookie
-}
-
-// AddTraps sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func AddTraps(c *xgb.Conn, Picture Picture, XOff int16, YOff int16, Traps []Trap) AddTrapsCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'AddTraps' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(addTrapsRequest(c, Picture, XOff, YOff, Traps), cookie)
-	return AddTrapsCookie{cookie}
-}
-
-// AddTrapsChecked sends a checked request.
-// If an error occurs, it can be retrieved using AddTrapsCookie.Check()
-func AddTrapsChecked(c *xgb.Conn, Picture Picture, XOff int16, YOff int16, Traps []Trap) AddTrapsCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'AddTraps' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(addTrapsRequest(c, Picture, XOff, YOff, Traps), cookie)
-	return AddTrapsCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook AddTrapsCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for AddTraps
-// addTrapsRequest writes a AddTraps request to a byte slice.
-func addTrapsRequest(c *xgb.Conn, Picture Picture, XOff int16, YOff int16, Traps []Trap) []byte {
-	size := xgb.Pad((12 + xgb.Pad((len(Traps) * 24))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 32 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Picture))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(XOff))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(YOff))
-	b += 2
-
-	b += TrapListBytes(buf[b:], Traps)
-
-	return buf
-}
-
-// ChangePictureCookie is a cookie used only for ChangePicture requests.
-type ChangePictureCookie struct {
-	*xgb.Cookie
-}
-
-// ChangePicture sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ChangePicture(c *xgb.Conn, Picture Picture, ValueMask uint32, ValueList []uint32) ChangePictureCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'ChangePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(changePictureRequest(c, Picture, ValueMask, ValueList), cookie)
-	return ChangePictureCookie{cookie}
-}
-
-// ChangePictureChecked sends a checked request.
-// If an error occurs, it can be retrieved using ChangePictureCookie.Check()
-func ChangePictureChecked(c *xgb.Conn, Picture Picture, ValueMask uint32, ValueList []uint32) ChangePictureCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'ChangePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(changePictureRequest(c, Picture, ValueMask, ValueList), cookie)
-	return ChangePictureCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ChangePictureCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ChangePicture
-// changePictureRequest writes a ChangePicture request to a byte slice.
-func changePictureRequest(c *xgb.Conn, Picture Picture, ValueMask uint32, ValueList []uint32) []byte {
-	size := xgb.Pad((8 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 5 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Picture))
-	b += 4
-
-	xgb.Put32(buf[b:], ValueMask)
-	b += 4
-	for i := 0; i < xgb.PopCount(int(ValueMask)); i++ {
-		xgb.Put32(buf[b:], ValueList[i])
-		b += 4
-	}
-	b = xgb.Pad(b)
-
-	return buf
-}
-
-// CompositeCookie is a cookie used only for Composite requests.
-type CompositeCookie struct {
-	*xgb.Cookie
-}
-
-// Composite sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func Composite(c *xgb.Conn, Op byte, Src Picture, Mask Picture, Dst Picture, SrcX int16, SrcY int16, MaskX int16, MaskY int16, DstX int16, DstY int16, Width uint16, Height uint16) CompositeCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'Composite' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(compositeRequest(c, Op, Src, Mask, Dst, SrcX, SrcY, MaskX, MaskY, DstX, DstY, Width, Height), cookie)
-	return CompositeCookie{cookie}
-}
-
-// CompositeChecked sends a checked request.
-// If an error occurs, it can be retrieved using CompositeCookie.Check()
-func CompositeChecked(c *xgb.Conn, Op byte, Src Picture, Mask Picture, Dst Picture, SrcX int16, SrcY int16, MaskX int16, MaskY int16, DstX int16, DstY int16, Width uint16, Height uint16) CompositeCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'Composite' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(compositeRequest(c, Op, Src, Mask, Dst, SrcX, SrcY, MaskX, MaskY, DstX, DstY, Width, Height), cookie)
-	return CompositeCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CompositeCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for Composite
-// compositeRequest writes a Composite request to a byte slice.
-func compositeRequest(c *xgb.Conn, Op byte, Src Picture, Mask Picture, Dst Picture, SrcX int16, SrcY int16, MaskX int16, MaskY int16, DstX int16, DstY int16, Width uint16, Height uint16) []byte {
-	size := 36
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 8 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = Op
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], uint32(Src))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Mask))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Dst))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(MaskX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(MaskY))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstY))
-	b += 2
-
-	xgb.Put16(buf[b:], Width)
-	b += 2
-
-	xgb.Put16(buf[b:], Height)
-	b += 2
-
-	return buf
-}
-
-// CompositeGlyphs16Cookie is a cookie used only for CompositeGlyphs16 requests.
-type CompositeGlyphs16Cookie struct {
-	*xgb.Cookie
-}
-
-// CompositeGlyphs16 sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CompositeGlyphs16(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs16Cookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CompositeGlyphs16' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(compositeGlyphs16Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie)
-	return CompositeGlyphs16Cookie{cookie}
-}
-
-// CompositeGlyphs16Checked sends a checked request.
-// If an error occurs, it can be retrieved using CompositeGlyphs16Cookie.Check()
-func CompositeGlyphs16Checked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs16Cookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CompositeGlyphs16' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(compositeGlyphs16Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie)
-	return CompositeGlyphs16Cookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CompositeGlyphs16Cookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CompositeGlyphs16
-// compositeGlyphs16Request writes a CompositeGlyphs16 request to a byte slice.
-func compositeGlyphs16Request(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) []byte {
-	size := xgb.Pad((28 + xgb.Pad((len(Glyphcmds) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 24 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = Op
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], uint32(Src))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Dst))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(MaskFormat))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Glyphset))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	copy(buf[b:], Glyphcmds[:len(Glyphcmds)])
-	b += int(len(Glyphcmds))
-
-	return buf
-}
-
-// CompositeGlyphs32Cookie is a cookie used only for CompositeGlyphs32 requests.
-type CompositeGlyphs32Cookie struct {
-	*xgb.Cookie
-}
-
-// CompositeGlyphs32 sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CompositeGlyphs32(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs32Cookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CompositeGlyphs32' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(compositeGlyphs32Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie)
-	return CompositeGlyphs32Cookie{cookie}
-}
-
-// CompositeGlyphs32Checked sends a checked request.
-// If an error occurs, it can be retrieved using CompositeGlyphs32Cookie.Check()
-func CompositeGlyphs32Checked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs32Cookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CompositeGlyphs32' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(compositeGlyphs32Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie)
-	return CompositeGlyphs32Cookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CompositeGlyphs32Cookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CompositeGlyphs32
-// compositeGlyphs32Request writes a CompositeGlyphs32 request to a byte slice.
-func compositeGlyphs32Request(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) []byte {
-	size := xgb.Pad((28 + xgb.Pad((len(Glyphcmds) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 25 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = Op
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], uint32(Src))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Dst))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(MaskFormat))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Glyphset))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	copy(buf[b:], Glyphcmds[:len(Glyphcmds)])
-	b += int(len(Glyphcmds))
-
-	return buf
-}
-
-// CompositeGlyphs8Cookie is a cookie used only for CompositeGlyphs8 requests.
-type CompositeGlyphs8Cookie struct {
-	*xgb.Cookie
-}
-
-// CompositeGlyphs8 sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CompositeGlyphs8(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs8Cookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CompositeGlyphs8' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(compositeGlyphs8Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie)
-	return CompositeGlyphs8Cookie{cookie}
-}
-
-// CompositeGlyphs8Checked sends a checked request.
-// If an error occurs, it can be retrieved using CompositeGlyphs8Cookie.Check()
-func CompositeGlyphs8Checked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) CompositeGlyphs8Cookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CompositeGlyphs8' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(compositeGlyphs8Request(c, Op, Src, Dst, MaskFormat, Glyphset, SrcX, SrcY, Glyphcmds), cookie)
-	return CompositeGlyphs8Cookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CompositeGlyphs8Cookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CompositeGlyphs8
-// compositeGlyphs8Request writes a CompositeGlyphs8 request to a byte slice.
-func compositeGlyphs8Request(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, Glyphset Glyphset, SrcX int16, SrcY int16, Glyphcmds []byte) []byte {
-	size := xgb.Pad((28 + xgb.Pad((len(Glyphcmds) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 23 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = Op
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], uint32(Src))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Dst))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(MaskFormat))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Glyphset))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	copy(buf[b:], Glyphcmds[:len(Glyphcmds)])
-	b += int(len(Glyphcmds))
-
-	return buf
-}
-
-// CreateAnimCursorCookie is a cookie used only for CreateAnimCursor requests.
-type CreateAnimCursorCookie struct {
-	*xgb.Cookie
-}
-
-// CreateAnimCursor sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateAnimCursor(c *xgb.Conn, Cid xproto.Cursor, Cursors []Animcursorelt) CreateAnimCursorCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateAnimCursor' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createAnimCursorRequest(c, Cid, Cursors), cookie)
-	return CreateAnimCursorCookie{cookie}
-}
-
-// CreateAnimCursorChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateAnimCursorCookie.Check()
-func CreateAnimCursorChecked(c *xgb.Conn, Cid xproto.Cursor, Cursors []Animcursorelt) CreateAnimCursorCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateAnimCursor' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createAnimCursorRequest(c, Cid, Cursors), cookie)
-	return CreateAnimCursorCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateAnimCursorCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateAnimCursor
-// createAnimCursorRequest writes a CreateAnimCursor request to a byte slice.
-func createAnimCursorRequest(c *xgb.Conn, Cid xproto.Cursor, Cursors []Animcursorelt) []byte {
-	size := xgb.Pad((8 + xgb.Pad((len(Cursors) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 31 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cid))
-	b += 4
-
-	b += AnimcursoreltListBytes(buf[b:], Cursors)
-
-	return buf
-}
-
-// CreateConicalGradientCookie is a cookie used only for CreateConicalGradient requests.
-type CreateConicalGradientCookie struct {
-	*xgb.Cookie
-}
-
-// CreateConicalGradient sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateConicalGradient(c *xgb.Conn, Picture Picture, Center Pointfix, Angle Fixed, NumStops uint32, Stops []Fixed, Colors []Color) CreateConicalGradientCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateConicalGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createConicalGradientRequest(c, Picture, Center, Angle, NumStops, Stops, Colors), cookie)
-	return CreateConicalGradientCookie{cookie}
-}
-
-// CreateConicalGradientChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateConicalGradientCookie.Check()
-func CreateConicalGradientChecked(c *xgb.Conn, Picture Picture, Center Pointfix, Angle Fixed, NumStops uint32, Stops []Fixed, Colors []Color) CreateConicalGradientCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateConicalGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createConicalGradientRequest(c, Picture, Center, Angle, NumStops, Stops, Colors), cookie)
-	return CreateConicalGradientCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateConicalGradientCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateConicalGradient
-// createConicalGradientRequest writes a CreateConicalGradient request to a byte slice.
-func createConicalGradientRequest(c *xgb.Conn, Picture Picture, Center Pointfix, Angle Fixed, NumStops uint32, Stops []Fixed, Colors []Color) []byte {
-	size := xgb.Pad((((24 + xgb.Pad((int(NumStops) * 4))) + 4) + xgb.Pad((int(NumStops) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 36 // request opcode
-	b += 1
-
-	blen := b
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Picture))
-	b += 4
-
-	{
-		structBytes := Center.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	xgb.Put32(buf[b:], uint32(Angle))
-	b += 4
-
-	xgb.Put32(buf[b:], NumStops)
-	b += 4
-
-	for i := 0; i < int(NumStops); i++ {
-		xgb.Put32(buf[b:], uint32(Stops[i]))
-		b += 4
-	}
-
-	b = (b + 3) & ^3 // alignment gap
-
-	b += ColorListBytes(buf[b:], Colors)
-
-	b = xgb.Pad(b)
-	xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units
-	return buf[:b]
-}
-
-// CreateCursorCookie is a cookie used only for CreateCursor requests.
-type CreateCursorCookie struct {
-	*xgb.Cookie
-}
-
-// CreateCursor sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateCursor(c *xgb.Conn, Cid xproto.Cursor, Source Picture, X uint16, Y uint16) CreateCursorCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateCursor' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createCursorRequest(c, Cid, Source, X, Y), cookie)
-	return CreateCursorCookie{cookie}
-}
-
-// CreateCursorChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateCursorCookie.Check()
-func CreateCursorChecked(c *xgb.Conn, Cid xproto.Cursor, Source Picture, X uint16, Y uint16) CreateCursorCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateCursor' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createCursorRequest(c, Cid, Source, X, Y), cookie)
-	return CreateCursorCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateCursorCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateCursor
-// createCursorRequest writes a CreateCursor request to a byte slice.
-func createCursorRequest(c *xgb.Conn, Cid xproto.Cursor, Source Picture, X uint16, Y uint16) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 27 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Source))
-	b += 4
-
-	xgb.Put16(buf[b:], X)
-	b += 2
-
-	xgb.Put16(buf[b:], Y)
-	b += 2
-
-	return buf
-}
-
-// CreateGlyphSetCookie is a cookie used only for CreateGlyphSet requests.
-type CreateGlyphSetCookie struct {
-	*xgb.Cookie
-}
-
-// CreateGlyphSet sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateGlyphSet(c *xgb.Conn, Gsid Glyphset, Format Pictformat) CreateGlyphSetCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createGlyphSetRequest(c, Gsid, Format), cookie)
-	return CreateGlyphSetCookie{cookie}
-}
-
-// CreateGlyphSetChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateGlyphSetCookie.Check()
-func CreateGlyphSetChecked(c *xgb.Conn, Gsid Glyphset, Format Pictformat) CreateGlyphSetCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createGlyphSetRequest(c, Gsid, Format), cookie)
-	return CreateGlyphSetCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateGlyphSetCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateGlyphSet
-// createGlyphSetRequest writes a CreateGlyphSet request to a byte slice.
-func createGlyphSetRequest(c *xgb.Conn, Gsid Glyphset, Format Pictformat) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 17 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Gsid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Format))
-	b += 4
-
-	return buf
-}
-
-// CreateLinearGradientCookie is a cookie used only for CreateLinearGradient requests.
-type CreateLinearGradientCookie struct {
-	*xgb.Cookie
-}
-
-// CreateLinearGradient sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateLinearGradient(c *xgb.Conn, Picture Picture, P1 Pointfix, P2 Pointfix, NumStops uint32, Stops []Fixed, Colors []Color) CreateLinearGradientCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateLinearGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createLinearGradientRequest(c, Picture, P1, P2, NumStops, Stops, Colors), cookie)
-	return CreateLinearGradientCookie{cookie}
-}
-
-// CreateLinearGradientChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateLinearGradientCookie.Check()
-func CreateLinearGradientChecked(c *xgb.Conn, Picture Picture, P1 Pointfix, P2 Pointfix, NumStops uint32, Stops []Fixed, Colors []Color) CreateLinearGradientCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateLinearGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createLinearGradientRequest(c, Picture, P1, P2, NumStops, Stops, Colors), cookie)
-	return CreateLinearGradientCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateLinearGradientCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateLinearGradient
-// createLinearGradientRequest writes a CreateLinearGradient request to a byte slice.
-func createLinearGradientRequest(c *xgb.Conn, Picture Picture, P1 Pointfix, P2 Pointfix, NumStops uint32, Stops []Fixed, Colors []Color) []byte {
-	size := xgb.Pad((((28 + xgb.Pad((int(NumStops) * 4))) + 4) + xgb.Pad((int(NumStops) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 34 // request opcode
-	b += 1
-
-	blen := b
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Picture))
-	b += 4
-
-	{
-		structBytes := P1.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	{
-		structBytes := P2.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	xgb.Put32(buf[b:], NumStops)
-	b += 4
-
-	for i := 0; i < int(NumStops); i++ {
-		xgb.Put32(buf[b:], uint32(Stops[i]))
-		b += 4
-	}
-
-	b = (b + 3) & ^3 // alignment gap
-
-	b += ColorListBytes(buf[b:], Colors)
-
-	b = xgb.Pad(b)
-	xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units
-	return buf[:b]
-}
-
-// CreatePictureCookie is a cookie used only for CreatePicture requests.
-type CreatePictureCookie struct {
-	*xgb.Cookie
-}
-
-// CreatePicture sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreatePicture(c *xgb.Conn, Pid Picture, Drawable xproto.Drawable, Format Pictformat, ValueMask uint32, ValueList []uint32) CreatePictureCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreatePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createPictureRequest(c, Pid, Drawable, Format, ValueMask, ValueList), cookie)
-	return CreatePictureCookie{cookie}
-}
-
-// CreatePictureChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreatePictureCookie.Check()
-func CreatePictureChecked(c *xgb.Conn, Pid Picture, Drawable xproto.Drawable, Format Pictformat, ValueMask uint32, ValueList []uint32) CreatePictureCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreatePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createPictureRequest(c, Pid, Drawable, Format, ValueMask, ValueList), cookie)
-	return CreatePictureCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreatePictureCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreatePicture
-// createPictureRequest writes a CreatePicture request to a byte slice.
-func createPictureRequest(c *xgb.Conn, Pid Picture, Drawable xproto.Drawable, Format Pictformat, ValueMask uint32, ValueList []uint32) []byte {
-	size := xgb.Pad((16 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 4 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Pid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Format))
-	b += 4
-
-	xgb.Put32(buf[b:], ValueMask)
-	b += 4
-	for i := 0; i < xgb.PopCount(int(ValueMask)); i++ {
-		xgb.Put32(buf[b:], ValueList[i])
-		b += 4
-	}
-	b = xgb.Pad(b)
-
-	return buf
-}
-
-// CreateRadialGradientCookie is a cookie used only for CreateRadialGradient requests.
-type CreateRadialGradientCookie struct {
-	*xgb.Cookie
-}
-
-// CreateRadialGradient sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateRadialGradient(c *xgb.Conn, Picture Picture, Inner Pointfix, Outer Pointfix, InnerRadius Fixed, OuterRadius Fixed, NumStops uint32, Stops []Fixed, Colors []Color) CreateRadialGradientCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateRadialGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createRadialGradientRequest(c, Picture, Inner, Outer, InnerRadius, OuterRadius, NumStops, Stops, Colors), cookie)
-	return CreateRadialGradientCookie{cookie}
-}
-
-// CreateRadialGradientChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateRadialGradientCookie.Check()
-func CreateRadialGradientChecked(c *xgb.Conn, Picture Picture, Inner Pointfix, Outer Pointfix, InnerRadius Fixed, OuterRadius Fixed, NumStops uint32, Stops []Fixed, Colors []Color) CreateRadialGradientCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateRadialGradient' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createRadialGradientRequest(c, Picture, Inner, Outer, InnerRadius, OuterRadius, NumStops, Stops, Colors), cookie)
-	return CreateRadialGradientCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateRadialGradientCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateRadialGradient
-// createRadialGradientRequest writes a CreateRadialGradient request to a byte slice.
-func createRadialGradientRequest(c *xgb.Conn, Picture Picture, Inner Pointfix, Outer Pointfix, InnerRadius Fixed, OuterRadius Fixed, NumStops uint32, Stops []Fixed, Colors []Color) []byte {
-	size := xgb.Pad((((36 + xgb.Pad((int(NumStops) * 4))) + 4) + xgb.Pad((int(NumStops) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 35 // request opcode
-	b += 1
-
-	blen := b
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Picture))
-	b += 4
-
-	{
-		structBytes := Inner.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	{
-		structBytes := Outer.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	xgb.Put32(buf[b:], uint32(InnerRadius))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(OuterRadius))
-	b += 4
-
-	xgb.Put32(buf[b:], NumStops)
-	b += 4
-
-	for i := 0; i < int(NumStops); i++ {
-		xgb.Put32(buf[b:], uint32(Stops[i]))
-		b += 4
-	}
-
-	b = (b + 3) & ^3 // alignment gap
-
-	b += ColorListBytes(buf[b:], Colors)
-
-	b = xgb.Pad(b)
-	xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units
-	return buf[:b]
-}
-
-// CreateSolidFillCookie is a cookie used only for CreateSolidFill requests.
-type CreateSolidFillCookie struct {
-	*xgb.Cookie
-}
-
-// CreateSolidFill sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateSolidFill(c *xgb.Conn, Picture Picture, Color Color) CreateSolidFillCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateSolidFill' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createSolidFillRequest(c, Picture, Color), cookie)
-	return CreateSolidFillCookie{cookie}
-}
-
-// CreateSolidFillChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateSolidFillCookie.Check()
-func CreateSolidFillChecked(c *xgb.Conn, Picture Picture, Color Color) CreateSolidFillCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'CreateSolidFill' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createSolidFillRequest(c, Picture, Color), cookie)
-	return CreateSolidFillCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateSolidFillCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateSolidFill
-// createSolidFillRequest writes a CreateSolidFill request to a byte slice.
-func createSolidFillRequest(c *xgb.Conn, Picture Picture, Color Color) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 33 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Picture))
-	b += 4
-
-	{
-		structBytes := Color.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	return buf
-}
-
-// FillRectanglesCookie is a cookie used only for FillRectangles requests.
-type FillRectanglesCookie struct {
-	*xgb.Cookie
-}
-
-// FillRectangles sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func FillRectangles(c *xgb.Conn, Op byte, Dst Picture, Color Color, Rects []xproto.Rectangle) FillRectanglesCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'FillRectangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(fillRectanglesRequest(c, Op, Dst, Color, Rects), cookie)
-	return FillRectanglesCookie{cookie}
-}
-
-// FillRectanglesChecked sends a checked request.
-// If an error occurs, it can be retrieved using FillRectanglesCookie.Check()
-func FillRectanglesChecked(c *xgb.Conn, Op byte, Dst Picture, Color Color, Rects []xproto.Rectangle) FillRectanglesCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'FillRectangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(fillRectanglesRequest(c, Op, Dst, Color, Rects), cookie)
-	return FillRectanglesCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook FillRectanglesCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for FillRectangles
-// fillRectanglesRequest writes a FillRectangles request to a byte slice.
-func fillRectanglesRequest(c *xgb.Conn, Op byte, Dst Picture, Color Color, Rects []xproto.Rectangle) []byte {
-	size := xgb.Pad((20 + xgb.Pad((len(Rects) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 26 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = Op
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], uint32(Dst))
-	b += 4
-
-	{
-		structBytes := Color.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	b += xproto.RectangleListBytes(buf[b:], Rects)
-
-	return buf
-}
-
-// FreeGlyphSetCookie is a cookie used only for FreeGlyphSet requests.
-type FreeGlyphSetCookie struct {
-	*xgb.Cookie
-}
-
-// FreeGlyphSet sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func FreeGlyphSet(c *xgb.Conn, Glyphset Glyphset) FreeGlyphSetCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'FreeGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(freeGlyphSetRequest(c, Glyphset), cookie)
-	return FreeGlyphSetCookie{cookie}
-}
-
-// FreeGlyphSetChecked sends a checked request.
-// If an error occurs, it can be retrieved using FreeGlyphSetCookie.Check()
-func FreeGlyphSetChecked(c *xgb.Conn, Glyphset Glyphset) FreeGlyphSetCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'FreeGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(freeGlyphSetRequest(c, Glyphset), cookie)
-	return FreeGlyphSetCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook FreeGlyphSetCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for FreeGlyphSet
-// freeGlyphSetRequest writes a FreeGlyphSet request to a byte slice.
-func freeGlyphSetRequest(c *xgb.Conn, Glyphset Glyphset) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 19 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Glyphset))
-	b += 4
-
-	return buf
-}
-
-// FreeGlyphsCookie is a cookie used only for FreeGlyphs requests.
-type FreeGlyphsCookie struct {
-	*xgb.Cookie
-}
-
-// FreeGlyphs sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func FreeGlyphs(c *xgb.Conn, Glyphset Glyphset, Glyphs []Glyph) FreeGlyphsCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'FreeGlyphs' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(freeGlyphsRequest(c, Glyphset, Glyphs), cookie)
-	return FreeGlyphsCookie{cookie}
-}
-
-// FreeGlyphsChecked sends a checked request.
-// If an error occurs, it can be retrieved using FreeGlyphsCookie.Check()
-func FreeGlyphsChecked(c *xgb.Conn, Glyphset Glyphset, Glyphs []Glyph) FreeGlyphsCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'FreeGlyphs' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(freeGlyphsRequest(c, Glyphset, Glyphs), cookie)
-	return FreeGlyphsCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook FreeGlyphsCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for FreeGlyphs
-// freeGlyphsRequest writes a FreeGlyphs request to a byte slice.
-func freeGlyphsRequest(c *xgb.Conn, Glyphset Glyphset, Glyphs []Glyph) []byte {
-	size := xgb.Pad((8 + xgb.Pad((len(Glyphs) * 4))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 22 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Glyphset))
-	b += 4
-
-	for i := 0; i < int(len(Glyphs)); i++ {
-		xgb.Put32(buf[b:], uint32(Glyphs[i]))
-		b += 4
-	}
-
-	return buf
-}
-
-// FreePictureCookie is a cookie used only for FreePicture requests.
-type FreePictureCookie struct {
-	*xgb.Cookie
-}
-
-// FreePicture sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func FreePicture(c *xgb.Conn, Picture Picture) FreePictureCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'FreePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(freePictureRequest(c, Picture), cookie)
-	return FreePictureCookie{cookie}
-}
-
-// FreePictureChecked sends a checked request.
-// If an error occurs, it can be retrieved using FreePictureCookie.Check()
-func FreePictureChecked(c *xgb.Conn, Picture Picture) FreePictureCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'FreePicture' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(freePictureRequest(c, Picture), cookie)
-	return FreePictureCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook FreePictureCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for FreePicture
-// freePictureRequest writes a FreePicture request to a byte slice.
-func freePictureRequest(c *xgb.Conn, Picture Picture) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 7 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Picture))
-	b += 4
-
-	return buf
-}
-
-// QueryFiltersCookie is a cookie used only for QueryFilters requests.
-type QueryFiltersCookie struct {
-	*xgb.Cookie
-}
-
-// QueryFilters sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryFiltersCookie.Reply()
-func QueryFilters(c *xgb.Conn, Drawable xproto.Drawable) QueryFiltersCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'QueryFilters' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryFiltersRequest(c, Drawable), cookie)
-	return QueryFiltersCookie{cookie}
-}
-
-// QueryFiltersUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryFiltersUnchecked(c *xgb.Conn, Drawable xproto.Drawable) QueryFiltersCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'QueryFilters' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryFiltersRequest(c, Drawable), cookie)
-	return QueryFiltersCookie{cookie}
-}
-
-// QueryFiltersReply represents the data returned from a QueryFilters request.
-type QueryFiltersReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	NumAliases uint32
-	NumFilters uint32
-	// padding: 16 bytes
-	Aliases []uint16     // size: xgb.Pad((int(NumAliases) * 2))
-	Filters []xproto.Str // size: xproto.StrListSize(Filters)
-}
-
-// Reply blocks and returns the reply data for a QueryFilters request.
-func (cook QueryFiltersCookie) Reply() (*QueryFiltersReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryFiltersReply(buf), nil
-}
-
-// queryFiltersReply reads a byte slice into a QueryFiltersReply value.
-func queryFiltersReply(buf []byte) *QueryFiltersReply {
-	v := new(QueryFiltersReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.NumAliases = xgb.Get32(buf[b:])
-	b += 4
-
-	v.NumFilters = xgb.Get32(buf[b:])
-	b += 4
-
-	b += 16 // padding
-
-	v.Aliases = make([]uint16, v.NumAliases)
-	for i := 0; i < int(v.NumAliases); i++ {
-		v.Aliases[i] = xgb.Get16(buf[b:])
-		b += 2
-	}
-
-	v.Filters = make([]xproto.Str, v.NumFilters)
-	b += xproto.StrReadList(buf[b:], v.Filters)
-
-	return v
-}
-
-// Write request to wire for QueryFilters
-// queryFiltersRequest writes a QueryFilters request to a byte slice.
-func queryFiltersRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 29 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	return buf
-}
-
-// QueryPictFormatsCookie is a cookie used only for QueryPictFormats requests.
-type QueryPictFormatsCookie struct {
-	*xgb.Cookie
-}
-
-// QueryPictFormats sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryPictFormatsCookie.Reply()
-func QueryPictFormats(c *xgb.Conn) QueryPictFormatsCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'QueryPictFormats' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryPictFormatsRequest(c), cookie)
-	return QueryPictFormatsCookie{cookie}
-}
-
-// QueryPictFormatsUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryPictFormatsUnchecked(c *xgb.Conn) QueryPictFormatsCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'QueryPictFormats' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryPictFormatsRequest(c), cookie)
-	return QueryPictFormatsCookie{cookie}
-}
-
-// QueryPictFormatsReply represents the data returned from a QueryPictFormats request.
-type QueryPictFormatsReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	NumFormats  uint32
-	NumScreens  uint32
-	NumDepths   uint32
-	NumVisuals  uint32
-	NumSubpixel uint32
-	// padding: 4 bytes
-	Formats []Pictforminfo // size: xgb.Pad((int(NumFormats) * 28))
-	// alignment gap to multiple of 4
-	Screens []Pictscreen // size: PictscreenListSize(Screens)
-	// alignment gap to multiple of 4
-	Subpixels []uint32 // size: xgb.Pad((int(NumSubpixel) * 4))
-}
-
-// Reply blocks and returns the reply data for a QueryPictFormats request.
-func (cook QueryPictFormatsCookie) Reply() (*QueryPictFormatsReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryPictFormatsReply(buf), nil
-}
-
-// queryPictFormatsReply reads a byte slice into a QueryPictFormatsReply value.
-func queryPictFormatsReply(buf []byte) *QueryPictFormatsReply {
-	v := new(QueryPictFormatsReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.NumFormats = xgb.Get32(buf[b:])
-	b += 4
-
-	v.NumScreens = xgb.Get32(buf[b:])
-	b += 4
-
-	v.NumDepths = xgb.Get32(buf[b:])
-	b += 4
-
-	v.NumVisuals = xgb.Get32(buf[b:])
-	b += 4
-
-	v.NumSubpixel = xgb.Get32(buf[b:])
-	b += 4
-
-	b += 4 // padding
-
-	v.Formats = make([]Pictforminfo, v.NumFormats)
-	b += PictforminfoReadList(buf[b:], v.Formats)
-
-	b = (b + 3) & ^3 // alignment gap
-
-	v.Screens = make([]Pictscreen, v.NumScreens)
-	b += PictscreenReadList(buf[b:], v.Screens)
-
-	b = (b + 3) & ^3 // alignment gap
-
-	v.Subpixels = make([]uint32, v.NumSubpixel)
-	for i := 0; i < int(v.NumSubpixel); i++ {
-		v.Subpixels[i] = xgb.Get32(buf[b:])
-		b += 4
-	}
-
-	return v
-}
-
-// Write request to wire for QueryPictFormats
-// queryPictFormatsRequest writes a QueryPictFormats request to a byte slice.
-func queryPictFormatsRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 1 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// QueryPictIndexValuesCookie is a cookie used only for QueryPictIndexValues requests.
-type QueryPictIndexValuesCookie struct {
-	*xgb.Cookie
-}
-
-// QueryPictIndexValues sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryPictIndexValuesCookie.Reply()
-func QueryPictIndexValues(c *xgb.Conn, Format Pictformat) QueryPictIndexValuesCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'QueryPictIndexValues' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryPictIndexValuesRequest(c, Format), cookie)
-	return QueryPictIndexValuesCookie{cookie}
-}
-
-// QueryPictIndexValuesUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryPictIndexValuesUnchecked(c *xgb.Conn, Format Pictformat) QueryPictIndexValuesCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'QueryPictIndexValues' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryPictIndexValuesRequest(c, Format), cookie)
-	return QueryPictIndexValuesCookie{cookie}
-}
-
-// QueryPictIndexValuesReply represents the data returned from a QueryPictIndexValues request.
-type QueryPictIndexValuesReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	NumValues uint32
-	// padding: 20 bytes
-	Values []Indexvalue // size: xgb.Pad((int(NumValues) * 12))
-}
-
-// Reply blocks and returns the reply data for a QueryPictIndexValues request.
-func (cook QueryPictIndexValuesCookie) Reply() (*QueryPictIndexValuesReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryPictIndexValuesReply(buf), nil
-}
-
-// queryPictIndexValuesReply reads a byte slice into a QueryPictIndexValuesReply value.
-func queryPictIndexValuesReply(buf []byte) *QueryPictIndexValuesReply {
-	v := new(QueryPictIndexValuesReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.NumValues = xgb.Get32(buf[b:])
-	b += 4
-
-	b += 20 // padding
-
-	v.Values = make([]Indexvalue, v.NumValues)
-	b += IndexvalueReadList(buf[b:], v.Values)
-
-	return v
-}
-
-// Write request to wire for QueryPictIndexValues
-// queryPictIndexValuesRequest writes a QueryPictIndexValues request to a byte slice.
-func queryPictIndexValuesRequest(c *xgb.Conn, Format Pictformat) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 2 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Format))
-	b += 4
-
-	return buf
-}
-
-// QueryVersionCookie is a cookie used only for QueryVersion requests.
-type QueryVersionCookie struct {
-	*xgb.Cookie
-}
-
-// QueryVersion sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply()
-func QueryVersion(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) QueryVersionCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie)
-	return QueryVersionCookie{cookie}
-}
-
-// QueryVersionUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryVersionUnchecked(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) QueryVersionCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryVersionRequest(c, ClientMajorVersion, ClientMinorVersion), cookie)
-	return QueryVersionCookie{cookie}
-}
-
-// QueryVersionReply represents the data returned from a QueryVersion request.
-type QueryVersionReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	MajorVersion uint32
-	MinorVersion uint32
-	// padding: 16 bytes
-}
-
-// Reply blocks and returns the reply data for a QueryVersion request.
-func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryVersionReply(buf), nil
-}
-
-// queryVersionReply reads a byte slice into a QueryVersionReply value.
-func queryVersionReply(buf []byte) *QueryVersionReply {
-	v := new(QueryVersionReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.MajorVersion = xgb.Get32(buf[b:])
-	b += 4
-
-	v.MinorVersion = xgb.Get32(buf[b:])
-	b += 4
-
-	b += 16 // padding
-
-	return v
-}
-
-// Write request to wire for QueryVersion
-// queryVersionRequest writes a QueryVersion request to a byte slice.
-func queryVersionRequest(c *xgb.Conn, ClientMajorVersion uint32, ClientMinorVersion uint32) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 0 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], ClientMajorVersion)
-	b += 4
-
-	xgb.Put32(buf[b:], ClientMinorVersion)
-	b += 4
-
-	return buf
-}
-
-// ReferenceGlyphSetCookie is a cookie used only for ReferenceGlyphSet requests.
-type ReferenceGlyphSetCookie struct {
-	*xgb.Cookie
-}
-
-// ReferenceGlyphSet sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ReferenceGlyphSet(c *xgb.Conn, Gsid Glyphset, Existing Glyphset) ReferenceGlyphSetCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'ReferenceGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(referenceGlyphSetRequest(c, Gsid, Existing), cookie)
-	return ReferenceGlyphSetCookie{cookie}
-}
-
-// ReferenceGlyphSetChecked sends a checked request.
-// If an error occurs, it can be retrieved using ReferenceGlyphSetCookie.Check()
-func ReferenceGlyphSetChecked(c *xgb.Conn, Gsid Glyphset, Existing Glyphset) ReferenceGlyphSetCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'ReferenceGlyphSet' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(referenceGlyphSetRequest(c, Gsid, Existing), cookie)
-	return ReferenceGlyphSetCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ReferenceGlyphSetCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ReferenceGlyphSet
-// referenceGlyphSetRequest writes a ReferenceGlyphSet request to a byte slice.
-func referenceGlyphSetRequest(c *xgb.Conn, Gsid Glyphset, Existing Glyphset) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 18 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Gsid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Existing))
-	b += 4
-
-	return buf
-}
-
-// SetPictureClipRectanglesCookie is a cookie used only for SetPictureClipRectangles requests.
-type SetPictureClipRectanglesCookie struct {
-	*xgb.Cookie
-}
-
-// SetPictureClipRectangles sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetPictureClipRectangles(c *xgb.Conn, Picture Picture, ClipXOrigin int16, ClipYOrigin int16, Rectangles []xproto.Rectangle) SetPictureClipRectanglesCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'SetPictureClipRectangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(setPictureClipRectanglesRequest(c, Picture, ClipXOrigin, ClipYOrigin, Rectangles), cookie)
-	return SetPictureClipRectanglesCookie{cookie}
-}
-
-// SetPictureClipRectanglesChecked sends a checked request.
-// If an error occurs, it can be retrieved using SetPictureClipRectanglesCookie.Check()
-func SetPictureClipRectanglesChecked(c *xgb.Conn, Picture Picture, ClipXOrigin int16, ClipYOrigin int16, Rectangles []xproto.Rectangle) SetPictureClipRectanglesCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'SetPictureClipRectangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(setPictureClipRectanglesRequest(c, Picture, ClipXOrigin, ClipYOrigin, Rectangles), cookie)
-	return SetPictureClipRectanglesCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SetPictureClipRectanglesCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SetPictureClipRectangles
-// setPictureClipRectanglesRequest writes a SetPictureClipRectangles request to a byte slice.
-func setPictureClipRectanglesRequest(c *xgb.Conn, Picture Picture, ClipXOrigin int16, ClipYOrigin int16, Rectangles []xproto.Rectangle) []byte {
-	size := xgb.Pad((12 + xgb.Pad((len(Rectangles) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 6 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Picture))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(ClipXOrigin))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(ClipYOrigin))
-	b += 2
-
-	b += xproto.RectangleListBytes(buf[b:], Rectangles)
-
-	return buf
-}
-
-// SetPictureFilterCookie is a cookie used only for SetPictureFilter requests.
-type SetPictureFilterCookie struct {
-	*xgb.Cookie
-}
-
-// SetPictureFilter sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetPictureFilter(c *xgb.Conn, Picture Picture, FilterLen uint16, Filter string, Values []Fixed) SetPictureFilterCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'SetPictureFilter' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(setPictureFilterRequest(c, Picture, FilterLen, Filter, Values), cookie)
-	return SetPictureFilterCookie{cookie}
-}
-
-// SetPictureFilterChecked sends a checked request.
-// If an error occurs, it can be retrieved using SetPictureFilterCookie.Check()
-func SetPictureFilterChecked(c *xgb.Conn, Picture Picture, FilterLen uint16, Filter string, Values []Fixed) SetPictureFilterCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'SetPictureFilter' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(setPictureFilterRequest(c, Picture, FilterLen, Filter, Values), cookie)
-	return SetPictureFilterCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SetPictureFilterCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SetPictureFilter
-// setPictureFilterRequest writes a SetPictureFilter request to a byte slice.
-func setPictureFilterRequest(c *xgb.Conn, Picture Picture, FilterLen uint16, Filter string, Values []Fixed) []byte {
-	size := xgb.Pad((((12 + xgb.Pad((int(FilterLen) * 1))) + 4) + xgb.Pad((len(Values) * 4))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 30 // request opcode
-	b += 1
-
-	blen := b
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Picture))
-	b += 4
-
-	xgb.Put16(buf[b:], FilterLen)
-	b += 2
-
-	b += 2 // padding
-
-	copy(buf[b:], Filter[:FilterLen])
-	b += int(FilterLen)
-
-	b = (b + 3) & ^3 // alignment gap
-
-	for i := 0; i < int(len(Values)); i++ {
-		xgb.Put32(buf[b:], uint32(Values[i]))
-		b += 4
-	}
-
-	b = xgb.Pad(b)
-	xgb.Put16(buf[blen:], uint16(b/4)) // write request size in 4-byte units
-	return buf[:b]
-}
-
-// SetPictureTransformCookie is a cookie used only for SetPictureTransform requests.
-type SetPictureTransformCookie struct {
-	*xgb.Cookie
-}
-
-// SetPictureTransform sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetPictureTransform(c *xgb.Conn, Picture Picture, Transform Transform) SetPictureTransformCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'SetPictureTransform' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(setPictureTransformRequest(c, Picture, Transform), cookie)
-	return SetPictureTransformCookie{cookie}
-}
-
-// SetPictureTransformChecked sends a checked request.
-// If an error occurs, it can be retrieved using SetPictureTransformCookie.Check()
-func SetPictureTransformChecked(c *xgb.Conn, Picture Picture, Transform Transform) SetPictureTransformCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'SetPictureTransform' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(setPictureTransformRequest(c, Picture, Transform), cookie)
-	return SetPictureTransformCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SetPictureTransformCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SetPictureTransform
-// setPictureTransformRequest writes a SetPictureTransform request to a byte slice.
-func setPictureTransformRequest(c *xgb.Conn, Picture Picture, Transform Transform) []byte {
-	size := 44
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 28 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Picture))
-	b += 4
-
-	{
-		structBytes := Transform.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-
-	return buf
-}
-
-// TrapezoidsCookie is a cookie used only for Trapezoids requests.
-type TrapezoidsCookie struct {
-	*xgb.Cookie
-}
-
-// Trapezoids sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func Trapezoids(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Traps []Trapezoid) TrapezoidsCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'Trapezoids' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(trapezoidsRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Traps), cookie)
-	return TrapezoidsCookie{cookie}
-}
-
-// TrapezoidsChecked sends a checked request.
-// If an error occurs, it can be retrieved using TrapezoidsCookie.Check()
-func TrapezoidsChecked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Traps []Trapezoid) TrapezoidsCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'Trapezoids' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(trapezoidsRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Traps), cookie)
-	return TrapezoidsCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook TrapezoidsCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for Trapezoids
-// trapezoidsRequest writes a Trapezoids request to a byte slice.
-func trapezoidsRequest(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Traps []Trapezoid) []byte {
-	size := xgb.Pad((24 + xgb.Pad((len(Traps) * 40))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 10 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = Op
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], uint32(Src))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Dst))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(MaskFormat))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	b += TrapezoidListBytes(buf[b:], Traps)
-
-	return buf
-}
-
-// TriFanCookie is a cookie used only for TriFan requests.
-type TriFanCookie struct {
-	*xgb.Cookie
-}
-
-// TriFan sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func TriFan(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) TriFanCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'TriFan' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(triFanRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Points), cookie)
-	return TriFanCookie{cookie}
-}
-
-// TriFanChecked sends a checked request.
-// If an error occurs, it can be retrieved using TriFanCookie.Check()
-func TriFanChecked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) TriFanCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'TriFan' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(triFanRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Points), cookie)
-	return TriFanCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook TriFanCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for TriFan
-// triFanRequest writes a TriFan request to a byte slice.
-func triFanRequest(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) []byte {
-	size := xgb.Pad((24 + xgb.Pad((len(Points) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 13 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = Op
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], uint32(Src))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Dst))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(MaskFormat))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	b += PointfixListBytes(buf[b:], Points)
-
-	return buf
-}
-
-// TriStripCookie is a cookie used only for TriStrip requests.
-type TriStripCookie struct {
-	*xgb.Cookie
-}
-
-// TriStrip sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func TriStrip(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) TriStripCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'TriStrip' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(triStripRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Points), cookie)
-	return TriStripCookie{cookie}
-}
-
-// TriStripChecked sends a checked request.
-// If an error occurs, it can be retrieved using TriStripCookie.Check()
-func TriStripChecked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) TriStripCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'TriStrip' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(triStripRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Points), cookie)
-	return TriStripCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook TriStripCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for TriStrip
-// triStripRequest writes a TriStrip request to a byte slice.
-func triStripRequest(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Points []Pointfix) []byte {
-	size := xgb.Pad((24 + xgb.Pad((len(Points) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 12 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = Op
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], uint32(Src))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Dst))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(MaskFormat))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	b += PointfixListBytes(buf[b:], Points)
-
-	return buf
-}
-
-// TrianglesCookie is a cookie used only for Triangles requests.
-type TrianglesCookie struct {
-	*xgb.Cookie
-}
-
-// Triangles sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func Triangles(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Triangles []Triangle) TrianglesCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'Triangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(trianglesRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Triangles), cookie)
-	return TrianglesCookie{cookie}
-}
-
-// TrianglesChecked sends a checked request.
-// If an error occurs, it can be retrieved using TrianglesCookie.Check()
-func TrianglesChecked(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Triangles []Triangle) TrianglesCookie {
-	if _, ok := c.Extensions["RENDER"]; !ok {
-		panic("Cannot issue request 'Triangles' using the uninitialized extension 'RENDER'. render.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(trianglesRequest(c, Op, Src, Dst, MaskFormat, SrcX, SrcY, Triangles), cookie)
-	return TrianglesCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook TrianglesCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for Triangles
-// trianglesRequest writes a Triangles request to a byte slice.
-func trianglesRequest(c *xgb.Conn, Op byte, Src Picture, Dst Picture, MaskFormat Pictformat, SrcX int16, SrcY int16, Triangles []Triangle) []byte {
-	size := xgb.Pad((24 + xgb.Pad((len(Triangles) * 24))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["RENDER"]
-	b += 1
-
-	buf[b] = 11 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = Op
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], uint32(Src))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Dst))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(MaskFormat))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	b += TriangleListBytes(buf[b:], Triangles)
-
-	return buf
-}
diff --git a/shiny/internal/xgb/shm/shm.go b/shiny/internal/xgb/shm/shm.go
deleted file mode 100644
index e50be1c..0000000
--- a/shiny/internal/xgb/shm/shm.go
+++ /dev/null
@@ -1,898 +0,0 @@
-// Package shm is the X client API for the MIT-SHM extension.
-package shm
-
-// This file is automatically generated from shm.xml. Edit at your peril!
-
-import (
-	"golang.org/x/exp/shiny/internal/xgb"
-
-	"golang.org/x/exp/shiny/internal/xgb/xproto"
-)
-
-// Init must be called before using the MIT-SHM extension.
-func Init(c *xgb.Conn) error {
-	reply, err := xproto.QueryExtension(c, 7, "MIT-SHM").Reply()
-	switch {
-	case err != nil:
-		return err
-	case !reply.Present:
-		return xgb.Errorf("No extension named MIT-SHM could be found on on the server.")
-	}
-
-	xgb.ExtLock.Lock()
-	c.Extensions["MIT-SHM"] = reply.MajorOpcode
-	for evNum, fun := range xgb.NewExtEventFuncs["MIT-SHM"] {
-		xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun
-	}
-	for errNum, fun := range xgb.NewExtErrorFuncs["MIT-SHM"] {
-		xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun
-	}
-	xgb.ExtLock.Unlock()
-
-	return nil
-}
-
-func init() {
-	xgb.NewExtEventFuncs["MIT-SHM"] = make(map[int]xgb.NewEventFun)
-	xgb.NewExtErrorFuncs["MIT-SHM"] = make(map[int]xgb.NewErrorFun)
-}
-
-// BadBadSeg is the error number for a BadBadSeg.
-const BadBadSeg = 0
-
-type BadSegError xproto.ValueError
-
-// BadSegErrorNew constructs a BadSegError value that implements xgb.Error from a byte slice.
-func BadSegErrorNew(buf []byte) xgb.Error {
-	v := BadSegError(xproto.ValueErrorNew(buf).(xproto.ValueError))
-	v.NiceName = "BadSeg"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadBadSeg error.
-// This is mostly used internally.
-func (err BadSegError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadBadSeg error. If no bad value exists, 0 is returned.
-func (err BadSegError) BadId() uint32 {
-	return 0
-}
-
-// Error returns a rudimentary string representation of the BadBadSeg error.
-func (err BadSegError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadBadSeg {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewExtErrorFuncs["MIT-SHM"][0] = BadSegErrorNew
-}
-
-// Completion is the event number for a CompletionEvent.
-const Completion = 0
-
-type CompletionEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Drawable   xproto.Drawable
-	MinorEvent uint16
-	MajorEvent byte
-	// padding: 1 bytes
-	Shmseg Seg
-	Offset uint32
-}
-
-// CompletionEventNew constructs a CompletionEvent value that implements xgb.Event from a byte slice.
-func CompletionEventNew(buf []byte) xgb.Event {
-	v := CompletionEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Drawable = xproto.Drawable(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.MinorEvent = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MajorEvent = buf[b]
-	b += 1
-
-	b += 1 // padding
-
-	v.Shmseg = Seg(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Offset = xgb.Get32(buf[b:])
-	b += 4
-
-	return v
-}
-
-// Bytes writes a CompletionEvent value to a byte slice.
-func (v CompletionEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 0
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Drawable))
-	b += 4
-
-	xgb.Put16(buf[b:], v.MinorEvent)
-	b += 2
-
-	buf[b] = v.MajorEvent
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put32(buf[b:], uint32(v.Shmseg))
-	b += 4
-
-	xgb.Put32(buf[b:], v.Offset)
-	b += 4
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the Completion event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v CompletionEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of CompletionEvent.
-func (v CompletionEvent) String() string {
-	fieldVals := make([]string, 0, 7)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorEvent: %d", v.MinorEvent))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorEvent: %d", v.MajorEvent))
-	fieldVals = append(fieldVals, xgb.Sprintf("Shmseg: %d", v.Shmseg))
-	fieldVals = append(fieldVals, xgb.Sprintf("Offset: %d", v.Offset))
-	return "Completion {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewExtEventFuncs["MIT-SHM"][0] = CompletionEventNew
-}
-
-type Seg uint32
-
-func NewSegId(c *xgb.Conn) (Seg, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Seg(id), nil
-}
-
-// Skipping definition for base type 'Bool'
-
-// Skipping definition for base type 'Byte'
-
-// Skipping definition for base type 'Card8'
-
-// Skipping definition for base type 'Char'
-
-// Skipping definition for base type 'Void'
-
-// Skipping definition for base type 'Double'
-
-// Skipping definition for base type 'Float'
-
-// Skipping definition for base type 'Int16'
-
-// Skipping definition for base type 'Int32'
-
-// Skipping definition for base type 'Int8'
-
-// Skipping definition for base type 'Card16'
-
-// Skipping definition for base type 'Card32'
-
-// AttachCookie is a cookie used only for Attach requests.
-type AttachCookie struct {
-	*xgb.Cookie
-}
-
-// Attach sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func Attach(c *xgb.Conn, Shmseg Seg, Shmid uint32, ReadOnly bool) AttachCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'Attach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(attachRequest(c, Shmseg, Shmid, ReadOnly), cookie)
-	return AttachCookie{cookie}
-}
-
-// AttachChecked sends a checked request.
-// If an error occurs, it can be retrieved using AttachCookie.Check()
-func AttachChecked(c *xgb.Conn, Shmseg Seg, Shmid uint32, ReadOnly bool) AttachCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'Attach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(attachRequest(c, Shmseg, Shmid, ReadOnly), cookie)
-	return AttachCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook AttachCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for Attach
-// attachRequest writes a Attach request to a byte slice.
-func attachRequest(c *xgb.Conn, Shmseg Seg, Shmid uint32, ReadOnly bool) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["MIT-SHM"]
-	b += 1
-
-	buf[b] = 1 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Shmseg))
-	b += 4
-
-	xgb.Put32(buf[b:], Shmid)
-	b += 4
-
-	if ReadOnly {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// AttachFdCookie is a cookie used only for AttachFd requests.
-type AttachFdCookie struct {
-	*xgb.Cookie
-}
-
-// AttachFd sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func AttachFd(c *xgb.Conn, Shmseg Seg, ReadOnly bool) AttachFdCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'AttachFd' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(attachFdRequest(c, Shmseg, ReadOnly), cookie)
-	return AttachFdCookie{cookie}
-}
-
-// AttachFdChecked sends a checked request.
-// If an error occurs, it can be retrieved using AttachFdCookie.Check()
-func AttachFdChecked(c *xgb.Conn, Shmseg Seg, ReadOnly bool) AttachFdCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'AttachFd' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(attachFdRequest(c, Shmseg, ReadOnly), cookie)
-	return AttachFdCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook AttachFdCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for AttachFd
-// attachFdRequest writes a AttachFd request to a byte slice.
-func attachFdRequest(c *xgb.Conn, Shmseg Seg, ReadOnly bool) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["MIT-SHM"]
-	b += 1
-
-	buf[b] = 6 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Shmseg))
-	b += 4
-
-	if ReadOnly {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// CreatePixmapCookie is a cookie used only for CreatePixmap requests.
-type CreatePixmapCookie struct {
-	*xgb.Cookie
-}
-
-// CreatePixmap sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreatePixmap(c *xgb.Conn, Pid xproto.Pixmap, Drawable xproto.Drawable, Width uint16, Height uint16, Depth byte, Shmseg Seg, Offset uint32) CreatePixmapCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'CreatePixmap' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createPixmapRequest(c, Pid, Drawable, Width, Height, Depth, Shmseg, Offset), cookie)
-	return CreatePixmapCookie{cookie}
-}
-
-// CreatePixmapChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreatePixmapCookie.Check()
-func CreatePixmapChecked(c *xgb.Conn, Pid xproto.Pixmap, Drawable xproto.Drawable, Width uint16, Height uint16, Depth byte, Shmseg Seg, Offset uint32) CreatePixmapCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'CreatePixmap' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createPixmapRequest(c, Pid, Drawable, Width, Height, Depth, Shmseg, Offset), cookie)
-	return CreatePixmapCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreatePixmapCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreatePixmap
-// createPixmapRequest writes a CreatePixmap request to a byte slice.
-func createPixmapRequest(c *xgb.Conn, Pid xproto.Pixmap, Drawable xproto.Drawable, Width uint16, Height uint16, Depth byte, Shmseg Seg, Offset uint32) []byte {
-	size := 28
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["MIT-SHM"]
-	b += 1
-
-	buf[b] = 5 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Pid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put16(buf[b:], Width)
-	b += 2
-
-	xgb.Put16(buf[b:], Height)
-	b += 2
-
-	buf[b] = Depth
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], uint32(Shmseg))
-	b += 4
-
-	xgb.Put32(buf[b:], Offset)
-	b += 4
-
-	return buf
-}
-
-// CreateSegmentCookie is a cookie used only for CreateSegment requests.
-type CreateSegmentCookie struct {
-	*xgb.Cookie
-}
-
-// CreateSegment sends a checked request.
-// If an error occurs, it will be returned with the reply by calling CreateSegmentCookie.Reply()
-func CreateSegment(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) CreateSegmentCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'CreateSegment' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(createSegmentRequest(c, Shmseg, Size, ReadOnly), cookie)
-	return CreateSegmentCookie{cookie}
-}
-
-// CreateSegmentUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateSegmentUnchecked(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) CreateSegmentCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'CreateSegment' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(createSegmentRequest(c, Shmseg, Size, ReadOnly), cookie)
-	return CreateSegmentCookie{cookie}
-}
-
-// CreateSegmentReply represents the data returned from a CreateSegment request.
-type CreateSegmentReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	Nfd      byte
-	// padding: 24 bytes
-}
-
-// Reply blocks and returns the reply data for a CreateSegment request.
-func (cook CreateSegmentCookie) Reply() (*CreateSegmentReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return createSegmentReply(buf), nil
-}
-
-// createSegmentReply reads a byte slice into a CreateSegmentReply value.
-func createSegmentReply(buf []byte) *CreateSegmentReply {
-	v := new(CreateSegmentReply)
-	b := 1 // skip reply determinant
-
-	v.Nfd = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	b += 24 // padding
-
-	return v
-}
-
-// Write request to wire for CreateSegment
-// createSegmentRequest writes a CreateSegment request to a byte slice.
-func createSegmentRequest(c *xgb.Conn, Shmseg Seg, Size uint32, ReadOnly bool) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["MIT-SHM"]
-	b += 1
-
-	buf[b] = 7 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Shmseg))
-	b += 4
-
-	xgb.Put32(buf[b:], Size)
-	b += 4
-
-	if ReadOnly {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// DetachCookie is a cookie used only for Detach requests.
-type DetachCookie struct {
-	*xgb.Cookie
-}
-
-// Detach sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func Detach(c *xgb.Conn, Shmseg Seg) DetachCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'Detach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(detachRequest(c, Shmseg), cookie)
-	return DetachCookie{cookie}
-}
-
-// DetachChecked sends a checked request.
-// If an error occurs, it can be retrieved using DetachCookie.Check()
-func DetachChecked(c *xgb.Conn, Shmseg Seg) DetachCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'Detach' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(detachRequest(c, Shmseg), cookie)
-	return DetachCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook DetachCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for Detach
-// detachRequest writes a Detach request to a byte slice.
-func detachRequest(c *xgb.Conn, Shmseg Seg) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["MIT-SHM"]
-	b += 1
-
-	buf[b] = 2 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Shmseg))
-	b += 4
-
-	return buf
-}
-
-// GetImageCookie is a cookie used only for GetImage requests.
-type GetImageCookie struct {
-	*xgb.Cookie
-}
-
-// GetImage sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetImageCookie.Reply()
-func GetImage(c *xgb.Conn, Drawable xproto.Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32, Format byte, Shmseg Seg, Offset uint32) GetImageCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'GetImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getImageRequest(c, Drawable, X, Y, Width, Height, PlaneMask, Format, Shmseg, Offset), cookie)
-	return GetImageCookie{cookie}
-}
-
-// GetImageUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetImageUnchecked(c *xgb.Conn, Drawable xproto.Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32, Format byte, Shmseg Seg, Offset uint32) GetImageCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'GetImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getImageRequest(c, Drawable, X, Y, Width, Height, PlaneMask, Format, Shmseg, Offset), cookie)
-	return GetImageCookie{cookie}
-}
-
-// GetImageReply represents the data returned from a GetImage request.
-type GetImageReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	Depth    byte
-	Visual   xproto.Visualid
-	Size     uint32
-}
-
-// Reply blocks and returns the reply data for a GetImage request.
-func (cook GetImageCookie) Reply() (*GetImageReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getImageReply(buf), nil
-}
-
-// getImageReply reads a byte slice into a GetImageReply value.
-func getImageReply(buf []byte) *GetImageReply {
-	v := new(GetImageReply)
-	b := 1 // skip reply determinant
-
-	v.Depth = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Visual = xproto.Visualid(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Size = xgb.Get32(buf[b:])
-	b += 4
-
-	return v
-}
-
-// Write request to wire for GetImage
-// getImageRequest writes a GetImage request to a byte slice.
-func getImageRequest(c *xgb.Conn, Drawable xproto.Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32, Format byte, Shmseg Seg, Offset uint32) []byte {
-	size := 32
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["MIT-SHM"]
-	b += 1
-
-	buf[b] = 4 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Y))
-	b += 2
-
-	xgb.Put16(buf[b:], Width)
-	b += 2
-
-	xgb.Put16(buf[b:], Height)
-	b += 2
-
-	xgb.Put32(buf[b:], PlaneMask)
-	b += 4
-
-	buf[b] = Format
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], uint32(Shmseg))
-	b += 4
-
-	xgb.Put32(buf[b:], Offset)
-	b += 4
-
-	return buf
-}
-
-// PutImageCookie is a cookie used only for PutImage requests.
-type PutImageCookie struct {
-	*xgb.Cookie
-}
-
-// PutImage sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func PutImage(c *xgb.Conn, Drawable xproto.Drawable, Gc xproto.Gcontext, TotalWidth uint16, TotalHeight uint16, SrcX uint16, SrcY uint16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16, Depth byte, Format byte, SendEvent byte, Shmseg Seg, Offset uint32) PutImageCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'PutImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(putImageRequest(c, Drawable, Gc, TotalWidth, TotalHeight, SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY, Depth, Format, SendEvent, Shmseg, Offset), cookie)
-	return PutImageCookie{cookie}
-}
-
-// PutImageChecked sends a checked request.
-// If an error occurs, it can be retrieved using PutImageCookie.Check()
-func PutImageChecked(c *xgb.Conn, Drawable xproto.Drawable, Gc xproto.Gcontext, TotalWidth uint16, TotalHeight uint16, SrcX uint16, SrcY uint16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16, Depth byte, Format byte, SendEvent byte, Shmseg Seg, Offset uint32) PutImageCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'PutImage' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(putImageRequest(c, Drawable, Gc, TotalWidth, TotalHeight, SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY, Depth, Format, SendEvent, Shmseg, Offset), cookie)
-	return PutImageCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook PutImageCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for PutImage
-// putImageRequest writes a PutImage request to a byte slice.
-func putImageRequest(c *xgb.Conn, Drawable xproto.Drawable, Gc xproto.Gcontext, TotalWidth uint16, TotalHeight uint16, SrcX uint16, SrcY uint16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16, Depth byte, Format byte, SendEvent byte, Shmseg Seg, Offset uint32) []byte {
-	size := 40
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["MIT-SHM"]
-	b += 1
-
-	buf[b] = 3 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	xgb.Put16(buf[b:], TotalWidth)
-	b += 2
-
-	xgb.Put16(buf[b:], TotalHeight)
-	b += 2
-
-	xgb.Put16(buf[b:], SrcX)
-	b += 2
-
-	xgb.Put16(buf[b:], SrcY)
-	b += 2
-
-	xgb.Put16(buf[b:], SrcWidth)
-	b += 2
-
-	xgb.Put16(buf[b:], SrcHeight)
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstY))
-	b += 2
-
-	buf[b] = Depth
-	b += 1
-
-	buf[b] = Format
-	b += 1
-
-	buf[b] = SendEvent
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put32(buf[b:], uint32(Shmseg))
-	b += 4
-
-	xgb.Put32(buf[b:], Offset)
-	b += 4
-
-	return buf
-}
-
-// QueryVersionCookie is a cookie used only for QueryVersion requests.
-type QueryVersionCookie struct {
-	*xgb.Cookie
-}
-
-// QueryVersion sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryVersionCookie.Reply()
-func QueryVersion(c *xgb.Conn) QueryVersionCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryVersionRequest(c), cookie)
-	return QueryVersionCookie{cookie}
-}
-
-// QueryVersionUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryVersionUnchecked(c *xgb.Conn) QueryVersionCookie {
-	if _, ok := c.Extensions["MIT-SHM"]; !ok {
-		panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'MIT-SHM'. shm.Init(connObj) must be called first.")
-	}
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryVersionRequest(c), cookie)
-	return QueryVersionCookie{cookie}
-}
-
-// QueryVersionReply represents the data returned from a QueryVersion request.
-type QueryVersionReply struct {
-	Sequence      uint16 // sequence number of the request for this reply
-	Length        uint32 // number of bytes in this reply
-	SharedPixmaps bool
-	MajorVersion  uint16
-	MinorVersion  uint16
-	Uid           uint16
-	Gid           uint16
-	PixmapFormat  byte
-	// padding: 15 bytes
-}
-
-// Reply blocks and returns the reply data for a QueryVersion request.
-func (cook QueryVersionCookie) Reply() (*QueryVersionReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryVersionReply(buf), nil
-}
-
-// queryVersionReply reads a byte slice into a QueryVersionReply value.
-func queryVersionReply(buf []byte) *QueryVersionReply {
-	v := new(QueryVersionReply)
-	b := 1 // skip reply determinant
-
-	if buf[b] == 1 {
-		v.SharedPixmaps = true
-	} else {
-		v.SharedPixmaps = false
-	}
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.MajorVersion = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MinorVersion = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Uid = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Gid = xgb.Get16(buf[b:])
-	b += 2
-
-	v.PixmapFormat = buf[b]
-	b += 1
-
-	b += 15 // padding
-
-	return v
-}
-
-// Write request to wire for QueryVersion
-// queryVersionRequest writes a QueryVersion request to a byte slice.
-func queryVersionRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = c.Extensions["MIT-SHM"]
-	b += 1
-
-	buf[b] = 0 // request opcode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
diff --git a/shiny/internal/xgb/sync.go b/shiny/internal/xgb/sync.go
deleted file mode 100644
index 59d0de1..0000000
--- a/shiny/internal/xgb/sync.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package xgb
-
-// Sync sends a round trip request and waits for the response.
-// This forces all pending cookies to be dealt with.
-// You actually shouldn't need to use this like you might with Xlib. Namely,
-// buffers are automatically flushed using Go's channels and round trip requests
-// are forced where appropriate automatically.
-func (c *Conn) Sync() {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(c.getInputFocusRequest(), cookie)
-	cookie.Reply() // wait for the buffer to clear
-}
-
-// getInputFocusRequest writes the raw bytes to a buffer.
-// It is duplicated from xproto/xproto.go.
-func (c *Conn) getInputFocusRequest() []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 43 // request opcode
-	b += 1
-
-	b += 1                         // padding
-	Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
diff --git a/shiny/internal/xgb/xgb.go b/shiny/internal/xgb/xgb.go
deleted file mode 100644
index 487ae16..0000000
--- a/shiny/internal/xgb/xgb.go
+++ /dev/null
@@ -1,554 +0,0 @@
-package xgb
-
-import (
-	"errors"
-	"io"
-	"log"
-	"net"
-	"os"
-	"sync"
-)
-
-var (
-	// Where to log error-messages. Defaults to stderr.
-	// To disable logging, just set this to log.New(ioutil.Discard, "", 0)
-	Logger = log.New(os.Stderr, "XGB: ", log.Lshortfile)
-
-	// ExtLock is a lock used whenever new extensions are initialized.
-	// It should not be used. It is exported for use in the extension
-	// sub-packages.
-	ExtLock sync.Mutex
-)
-
-const (
-	// cookieBuffer represents the queue size of cookies existing at any
-	// point in time. The size of the buffer is really only important when
-	// there are many requests without replies made in sequence. Once the
-	// buffer fills, a round trip request is made to clear the buffer.
-	cookieBuffer = 1000
-
-	// xidBuffer represents the queue size of the xid channel.
-	// I don't think this value matters much, since xid generation is not
-	// that expensive.
-	xidBuffer = 5
-
-	// seqBuffer represents the queue size of the sequence number channel.
-	// I don't think this value matters much, since sequence number generation
-	// is not that expensive.
-	seqBuffer = 5
-
-	// reqBuffer represents the queue size of the number of requests that
-	// can be made until new ones block. This value seems OK.
-	reqBuffer = 100
-
-	// eventBuffer represents the queue size of the number of events or errors
-	// that can be loaded off the wire and not grabbed with WaitForEvent
-	// until reading an event blocks. This value should be big enough to handle
-	// bursts of events.
-	eventBuffer = 5000
-)
-
-// A Conn represents a connection to an X server.
-type Conn struct {
-	host          string
-	conn          net.Conn
-	display       string
-	DisplayNumber int
-	DefaultScreen int
-	SetupBytes    []byte
-
-	setupResourceIdBase uint32
-	setupResourceIdMask uint32
-
-	eventChan  chan eventOrError
-	cookieChan chan *Cookie
-	xidChan    chan xid
-	seqChan    chan uint16
-	reqChan    chan *request
-	closing    chan chan struct{}
-
-	// Extensions is a map from extension name to major opcode. It should
-	// not be used. It is exported for use in the extension sub-packages.
-	Extensions map[string]byte
-}
-
-// NewConn creates a new connection instance. It initializes locks, data
-// structures, and performs the initial handshake. (The code for the handshake
-// has been relegated to conn.go.)
-func NewConn() (*Conn, error) {
-	return NewConnDisplay("")
-}
-
-// NewConnDisplay is just like NewConn, but allows a specific DISPLAY
-// string to be used.
-// If 'display' is empty it will be taken from os.Getenv("DISPLAY").
-//
-// Examples:
-//	NewConn(":1") -> net.Dial("unix", "", "/tmp/.X11-unix/X1")
-//	NewConn("/tmp/launch-12/:0") -> net.Dial("unix", "", "/tmp/launch-12/:0")
-//	NewConn("hostname:2.1") -> net.Dial("tcp", "", "hostname:6002")
-//	NewConn("tcp/hostname:1.0") -> net.Dial("tcp", "", "hostname:6001")
-func NewConnDisplay(display string) (*Conn, error) {
-	conn := &Conn{}
-
-	// First connect. This reads authority, checks DISPLAY environment
-	// variable, and loads the initial Setup info.
-	err := conn.connect(display)
-	if err != nil {
-		return nil, err
-	}
-
-	return postNewConn(conn)
-}
-
-// NewConnDisplay is just like NewConn, but allows a specific net.Conn
-// to be used.
-func NewConnNet(netConn net.Conn) (*Conn, error) {
-	conn := &Conn{}
-
-	// First connect. This reads authority, checks DISPLAY environment
-	// variable, and loads the initial Setup info.
-	err := conn.connectNet(netConn)
-
-	if err != nil {
-		return nil, err
-	}
-
-	return postNewConn(conn)
-}
-
-func postNewConn(conn *Conn) (*Conn, error) {
-	conn.Extensions = make(map[string]byte)
-
-	conn.cookieChan = make(chan *Cookie, cookieBuffer)
-	conn.xidChan = make(chan xid, xidBuffer)
-	conn.seqChan = make(chan uint16, seqBuffer)
-	conn.reqChan = make(chan *request, reqBuffer)
-	conn.eventChan = make(chan eventOrError, eventBuffer)
-	conn.closing = make(chan chan struct{}, 1)
-
-	go conn.generateXIds()
-	go conn.generateSeqIds()
-	go conn.sendRequests()
-	go conn.readResponses()
-
-	return conn, nil
-}
-
-// Close gracefully closes the connection to the X server.
-func (c *Conn) Close() {
-	close(c.reqChan)
-}
-
-// Event is an interface that can contain any of the events returned by the
-// server. Use a type assertion switch to extract the Event structs.
-type Event interface {
-	Bytes() []byte
-	String() string
-}
-
-// NewEventFun is the type of function use to construct events from raw bytes.
-// It should not be used. It is exported for use in the extension sub-packages.
-type NewEventFun func(buf []byte) Event
-
-// NewEventFuncs is a map from event numbers to functions that create
-// the corresponding event. It should not be used. It is exported for use
-// in the extension sub-packages.
-var NewEventFuncs = make(map[int]NewEventFun)
-
-// NewExtEventFuncs is a temporary map that stores event constructor functions
-// for each extension. When an extension is initialized, each event for that
-// extension is added to the 'NewEventFuncs' map. It should not be used. It is
-// exported for use in the extension sub-packages.
-var NewExtEventFuncs = make(map[string]map[int]NewEventFun)
-
-// Error is an interface that can contain any of the errors returned by
-// the server. Use a type assertion switch to extract the Error structs.
-type Error interface {
-	SequenceId() uint16
-	BadId() uint32
-	Error() string
-}
-
-// NewErrorFun is the type of function use to construct errors from raw bytes.
-// It should not be used. It is exported for use in the extension sub-packages.
-type NewErrorFun func(buf []byte) Error
-
-// NewErrorFuncs is a map from error numbers to functions that create
-// the corresponding error. It should not be used. It is exported for use in
-// the extension sub-packages.
-var NewErrorFuncs = make(map[int]NewErrorFun)
-
-// NewExtErrorFuncs is a temporary map that stores error constructor functions
-// for each extension. When an extension is initialized, each error for that
-// extension is added to the 'NewErrorFuncs' map. It should not be used. It is
-// exported for use in the extension sub-packages.
-var NewExtErrorFuncs = make(map[string]map[int]NewErrorFun)
-
-// eventOrError corresponds to values that can be either an event or an
-// error.
-type eventOrError interface{}
-
-// NewId generates a new unused ID for use with requests like CreateWindow.
-// If no new ids can be generated, the id returned is 0 and error is non-nil.
-// This shouldn't be used directly, and is exported for use in the extension
-// sub-packages.
-// If you need identifiers, use the appropriate constructor.
-// e.g., For a window id, use xproto.NewWindowId. For
-// a new pixmap id, use xproto.NewPixmapId. And so on.
-func (c *Conn) NewId() (uint32, error) {
-	xid := <-c.xidChan
-	if xid.err != nil {
-		return 0, xid.err
-	}
-	return xid.id, nil
-}
-
-// xid encapsulates a resource identifier being sent over the Conn.xidChan
-// channel. If no new resource id can be generated, id is set to 0 and a
-// non-nil error is set in xid.err.
-type xid struct {
-	id  uint32
-	err error
-}
-
-// generateXids sends new Ids down the channel for NewId to use.
-// generateXids should be run in its own goroutine.
-// This needs to be updated to use the XC Misc extension once we run out of
-// new ids.
-// Thanks to libxcb/src/xcb_xid.c. This code is greatly inspired by it.
-func (conn *Conn) generateXIds() {
-	defer close(conn.xidChan)
-
-	// This requires some explanation. From the horse's mouth:
-	// "The resource-id-mask contains a single contiguous set of bits (at least
-	// 18).  The client allocates resource IDs for types WINDOW, PIXMAP,
-	// CURSOR, FONT, GCONTEXT, and COLORMAP by choosing a value with only some
-	// subset of these bits set and ORing it with resource-id-base. Only values
-	// constructed in this way can be used to name newly created resources over
-	// this connection."
-	// So for example (using 8 bit integers), the mask might look like:
-	// 00111000
-	// So that valid values would be 00101000, 00110000, 00001000, and so on.
-	// Thus, the idea is to increment it by the place of the last least
-	// significant '1'. In this case, that value would be 00001000. To get
-	// that value, we can AND the original mask with its two's complement:
-	// 00111000 & 11001000 = 00001000.
-	// And we use that value to increment the last resource id to get a new one.
-	// (And then, of course, we OR it with resource-id-base.)
-	inc := conn.setupResourceIdMask & -conn.setupResourceIdMask
-	max := conn.setupResourceIdMask
-	last := uint32(0)
-	for {
-		// TODO: Use the XC Misc extension to look for released ids.
-		if last > 0 && last >= max-inc+1 {
-			conn.xidChan <- xid{
-				id: 0,
-				err: errors.New("There are no more available resource" +
-					"identifiers."),
-			}
-		}
-
-		last += inc
-		conn.xidChan <- xid{
-			id:  last | conn.setupResourceIdBase,
-			err: nil,
-		}
-	}
-}
-
-// newSeqId fetches the next sequence id from the Conn.seqChan channel.
-func (c *Conn) newSequenceId() uint16 {
-	return <-c.seqChan
-}
-
-// generateSeqIds returns new sequence ids. It is meant to be run in its
-// own goroutine.
-// A sequence id is generated for *every* request. It's the identifier used
-// to match up replies with requests.
-// Since sequence ids can only be 16 bit integers we start over at zero when it
-// comes time to wrap.
-// N.B. As long as the cookie buffer is less than 2^16, there are no limitations
-// on the number (or kind) of requests made in sequence.
-func (c *Conn) generateSeqIds() {
-	defer close(c.seqChan)
-
-	seqid := uint16(1)
-	for {
-		c.seqChan <- seqid
-		if seqid == uint16((1<<16)-1) {
-			seqid = 0
-		} else {
-			seqid++
-		}
-	}
-}
-
-// request encapsulates a buffer of raw bytes (containing the request data)
-// and a cookie, which when combined represents a single request.
-// The cookie is used to match up the reply/error.
-type request struct {
-	buf    []byte
-	cookie *Cookie
-
-	// seq is closed when the request (cookie) has been sequenced by the Conn.
-	seq chan struct{}
-}
-
-// NewRequest takes the bytes and a cookie of a particular request, constructs
-// a request type, and sends it over the Conn.reqChan channel.
-// Note that the sequence number is added to the cookie after it is sent
-// over the request channel, but before it is sent to X.
-//
-// Note that you may safely use NewRequest to send arbitrary byte requests
-// to X. The resulting cookie can be used just like any normal cookie and
-// abides by the same rules, except that for replies, you'll get back the
-// raw byte data. This may be useful for performance critical sections where
-// every allocation counts, since all X requests in XGB allocate a new byte
-// slice. In contrast, NewRequest allocates one small request struct and
-// nothing else. (Except when the cookie buffer is full and has to be flushed.)
-//
-// If you're using NewRequest manually, you'll need to use NewCookie to create
-// a new cookie.
-//
-// In all likelihood, you should be able to copy and paste with some minor
-// edits the generated code for the request you want to issue.
-func (c *Conn) NewRequest(buf []byte, cookie *Cookie) {
-	seq := make(chan struct{})
-	c.reqChan <- &request{buf: buf, cookie: cookie, seq: seq}
-	<-seq
-}
-
-// sendRequests is run as a single goroutine that takes requests and writes
-// the bytes to the wire and adds the cookie to the cookie queue.
-// It is meant to be run as its own goroutine.
-func (c *Conn) sendRequests() {
-	defer close(c.cookieChan)
-
-	for req := range c.reqChan {
-		// ho there! if the cookie channel is nearly full, force a round
-		// trip to clear out the cookie buffer.
-		// Note that we circumvent the request channel, because we're *in*
-		// the request channel.
-		if len(c.cookieChan) == cookieBuffer-1 {
-			if err := c.noop(); err != nil {
-				// Shut everything down.
-				break
-			}
-		}
-		req.cookie.Sequence = c.newSequenceId()
-		close(req.seq)
-		c.cookieChan <- req.cookie
-		c.writeBuffer(req.buf)
-	}
-	response := make(chan struct{})
-	c.closing <- response
-	c.noop() // Flush the response reading goroutine, ignore error.
-	<-response
-	c.conn.Close()
-}
-
-// noop circumvents the usual request sending goroutines and forces a round
-// trip request manually.
-func (c *Conn) noop() error {
-	cookie := c.NewCookie(true, true)
-	cookie.Sequence = c.newSequenceId()
-	c.cookieChan <- cookie
-	if err := c.writeBuffer(c.getInputFocusRequest()); err != nil {
-		return err
-	}
-	cookie.Reply() // wait for the buffer to clear
-	return nil
-}
-
-// writeBuffer is a convenience function for writing a byte slice to the wire.
-func (c *Conn) writeBuffer(buf []byte) error {
-	if _, err := c.conn.Write(buf); err != nil {
-		Logger.Printf("A write error is unrecoverable: %s", err)
-		return err
-	} else {
-		return nil
-	}
-}
-
-// readResponses is a goroutine that reads events, errors and
-// replies off the wire.
-// When an event is read, it is always added to the event channel.
-// When an error is read, if it corresponds to an existing checked cookie,
-// it is sent to that cookie's error channel. Otherwise it is added to the
-// event channel.
-// When a reply is read, it is added to the corresponding cookie's reply
-// channel. (It is an error if no such cookie exists in this case.)
-// Finally, cookies that came "before" this reply are always cleaned up.
-func (c *Conn) readResponses() {
-	defer close(c.eventChan)
-
-	var (
-		err        Error
-		seq        uint16
-		replyBytes []byte
-	)
-
-	for {
-		select {
-		case respond := <-c.closing:
-			respond <- struct{}{}
-			return
-		default:
-		}
-
-		buf := make([]byte, 32)
-		err, seq = nil, 0
-		if _, err := io.ReadFull(c.conn, buf); err != nil {
-			Logger.Printf("A read error is unrecoverable: %s", err)
-			c.eventChan <- err
-			c.Close()
-			continue
-		}
-		switch buf[0] {
-		case 0: // This is an error
-			// Use the constructor function for this error (that is auto
-			// generated) by looking it up by the error number.
-			newErrFun, ok := NewErrorFuncs[int(buf[1])]
-			if !ok {
-				Logger.Printf("BUG: Could not find error constructor function "+
-					"for error with number %d.", buf[1])
-				continue
-			}
-			err = newErrFun(buf)
-			seq = err.SequenceId()
-
-			// This error is either sent to the event channel or a specific
-			// cookie's error channel below.
-		case 1: // This is a reply
-			seq = Get16(buf[2:])
-
-			// check to see if this reply has more bytes to be read
-			size := Get32(buf[4:])
-			if size > 0 {
-				byteCount := 32 + size*4
-				biggerBuf := make([]byte, byteCount)
-				copy(biggerBuf[:32], buf)
-				if _, err := io.ReadFull(c.conn, biggerBuf[32:]); err != nil {
-					Logger.Printf("A read error is unrecoverable: %s", err)
-					c.eventChan <- err
-					c.Close()
-					continue
-				}
-				replyBytes = biggerBuf
-			} else {
-				replyBytes = buf
-			}
-
-			// This reply is sent to its corresponding cookie below.
-		default: // This is an event
-			// Use the constructor function for this event (like for errors,
-			// and is also auto generated) by looking it up by the event number.
-			// Note that we AND the event number with 127 so that we ignore
-			// the most significant bit (which is set when it was sent from
-			// a SendEvent request).
-			evNum := int(buf[0] & 127)
-			newEventFun, ok := NewEventFuncs[evNum]
-			if !ok {
-				Logger.Printf("BUG: Could not find event construct function "+
-					"for event with number %d.", evNum)
-				continue
-			}
-			c.eventChan <- newEventFun(buf)
-			continue
-		}
-
-		// At this point, we have a sequence number and we're either
-		// processing an error or a reply, which are both responses to
-		// requests. So all we have to do is find the cookie corresponding
-		// to this error/reply, and send the appropriate data to it.
-		// In doing so, we make sure that any cookies that came before it
-		// are marked as successful if they are void and checked.
-		// If there's a cookie that requires a reply that is before this
-		// reply, then something is wrong.
-		for cookie := range c.cookieChan {
-			// This is the cookie we're looking for. Process and break.
-			if cookie.Sequence == seq {
-				if err != nil { // this is an error to a request
-					// synchronous processing
-					if cookie.errorChan != nil {
-						cookie.errorChan <- err
-					} else { // asynchronous processing
-						c.eventChan <- err
-						// if this is an unchecked reply, ping the cookie too
-						if cookie.pingChan != nil {
-							cookie.pingChan <- true
-						}
-					}
-				} else { // this is a reply
-					if cookie.replyChan == nil {
-						Logger.Printf("Reply with sequence id %d does not "+
-							"have a cookie with a valid reply channel.", seq)
-						continue
-					} else {
-						cookie.replyChan <- replyBytes
-					}
-				}
-				break
-			}
-
-			switch {
-			// Checked requests with replies
-			case cookie.replyChan != nil && cookie.errorChan != nil:
-				Logger.Printf("Found cookie with sequence id %d that is "+
-					"expecting a reply but will never get it. Currently "+
-					"on sequence number %d", cookie.Sequence, seq)
-			// Unchecked requests with replies
-			case cookie.replyChan != nil && cookie.pingChan != nil:
-				Logger.Printf("Found cookie with sequence id %d that is "+
-					"expecting a reply (and not an error) but will never "+
-					"get it. Currently on sequence number %d",
-					cookie.Sequence, seq)
-			// Checked requests without replies
-			case cookie.pingChan != nil && cookie.errorChan != nil:
-				cookie.pingChan <- true
-				// Unchecked requests without replies don't have any channels,
-				// so we can't do anything with them except let them pass by.
-			}
-		}
-	}
-}
-
-// processEventOrError takes an eventOrError, type switches on it,
-// and returns it in Go idiomatic style.
-func processEventOrError(everr eventOrError) (Event, Error) {
-	switch ee := everr.(type) {
-	case Event:
-		return ee, nil
-	case Error:
-		return nil, ee
-	default:
-		Logger.Printf("Invalid event/error type: %T", everr)
-		return nil, nil
-	}
-}
-
-// WaitForEvent returns the next event from the server.
-// It will block until an event is available.
-// WaitForEvent returns either an Event or an Error. (Returning both
-// is a bug.) Note than an Error here is an X error and not an XGB error. That
-// is, X errors are sometimes completely expected (and you may want to ignore
-// them in some cases).
-//
-// If both the event and error are nil, then the connection has been closed.
-func (c *Conn) WaitForEvent() (Event, Error) {
-	return processEventOrError(<-c.eventChan)
-}
-
-// PollForEvent returns the next event from the server if one is available in
-// the internal queue without blocking. Note that unlike WaitForEvent, both
-// Event and Error could be nil. Indeed, they are both nil when the event queue
-// is empty.
-func (c *Conn) PollForEvent() (Event, Error) {
-	select {
-	case everr := <-c.eventChan:
-		return processEventOrError(everr)
-	default:
-		return nil, nil
-	}
-}
diff --git a/shiny/internal/xgb/xproto/xproto.go b/shiny/internal/xgb/xproto/xproto.go
deleted file mode 100644
index 5f9a566..0000000
--- a/shiny/internal/xgb/xproto/xproto.go
+++ /dev/null
@@ -1,14910 +0,0 @@
-// Package xproto is the X client API for the  extension.
-package xproto
-
-// This file is automatically generated from xproto.xml. Edit at your peril!
-
-import (
-	"golang.org/x/exp/shiny/internal/xgb"
-)
-
-// Setup parses the setup bytes retrieved when
-// connecting into a SetupInfo struct.
-func Setup(c *xgb.Conn) *SetupInfo {
-	setup := new(SetupInfo)
-	SetupInfoRead(c.SetupBytes, setup)
-	return setup
-}
-
-// DefaultScreen gets the default screen info from SetupInfo.
-func (s *SetupInfo) DefaultScreen(c *xgb.Conn) *ScreenInfo {
-	return &s.Roots[c.DefaultScreen]
-}
-
-// BadAccess is the error number for a BadAccess.
-const BadAccess = 10
-
-type AccessError RequestError
-
-// AccessErrorNew constructs a AccessError value that implements xgb.Error from a byte slice.
-func AccessErrorNew(buf []byte) xgb.Error {
-	v := AccessError(RequestErrorNew(buf).(RequestError))
-	v.NiceName = "Access"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadAccess error.
-// This is mostly used internally.
-func (err AccessError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadAccess error. If no bad value exists, 0 is returned.
-func (err AccessError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadAccess error.
-func (err AccessError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadAccess {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[10] = AccessErrorNew
-}
-
-const (
-	AccessControlDisable = 0
-	AccessControlEnable  = 1
-)
-
-// BadAlloc is the error number for a BadAlloc.
-const BadAlloc = 11
-
-type AllocError RequestError
-
-// AllocErrorNew constructs a AllocError value that implements xgb.Error from a byte slice.
-func AllocErrorNew(buf []byte) xgb.Error {
-	v := AllocError(RequestErrorNew(buf).(RequestError))
-	v.NiceName = "Alloc"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadAlloc error.
-// This is mostly used internally.
-func (err AllocError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadAlloc error. If no bad value exists, 0 is returned.
-func (err AllocError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadAlloc error.
-func (err AllocError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadAlloc {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[11] = AllocErrorNew
-}
-
-const (
-	AllowAsyncPointer   = 0
-	AllowSyncPointer    = 1
-	AllowReplayPointer  = 2
-	AllowAsyncKeyboard  = 3
-	AllowSyncKeyboard   = 4
-	AllowReplayKeyboard = 5
-	AllowAsyncBoth      = 6
-	AllowSyncBoth       = 7
-)
-
-type Arc struct {
-	X      int16
-	Y      int16
-	Width  uint16
-	Height uint16
-	Angle1 int16
-	Angle2 int16
-}
-
-// ArcRead reads a byte slice into a Arc value.
-func ArcRead(buf []byte, v *Arc) int {
-	b := 0
-
-	v.X = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Width = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Height = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Angle1 = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Angle2 = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	return b
-}
-
-// ArcReadList reads a byte slice into a list of Arc values.
-func ArcReadList(buf []byte, dest []Arc) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Arc{}
-		b += ArcRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Arc value to a byte slice.
-func (v Arc) Bytes() []byte {
-	buf := make([]byte, 12)
-	b := 0
-
-	xgb.Put16(buf[b:], uint16(v.X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y))
-	b += 2
-
-	xgb.Put16(buf[b:], v.Width)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Height)
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Angle1))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Angle2))
-	b += 2
-
-	return buf[:b]
-}
-
-// ArcListBytes writes a list of Arc values to a byte slice.
-func ArcListBytes(buf []byte, list []Arc) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-const (
-	ArcModeChord    = 0
-	ArcModePieSlice = 1
-)
-
-type Atom uint32
-
-func NewAtomId(c *xgb.Conn) (Atom, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Atom(id), nil
-}
-
-const (
-	AtomNone               = 0
-	AtomAny                = 0
-	AtomPrimary            = 1
-	AtomSecondary          = 2
-	AtomArc                = 3
-	AtomAtom               = 4
-	AtomBitmap             = 5
-	AtomCardinal           = 6
-	AtomColormap           = 7
-	AtomCursor             = 8
-	AtomCutBuffer0         = 9
-	AtomCutBuffer1         = 10
-	AtomCutBuffer2         = 11
-	AtomCutBuffer3         = 12
-	AtomCutBuffer4         = 13
-	AtomCutBuffer5         = 14
-	AtomCutBuffer6         = 15
-	AtomCutBuffer7         = 16
-	AtomDrawable           = 17
-	AtomFont               = 18
-	AtomInteger            = 19
-	AtomPixmap             = 20
-	AtomPoint              = 21
-	AtomRectangle          = 22
-	AtomResourceManager    = 23
-	AtomRgbColorMap        = 24
-	AtomRgbBestMap         = 25
-	AtomRgbBlueMap         = 26
-	AtomRgbDefaultMap      = 27
-	AtomRgbGrayMap         = 28
-	AtomRgbGreenMap        = 29
-	AtomRgbRedMap          = 30
-	AtomString             = 31
-	AtomVisualid           = 32
-	AtomWindow             = 33
-	AtomWmCommand          = 34
-	AtomWmHints            = 35
-	AtomWmClientMachine    = 36
-	AtomWmIconName         = 37
-	AtomWmIconSize         = 38
-	AtomWmName             = 39
-	AtomWmNormalHints      = 40
-	AtomWmSizeHints        = 41
-	AtomWmZoomHints        = 42
-	AtomMinSpace           = 43
-	AtomNormSpace          = 44
-	AtomMaxSpace           = 45
-	AtomEndSpace           = 46
-	AtomSuperscriptX       = 47
-	AtomSuperscriptY       = 48
-	AtomSubscriptX         = 49
-	AtomSubscriptY         = 50
-	AtomUnderlinePosition  = 51
-	AtomUnderlineThickness = 52
-	AtomStrikeoutAscent    = 53
-	AtomStrikeoutDescent   = 54
-	AtomItalicAngle        = 55
-	AtomXHeight            = 56
-	AtomQuadWidth          = 57
-	AtomWeight             = 58
-	AtomPointSize          = 59
-	AtomResolution         = 60
-	AtomCopyright          = 61
-	AtomNotice             = 62
-	AtomFontName           = 63
-	AtomFamilyName         = 64
-	AtomFullName           = 65
-	AtomCapHeight          = 66
-	AtomWmClass            = 67
-	AtomWmTransientFor     = 68
-)
-
-// BadAtom is the error number for a BadAtom.
-const BadAtom = 5
-
-type AtomError ValueError
-
-// AtomErrorNew constructs a AtomError value that implements xgb.Error from a byte slice.
-func AtomErrorNew(buf []byte) xgb.Error {
-	v := AtomError(ValueErrorNew(buf).(ValueError))
-	v.NiceName = "Atom"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadAtom error.
-// This is mostly used internally.
-func (err AtomError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadAtom error. If no bad value exists, 0 is returned.
-func (err AtomError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadAtom error.
-func (err AtomError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadAtom {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[5] = AtomErrorNew
-}
-
-const (
-	AutoRepeatModeOff     = 0
-	AutoRepeatModeOn      = 1
-	AutoRepeatModeDefault = 2
-)
-
-const (
-	BackPixmapNone           = 0
-	BackPixmapParentRelative = 1
-)
-
-const (
-	BackingStoreNotUseful  = 0
-	BackingStoreWhenMapped = 1
-	BackingStoreAlways     = 2
-)
-
-const (
-	BlankingNotPreferred = 0
-	BlankingPreferred    = 1
-	BlankingDefault      = 2
-)
-
-type Button byte
-
-const (
-	ButtonIndexAny = 0
-	ButtonIndex1   = 1
-	ButtonIndex2   = 2
-	ButtonIndex3   = 3
-	ButtonIndex4   = 4
-	ButtonIndex5   = 5
-)
-
-const (
-	ButtonMask1   = 256
-	ButtonMask2   = 512
-	ButtonMask3   = 1024
-	ButtonMask4   = 2048
-	ButtonMask5   = 4096
-	ButtonMaskAny = 32768
-)
-
-// ButtonPress is the event number for a ButtonPressEvent.
-const ButtonPress = 4
-
-type ButtonPressEvent struct {
-	Sequence   uint16
-	Detail     Button
-	Time       Timestamp
-	Root       Window
-	Event      Window
-	Child      Window
-	RootX      int16
-	RootY      int16
-	EventX     int16
-	EventY     int16
-	State      uint16
-	SameScreen bool
-	// padding: 1 bytes
-}
-
-// ButtonPressEventNew constructs a ButtonPressEvent value that implements xgb.Event from a byte slice.
-func ButtonPressEventNew(buf []byte) xgb.Event {
-	v := ButtonPressEvent{}
-	b := 1 // don't read event number
-
-	v.Detail = Button(buf[b])
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Time = Timestamp(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Root = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Child = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.RootX = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.RootY = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.EventX = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.EventY = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.State = xgb.Get16(buf[b:])
-	b += 2
-
-	if buf[b] == 1 {
-		v.SameScreen = true
-	} else {
-		v.SameScreen = false
-	}
-	b += 1
-
-	b += 1 // padding
-
-	return v
-}
-
-// Bytes writes a ButtonPressEvent value to a byte slice.
-func (v ButtonPressEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 4
-	b += 1
-
-	buf[b] = byte(v.Detail)
-	b += 1
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Time))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Root))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Child))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(v.RootX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.RootY))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.EventX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.EventY))
-	b += 2
-
-	xgb.Put16(buf[b:], v.State)
-	b += 2
-
-	if v.SameScreen {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	b += 1 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the ButtonPress event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v ButtonPressEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of ButtonPressEvent.
-func (v ButtonPressEvent) String() string {
-	fieldVals := make([]string, 0, 12)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail))
-	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
-	fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY))
-	fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State))
-	fieldVals = append(fieldVals, xgb.Sprintf("SameScreen: %t", v.SameScreen))
-	return "ButtonPress {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[4] = ButtonPressEventNew
-}
-
-// ButtonRelease is the event number for a ButtonReleaseEvent.
-const ButtonRelease = 5
-
-type ButtonReleaseEvent ButtonPressEvent
-
-// ButtonReleaseEventNew constructs a ButtonReleaseEvent value that implements xgb.Event from a byte slice.
-func ButtonReleaseEventNew(buf []byte) xgb.Event {
-	return ButtonReleaseEvent(ButtonPressEventNew(buf).(ButtonPressEvent))
-}
-
-// Bytes writes a ButtonReleaseEvent value to a byte slice.
-func (v ButtonReleaseEvent) Bytes() []byte {
-	return ButtonPressEvent(v).Bytes()
-}
-
-// SequenceId returns the sequence id attached to the ButtonRelease event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v ButtonReleaseEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-func (v ButtonReleaseEvent) String() string {
-	fieldVals := make([]string, 0, 12)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail))
-	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
-	fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY))
-	fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State))
-	fieldVals = append(fieldVals, xgb.Sprintf("SameScreen: %t", v.SameScreen))
-	return "ButtonRelease {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[5] = ButtonReleaseEventNew
-}
-
-const (
-	CapStyleNotLast    = 0
-	CapStyleButt       = 1
-	CapStyleRound      = 2
-	CapStyleProjecting = 3
-)
-
-type Char2b struct {
-	Byte1 byte
-	Byte2 byte
-}
-
-// Char2bRead reads a byte slice into a Char2b value.
-func Char2bRead(buf []byte, v *Char2b) int {
-	b := 0
-
-	v.Byte1 = buf[b]
-	b += 1
-
-	v.Byte2 = buf[b]
-	b += 1
-
-	return b
-}
-
-// Char2bReadList reads a byte slice into a list of Char2b values.
-func Char2bReadList(buf []byte, dest []Char2b) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Char2b{}
-		b += Char2bRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Char2b value to a byte slice.
-func (v Char2b) Bytes() []byte {
-	buf := make([]byte, 2)
-	b := 0
-
-	buf[b] = v.Byte1
-	b += 1
-
-	buf[b] = v.Byte2
-	b += 1
-
-	return buf[:b]
-}
-
-// Char2bListBytes writes a list of Char2b values to a byte slice.
-func Char2bListBytes(buf []byte, list []Char2b) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Charinfo struct {
-	LeftSideBearing  int16
-	RightSideBearing int16
-	CharacterWidth   int16
-	Ascent           int16
-	Descent          int16
-	Attributes       uint16
-}
-
-// CharinfoRead reads a byte slice into a Charinfo value.
-func CharinfoRead(buf []byte, v *Charinfo) int {
-	b := 0
-
-	v.LeftSideBearing = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.RightSideBearing = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.CharacterWidth = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Ascent = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Descent = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Attributes = xgb.Get16(buf[b:])
-	b += 2
-
-	return b
-}
-
-// CharinfoReadList reads a byte slice into a list of Charinfo values.
-func CharinfoReadList(buf []byte, dest []Charinfo) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Charinfo{}
-		b += CharinfoRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Charinfo value to a byte slice.
-func (v Charinfo) Bytes() []byte {
-	buf := make([]byte, 12)
-	b := 0
-
-	xgb.Put16(buf[b:], uint16(v.LeftSideBearing))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.RightSideBearing))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.CharacterWidth))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Ascent))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Descent))
-	b += 2
-
-	xgb.Put16(buf[b:], v.Attributes)
-	b += 2
-
-	return buf[:b]
-}
-
-// CharinfoListBytes writes a list of Charinfo values to a byte slice.
-func CharinfoListBytes(buf []byte, list []Charinfo) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-const (
-	CirculateRaiseLowest  = 0
-	CirculateLowerHighest = 1
-)
-
-// CirculateNotify is the event number for a CirculateNotifyEvent.
-const CirculateNotify = 26
-
-type CirculateNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Event  Window
-	Window Window
-	// padding: 4 bytes
-	Place byte
-	// padding: 3 bytes
-}
-
-// CirculateNotifyEventNew constructs a CirculateNotifyEvent value that implements xgb.Event from a byte slice.
-func CirculateNotifyEventNew(buf []byte) xgb.Event {
-	v := CirculateNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	b += 4 // padding
-
-	v.Place = buf[b]
-	b += 1
-
-	b += 3 // padding
-
-	return v
-}
-
-// Bytes writes a CirculateNotifyEvent value to a byte slice.
-func (v CirculateNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 26
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	b += 4 // padding
-
-	buf[b] = v.Place
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the CirculateNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v CirculateNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of CirculateNotifyEvent.
-func (v CirculateNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 6)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("Place: %d", v.Place))
-	return "CirculateNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[26] = CirculateNotifyEventNew
-}
-
-// CirculateRequest is the event number for a CirculateRequestEvent.
-const CirculateRequest = 27
-
-type CirculateRequestEvent CirculateNotifyEvent
-
-// CirculateRequestEventNew constructs a CirculateRequestEvent value that implements xgb.Event from a byte slice.
-func CirculateRequestEventNew(buf []byte) xgb.Event {
-	return CirculateRequestEvent(CirculateNotifyEventNew(buf).(CirculateNotifyEvent))
-}
-
-// Bytes writes a CirculateRequestEvent value to a byte slice.
-func (v CirculateRequestEvent) Bytes() []byte {
-	return CirculateNotifyEvent(v).Bytes()
-}
-
-// SequenceId returns the sequence id attached to the CirculateRequest event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v CirculateRequestEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-func (v CirculateRequestEvent) String() string {
-	fieldVals := make([]string, 0, 6)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("Place: %d", v.Place))
-	return "CirculateRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[27] = CirculateRequestEventNew
-}
-
-// ClientMessage is the event number for a ClientMessageEvent.
-const ClientMessage = 33
-
-type ClientMessageEvent struct {
-	Sequence uint16
-	Format   byte
-	Window   Window
-	Type     Atom
-	Data     ClientMessageDataUnion
-}
-
-// ClientMessageEventNew constructs a ClientMessageEvent value that implements xgb.Event from a byte slice.
-func ClientMessageEventNew(buf []byte) xgb.Event {
-	v := ClientMessageEvent{}
-	b := 1 // don't read event number
-
-	v.Format = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Type = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Data = ClientMessageDataUnion{}
-	b += ClientMessageDataUnionRead(buf[b:], &v.Data)
-
-	return v
-}
-
-// Bytes writes a ClientMessageEvent value to a byte slice.
-func (v ClientMessageEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 33
-	b += 1
-
-	buf[b] = v.Format
-	b += 1
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Type))
-	b += 4
-
-	{
-		unionBytes := v.Data.Bytes()
-		copy(buf[b:], unionBytes)
-		b += len(unionBytes)
-	}
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the ClientMessage event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v ClientMessageEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of ClientMessageEvent.
-func (v ClientMessageEvent) String() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Format: %d", v.Format))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("Type: %d", v.Type))
-	return "ClientMessage {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[33] = ClientMessageEventNew
-}
-
-// ClientMessageDataUnion is a representation of the ClientMessageDataUnion union type.
-// Note that to *create* a Union, you should *never* create
-// this struct directly (unless you know what you're doing).
-// Instead use one of the following constructors for 'ClientMessageDataUnion':
-//     ClientMessageDataUnionData8New(Data8 []byte) ClientMessageDataUnion
-//     ClientMessageDataUnionData16New(Data16 []uint16) ClientMessageDataUnion
-//     ClientMessageDataUnionData32New(Data32 []uint32) ClientMessageDataUnion
-type ClientMessageDataUnion struct {
-	Data8  []byte   // size: 20
-	Data16 []uint16 // size: 20
-	Data32 []uint32 // size: 20
-}
-
-// ClientMessageDataUnionData8New constructs a new ClientMessageDataUnion union type with the Data8 field.
-func ClientMessageDataUnionData8New(Data8 []byte) ClientMessageDataUnion {
-	var b int
-	buf := make([]byte, 20)
-
-	copy(buf[b:], Data8[:20])
-	b += int(20)
-
-	// Create the Union type
-	v := ClientMessageDataUnion{}
-
-	// Now copy buf into all fields
-
-	b = 0 // always read the same bytes
-	v.Data8 = make([]byte, 20)
-	copy(v.Data8[:20], buf[b:])
-	b += int(20)
-
-	b = 0 // always read the same bytes
-	v.Data16 = make([]uint16, 10)
-	for i := 0; i < int(10); i++ {
-		v.Data16[i] = xgb.Get16(buf[b:])
-		b += 2
-	}
-
-	b = 0 // always read the same bytes
-	v.Data32 = make([]uint32, 5)
-	for i := 0; i < int(5); i++ {
-		v.Data32[i] = xgb.Get32(buf[b:])
-		b += 4
-	}
-
-	return v
-}
-
-// ClientMessageDataUnionData16New constructs a new ClientMessageDataUnion union type with the Data16 field.
-func ClientMessageDataUnionData16New(Data16 []uint16) ClientMessageDataUnion {
-	var b int
-	buf := make([]byte, 20)
-
-	for i := 0; i < int(10); i++ {
-		xgb.Put16(buf[b:], Data16[i])
-		b += 2
-	}
-
-	// Create the Union type
-	v := ClientMessageDataUnion{}
-
-	// Now copy buf into all fields
-
-	b = 0 // always read the same bytes
-	v.Data8 = make([]byte, 20)
-	copy(v.Data8[:20], buf[b:])
-	b += int(20)
-
-	b = 0 // always read the same bytes
-	v.Data16 = make([]uint16, 10)
-	for i := 0; i < int(10); i++ {
-		v.Data16[i] = xgb.Get16(buf[b:])
-		b += 2
-	}
-
-	b = 0 // always read the same bytes
-	v.Data32 = make([]uint32, 5)
-	for i := 0; i < int(5); i++ {
-		v.Data32[i] = xgb.Get32(buf[b:])
-		b += 4
-	}
-
-	return v
-}
-
-// ClientMessageDataUnionData32New constructs a new ClientMessageDataUnion union type with the Data32 field.
-func ClientMessageDataUnionData32New(Data32 []uint32) ClientMessageDataUnion {
-	var b int
-	buf := make([]byte, 20)
-
-	for i := 0; i < int(5); i++ {
-		xgb.Put32(buf[b:], Data32[i])
-		b += 4
-	}
-
-	// Create the Union type
-	v := ClientMessageDataUnion{}
-
-	// Now copy buf into all fields
-
-	b = 0 // always read the same bytes
-	v.Data8 = make([]byte, 20)
-	copy(v.Data8[:20], buf[b:])
-	b += int(20)
-
-	b = 0 // always read the same bytes
-	v.Data16 = make([]uint16, 10)
-	for i := 0; i < int(10); i++ {
-		v.Data16[i] = xgb.Get16(buf[b:])
-		b += 2
-	}
-
-	b = 0 // always read the same bytes
-	v.Data32 = make([]uint32, 5)
-	for i := 0; i < int(5); i++ {
-		v.Data32[i] = xgb.Get32(buf[b:])
-		b += 4
-	}
-
-	return v
-}
-
-// ClientMessageDataUnionRead reads a byte slice into a ClientMessageDataUnion value.
-func ClientMessageDataUnionRead(buf []byte, v *ClientMessageDataUnion) int {
-	var b int
-
-	b = 0 // re-read the same bytes
-	v.Data8 = make([]byte, 20)
-	copy(v.Data8[:20], buf[b:])
-	b += int(20)
-
-	b = 0 // re-read the same bytes
-	v.Data16 = make([]uint16, 10)
-	for i := 0; i < int(10); i++ {
-		v.Data16[i] = xgb.Get16(buf[b:])
-		b += 2
-	}
-
-	b = 0 // re-read the same bytes
-	v.Data32 = make([]uint32, 5)
-	for i := 0; i < int(5); i++ {
-		v.Data32[i] = xgb.Get32(buf[b:])
-		b += 4
-	}
-
-	return 20
-}
-
-// ClientMessageDataUnionReadList reads a byte slice into a list of ClientMessageDataUnion values.
-func ClientMessageDataUnionReadList(buf []byte, dest []ClientMessageDataUnion) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = ClientMessageDataUnion{}
-		b += ClientMessageDataUnionRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a ClientMessageDataUnion value to a byte slice.
-// Each field in a union must contain the same data.
-// So simply pick the first field and write that to the wire.
-func (v ClientMessageDataUnion) Bytes() []byte {
-	buf := make([]byte, 20)
-	b := 0
-
-	copy(buf[b:], v.Data8[:20])
-	b += int(20)
-	return buf
-}
-
-// ClientMessageDataUnionListBytes writes a list of ClientMessageDataUnion values to a byte slice.
-func ClientMessageDataUnionListBytes(buf []byte, list []ClientMessageDataUnion) int {
-	b := 0
-	var unionBytes []byte
-	for _, item := range list {
-		unionBytes = item.Bytes()
-		copy(buf[b:], unionBytes)
-		b += xgb.Pad(len(unionBytes))
-	}
-	return b
-}
-
-const (
-	ClipOrderingUnsorted = 0
-	ClipOrderingYSorted  = 1
-	ClipOrderingYXSorted = 2
-	ClipOrderingYXBanded = 3
-)
-
-const (
-	CloseDownDestroyAll      = 0
-	CloseDownRetainPermanent = 1
-	CloseDownRetainTemporary = 2
-)
-
-const (
-	ColorFlagRed   = 1
-	ColorFlagGreen = 2
-	ColorFlagBlue  = 4
-)
-
-type Coloritem struct {
-	Pixel uint32
-	Red   uint16
-	Green uint16
-	Blue  uint16
-	Flags byte
-	// padding: 1 bytes
-}
-
-// ColoritemRead reads a byte slice into a Coloritem value.
-func ColoritemRead(buf []byte, v *Coloritem) int {
-	b := 0
-
-	v.Pixel = xgb.Get32(buf[b:])
-	b += 4
-
-	v.Red = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Green = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Blue = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Flags = buf[b]
-	b += 1
-
-	b += 1 // padding
-
-	return b
-}
-
-// ColoritemReadList reads a byte slice into a list of Coloritem values.
-func ColoritemReadList(buf []byte, dest []Coloritem) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Coloritem{}
-		b += ColoritemRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Coloritem value to a byte slice.
-func (v Coloritem) Bytes() []byte {
-	buf := make([]byte, 12)
-	b := 0
-
-	xgb.Put32(buf[b:], v.Pixel)
-	b += 4
-
-	xgb.Put16(buf[b:], v.Red)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Green)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Blue)
-	b += 2
-
-	buf[b] = v.Flags
-	b += 1
-
-	b += 1 // padding
-
-	return buf[:b]
-}
-
-// ColoritemListBytes writes a list of Coloritem values to a byte slice.
-func ColoritemListBytes(buf []byte, list []Coloritem) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Colormap uint32
-
-func NewColormapId(c *xgb.Conn) (Colormap, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Colormap(id), nil
-}
-
-// BadColormap is the error number for a BadColormap.
-const BadColormap = 12
-
-type ColormapError ValueError
-
-// ColormapErrorNew constructs a ColormapError value that implements xgb.Error from a byte slice.
-func ColormapErrorNew(buf []byte) xgb.Error {
-	v := ColormapError(ValueErrorNew(buf).(ValueError))
-	v.NiceName = "Colormap"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadColormap error.
-// This is mostly used internally.
-func (err ColormapError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadColormap error. If no bad value exists, 0 is returned.
-func (err ColormapError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadColormap error.
-func (err ColormapError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadColormap {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[12] = ColormapErrorNew
-}
-
-const (
-	ColormapNone = 0
-)
-
-const (
-	ColormapAllocNone = 0
-	ColormapAllocAll  = 1
-)
-
-// ColormapNotify is the event number for a ColormapNotifyEvent.
-const ColormapNotify = 32
-
-type ColormapNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Window   Window
-	Colormap Colormap
-	New      bool
-	State    byte
-	// padding: 2 bytes
-}
-
-// ColormapNotifyEventNew constructs a ColormapNotifyEvent value that implements xgb.Event from a byte slice.
-func ColormapNotifyEventNew(buf []byte) xgb.Event {
-	v := ColormapNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Colormap = Colormap(xgb.Get32(buf[b:]))
-	b += 4
-
-	if buf[b] == 1 {
-		v.New = true
-	} else {
-		v.New = false
-	}
-	b += 1
-
-	v.State = buf[b]
-	b += 1
-
-	b += 2 // padding
-
-	return v
-}
-
-// Bytes writes a ColormapNotifyEvent value to a byte slice.
-func (v ColormapNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 32
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Colormap))
-	b += 4
-
-	if v.New {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	buf[b] = v.State
-	b += 1
-
-	b += 2 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the ColormapNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v ColormapNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of ColormapNotifyEvent.
-func (v ColormapNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 6)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("Colormap: %d", v.Colormap))
-	fieldVals = append(fieldVals, xgb.Sprintf("New: %t", v.New))
-	fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State))
-	return "ColormapNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[32] = ColormapNotifyEventNew
-}
-
-const (
-	ColormapStateUninstalled = 0
-	ColormapStateInstalled   = 1
-)
-
-const (
-	ConfigWindowX           = 1
-	ConfigWindowY           = 2
-	ConfigWindowWidth       = 4
-	ConfigWindowHeight      = 8
-	ConfigWindowBorderWidth = 16
-	ConfigWindowSibling     = 32
-	ConfigWindowStackMode   = 64
-)
-
-// ConfigureNotify is the event number for a ConfigureNotifyEvent.
-const ConfigureNotify = 22
-
-type ConfigureNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Event            Window
-	Window           Window
-	AboveSibling     Window
-	X                int16
-	Y                int16
-	Width            uint16
-	Height           uint16
-	BorderWidth      uint16
-	OverrideRedirect bool
-	// padding: 1 bytes
-}
-
-// ConfigureNotifyEventNew constructs a ConfigureNotifyEvent value that implements xgb.Event from a byte slice.
-func ConfigureNotifyEventNew(buf []byte) xgb.Event {
-	v := ConfigureNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.AboveSibling = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.X = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Width = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Height = xgb.Get16(buf[b:])
-	b += 2
-
-	v.BorderWidth = xgb.Get16(buf[b:])
-	b += 2
-
-	if buf[b] == 1 {
-		v.OverrideRedirect = true
-	} else {
-		v.OverrideRedirect = false
-	}
-	b += 1
-
-	b += 1 // padding
-
-	return v
-}
-
-// Bytes writes a ConfigureNotifyEvent value to a byte slice.
-func (v ConfigureNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 22
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.AboveSibling))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(v.X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y))
-	b += 2
-
-	xgb.Put16(buf[b:], v.Width)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Height)
-	b += 2
-
-	xgb.Put16(buf[b:], v.BorderWidth)
-	b += 2
-
-	if v.OverrideRedirect {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	b += 1 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the ConfigureNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v ConfigureNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of ConfigureNotifyEvent.
-func (v ConfigureNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 11)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("AboveSibling: %d", v.AboveSibling))
-	fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X))
-	fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y))
-	fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width))
-	fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height))
-	fieldVals = append(fieldVals, xgb.Sprintf("BorderWidth: %d", v.BorderWidth))
-	fieldVals = append(fieldVals, xgb.Sprintf("OverrideRedirect: %t", v.OverrideRedirect))
-	return "ConfigureNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[22] = ConfigureNotifyEventNew
-}
-
-// ConfigureRequest is the event number for a ConfigureRequestEvent.
-const ConfigureRequest = 23
-
-type ConfigureRequestEvent struct {
-	Sequence    uint16
-	StackMode   byte
-	Parent      Window
-	Window      Window
-	Sibling     Window
-	X           int16
-	Y           int16
-	Width       uint16
-	Height      uint16
-	BorderWidth uint16
-	ValueMask   uint16
-}
-
-// ConfigureRequestEventNew constructs a ConfigureRequestEvent value that implements xgb.Event from a byte slice.
-func ConfigureRequestEventNew(buf []byte) xgb.Event {
-	v := ConfigureRequestEvent{}
-	b := 1 // don't read event number
-
-	v.StackMode = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Parent = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Sibling = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.X = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Width = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Height = xgb.Get16(buf[b:])
-	b += 2
-
-	v.BorderWidth = xgb.Get16(buf[b:])
-	b += 2
-
-	v.ValueMask = xgb.Get16(buf[b:])
-	b += 2
-
-	return v
-}
-
-// Bytes writes a ConfigureRequestEvent value to a byte slice.
-func (v ConfigureRequestEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 23
-	b += 1
-
-	buf[b] = v.StackMode
-	b += 1
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Parent))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Sibling))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(v.X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y))
-	b += 2
-
-	xgb.Put16(buf[b:], v.Width)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Height)
-	b += 2
-
-	xgb.Put16(buf[b:], v.BorderWidth)
-	b += 2
-
-	xgb.Put16(buf[b:], v.ValueMask)
-	b += 2
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the ConfigureRequest event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v ConfigureRequestEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of ConfigureRequestEvent.
-func (v ConfigureRequestEvent) String() string {
-	fieldVals := make([]string, 0, 10)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("StackMode: %d", v.StackMode))
-	fieldVals = append(fieldVals, xgb.Sprintf("Parent: %d", v.Parent))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("Sibling: %d", v.Sibling))
-	fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X))
-	fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y))
-	fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width))
-	fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height))
-	fieldVals = append(fieldVals, xgb.Sprintf("BorderWidth: %d", v.BorderWidth))
-	fieldVals = append(fieldVals, xgb.Sprintf("ValueMask: %d", v.ValueMask))
-	return "ConfigureRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[23] = ConfigureRequestEventNew
-}
-
-const (
-	CoordModeOrigin   = 0
-	CoordModePrevious = 1
-)
-
-// CreateNotify is the event number for a CreateNotifyEvent.
-const CreateNotify = 16
-
-type CreateNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Parent           Window
-	Window           Window
-	X                int16
-	Y                int16
-	Width            uint16
-	Height           uint16
-	BorderWidth      uint16
-	OverrideRedirect bool
-	// padding: 1 bytes
-}
-
-// CreateNotifyEventNew constructs a CreateNotifyEvent value that implements xgb.Event from a byte slice.
-func CreateNotifyEventNew(buf []byte) xgb.Event {
-	v := CreateNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Parent = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.X = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Width = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Height = xgb.Get16(buf[b:])
-	b += 2
-
-	v.BorderWidth = xgb.Get16(buf[b:])
-	b += 2
-
-	if buf[b] == 1 {
-		v.OverrideRedirect = true
-	} else {
-		v.OverrideRedirect = false
-	}
-	b += 1
-
-	b += 1 // padding
-
-	return v
-}
-
-// Bytes writes a CreateNotifyEvent value to a byte slice.
-func (v CreateNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 16
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Parent))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(v.X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y))
-	b += 2
-
-	xgb.Put16(buf[b:], v.Width)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Height)
-	b += 2
-
-	xgb.Put16(buf[b:], v.BorderWidth)
-	b += 2
-
-	if v.OverrideRedirect {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	b += 1 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the CreateNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v CreateNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of CreateNotifyEvent.
-func (v CreateNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 10)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Parent: %d", v.Parent))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X))
-	fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y))
-	fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width))
-	fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height))
-	fieldVals = append(fieldVals, xgb.Sprintf("BorderWidth: %d", v.BorderWidth))
-	fieldVals = append(fieldVals, xgb.Sprintf("OverrideRedirect: %t", v.OverrideRedirect))
-	return "CreateNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[16] = CreateNotifyEventNew
-}
-
-type Cursor uint32
-
-func NewCursorId(c *xgb.Conn) (Cursor, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Cursor(id), nil
-}
-
-// BadCursor is the error number for a BadCursor.
-const BadCursor = 6
-
-type CursorError ValueError
-
-// CursorErrorNew constructs a CursorError value that implements xgb.Error from a byte slice.
-func CursorErrorNew(buf []byte) xgb.Error {
-	v := CursorError(ValueErrorNew(buf).(ValueError))
-	v.NiceName = "Cursor"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadCursor error.
-// This is mostly used internally.
-func (err CursorError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadCursor error. If no bad value exists, 0 is returned.
-func (err CursorError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadCursor error.
-func (err CursorError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadCursor {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[6] = CursorErrorNew
-}
-
-const (
-	CursorNone = 0
-)
-
-const (
-	CwBackPixmap       = 1
-	CwBackPixel        = 2
-	CwBorderPixmap     = 4
-	CwBorderPixel      = 8
-	CwBitGravity       = 16
-	CwWinGravity       = 32
-	CwBackingStore     = 64
-	CwBackingPlanes    = 128
-	CwBackingPixel     = 256
-	CwOverrideRedirect = 512
-	CwSaveUnder        = 1024
-	CwEventMask        = 2048
-	CwDontPropagate    = 4096
-	CwColormap         = 8192
-	CwCursor           = 16384
-)
-
-type DepthInfo struct {
-	Depth byte
-	// padding: 1 bytes
-	VisualsLen uint16
-	// padding: 4 bytes
-	Visuals []VisualInfo // size: xgb.Pad((int(VisualsLen) * 24))
-}
-
-// DepthInfoRead reads a byte slice into a DepthInfo value.
-func DepthInfoRead(buf []byte, v *DepthInfo) int {
-	b := 0
-
-	v.Depth = buf[b]
-	b += 1
-
-	b += 1 // padding
-
-	v.VisualsLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 4 // padding
-
-	v.Visuals = make([]VisualInfo, v.VisualsLen)
-	b += VisualInfoReadList(buf[b:], v.Visuals)
-
-	return b
-}
-
-// DepthInfoReadList reads a byte slice into a list of DepthInfo values.
-func DepthInfoReadList(buf []byte, dest []DepthInfo) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = DepthInfo{}
-		b += DepthInfoRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a DepthInfo value to a byte slice.
-func (v DepthInfo) Bytes() []byte {
-	buf := make([]byte, (8 + xgb.Pad((int(v.VisualsLen) * 24))))
-	b := 0
-
-	buf[b] = v.Depth
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], v.VisualsLen)
-	b += 2
-
-	b += 4 // padding
-
-	b += VisualInfoListBytes(buf[b:], v.Visuals)
-
-	return buf[:b]
-}
-
-// DepthInfoListBytes writes a list of DepthInfo values to a byte slice.
-func DepthInfoListBytes(buf []byte, list []DepthInfo) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// DepthInfoListSize computes the size (bytes) of a list of DepthInfo values.
-func DepthInfoListSize(list []DepthInfo) int {
-	size := 0
-	for _, item := range list {
-		size += (8 + xgb.Pad((int(item.VisualsLen) * 24)))
-	}
-	return size
-}
-
-// DestroyNotify is the event number for a DestroyNotifyEvent.
-const DestroyNotify = 17
-
-type DestroyNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Event  Window
-	Window Window
-}
-
-// DestroyNotifyEventNew constructs a DestroyNotifyEvent value that implements xgb.Event from a byte slice.
-func DestroyNotifyEventNew(buf []byte) xgb.Event {
-	v := DestroyNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	return v
-}
-
-// Bytes writes a DestroyNotifyEvent value to a byte slice.
-func (v DestroyNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 17
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the DestroyNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v DestroyNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of DestroyNotifyEvent.
-func (v DestroyNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 3)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	return "DestroyNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[17] = DestroyNotifyEventNew
-}
-
-type Drawable uint32
-
-func NewDrawableId(c *xgb.Conn) (Drawable, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Drawable(id), nil
-}
-
-// BadDrawable is the error number for a BadDrawable.
-const BadDrawable = 9
-
-type DrawableError ValueError
-
-// DrawableErrorNew constructs a DrawableError value that implements xgb.Error from a byte slice.
-func DrawableErrorNew(buf []byte) xgb.Error {
-	v := DrawableError(ValueErrorNew(buf).(ValueError))
-	v.NiceName = "Drawable"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadDrawable error.
-// This is mostly used internally.
-func (err DrawableError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadDrawable error. If no bad value exists, 0 is returned.
-func (err DrawableError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadDrawable error.
-func (err DrawableError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadDrawable {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[9] = DrawableErrorNew
-}
-
-// EnterNotify is the event number for a EnterNotifyEvent.
-const EnterNotify = 7
-
-type EnterNotifyEvent struct {
-	Sequence        uint16
-	Detail          byte
-	Time            Timestamp
-	Root            Window
-	Event           Window
-	Child           Window
-	RootX           int16
-	RootY           int16
-	EventX          int16
-	EventY          int16
-	State           uint16
-	Mode            byte
-	SameScreenFocus byte
-}
-
-// EnterNotifyEventNew constructs a EnterNotifyEvent value that implements xgb.Event from a byte slice.
-func EnterNotifyEventNew(buf []byte) xgb.Event {
-	v := EnterNotifyEvent{}
-	b := 1 // don't read event number
-
-	v.Detail = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Time = Timestamp(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Root = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Child = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.RootX = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.RootY = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.EventX = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.EventY = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.State = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Mode = buf[b]
-	b += 1
-
-	v.SameScreenFocus = buf[b]
-	b += 1
-
-	return v
-}
-
-// Bytes writes a EnterNotifyEvent value to a byte slice.
-func (v EnterNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 7
-	b += 1
-
-	buf[b] = v.Detail
-	b += 1
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Time))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Root))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Child))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(v.RootX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.RootY))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.EventX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.EventY))
-	b += 2
-
-	xgb.Put16(buf[b:], v.State)
-	b += 2
-
-	buf[b] = v.Mode
-	b += 1
-
-	buf[b] = v.SameScreenFocus
-	b += 1
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the EnterNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v EnterNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of EnterNotifyEvent.
-func (v EnterNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 12)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail))
-	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
-	fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY))
-	fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State))
-	fieldVals = append(fieldVals, xgb.Sprintf("Mode: %d", v.Mode))
-	fieldVals = append(fieldVals, xgb.Sprintf("SameScreenFocus: %d", v.SameScreenFocus))
-	return "EnterNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[7] = EnterNotifyEventNew
-}
-
-const (
-	EventMaskNoEvent              = 0
-	EventMaskKeyPress             = 1
-	EventMaskKeyRelease           = 2
-	EventMaskButtonPress          = 4
-	EventMaskButtonRelease        = 8
-	EventMaskEnterWindow          = 16
-	EventMaskLeaveWindow          = 32
-	EventMaskPointerMotion        = 64
-	EventMaskPointerMotionHint    = 128
-	EventMaskButton1Motion        = 256
-	EventMaskButton2Motion        = 512
-	EventMaskButton3Motion        = 1024
-	EventMaskButton4Motion        = 2048
-	EventMaskButton5Motion        = 4096
-	EventMaskButtonMotion         = 8192
-	EventMaskKeymapState          = 16384
-	EventMaskExposure             = 32768
-	EventMaskVisibilityChange     = 65536
-	EventMaskStructureNotify      = 131072
-	EventMaskResizeRedirect       = 262144
-	EventMaskSubstructureNotify   = 524288
-	EventMaskSubstructureRedirect = 1048576
-	EventMaskFocusChange          = 2097152
-	EventMaskPropertyChange       = 4194304
-	EventMaskColorMapChange       = 8388608
-	EventMaskOwnerGrabButton      = 16777216
-)
-
-// Expose is the event number for a ExposeEvent.
-const Expose = 12
-
-type ExposeEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Window Window
-	X      uint16
-	Y      uint16
-	Width  uint16
-	Height uint16
-	Count  uint16
-	// padding: 2 bytes
-}
-
-// ExposeEventNew constructs a ExposeEvent value that implements xgb.Event from a byte slice.
-func ExposeEventNew(buf []byte) xgb.Event {
-	v := ExposeEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.X = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Y = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Width = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Height = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Count = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 2 // padding
-
-	return v
-}
-
-// Bytes writes a ExposeEvent value to a byte slice.
-func (v ExposeEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 12
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	xgb.Put16(buf[b:], v.X)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Y)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Width)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Height)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Count)
-	b += 2
-
-	b += 2 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the Expose event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v ExposeEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of ExposeEvent.
-func (v ExposeEvent) String() string {
-	fieldVals := make([]string, 0, 8)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X))
-	fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y))
-	fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width))
-	fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height))
-	fieldVals = append(fieldVals, xgb.Sprintf("Count: %d", v.Count))
-	return "Expose {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[12] = ExposeEventNew
-}
-
-const (
-	ExposuresNotAllowed = 0
-	ExposuresAllowed    = 1
-	ExposuresDefault    = 2
-)
-
-const (
-	FamilyInternet          = 0
-	FamilyDECnet            = 1
-	FamilyChaos             = 2
-	FamilyServerInterpreted = 5
-	FamilyInternet6         = 6
-)
-
-const (
-	FillRuleEvenOdd = 0
-	FillRuleWinding = 1
-)
-
-const (
-	FillStyleSolid          = 0
-	FillStyleTiled          = 1
-	FillStyleStippled       = 2
-	FillStyleOpaqueStippled = 3
-)
-
-// FocusIn is the event number for a FocusInEvent.
-const FocusIn = 9
-
-type FocusInEvent struct {
-	Sequence uint16
-	Detail   byte
-	Event    Window
-	Mode     byte
-	// padding: 3 bytes
-}
-
-// FocusInEventNew constructs a FocusInEvent value that implements xgb.Event from a byte slice.
-func FocusInEventNew(buf []byte) xgb.Event {
-	v := FocusInEvent{}
-	b := 1 // don't read event number
-
-	v.Detail = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Mode = buf[b]
-	b += 1
-
-	b += 3 // padding
-
-	return v
-}
-
-// Bytes writes a FocusInEvent value to a byte slice.
-func (v FocusInEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 9
-	b += 1
-
-	buf[b] = v.Detail
-	b += 1
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	buf[b] = v.Mode
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the FocusIn event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v FocusInEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of FocusInEvent.
-func (v FocusInEvent) String() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Mode: %d", v.Mode))
-	return "FocusIn {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[9] = FocusInEventNew
-}
-
-// FocusOut is the event number for a FocusOutEvent.
-const FocusOut = 10
-
-type FocusOutEvent FocusInEvent
-
-// FocusOutEventNew constructs a FocusOutEvent value that implements xgb.Event from a byte slice.
-func FocusOutEventNew(buf []byte) xgb.Event {
-	return FocusOutEvent(FocusInEventNew(buf).(FocusInEvent))
-}
-
-// Bytes writes a FocusOutEvent value to a byte slice.
-func (v FocusOutEvent) Bytes() []byte {
-	return FocusInEvent(v).Bytes()
-}
-
-// SequenceId returns the sequence id attached to the FocusOut event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v FocusOutEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-func (v FocusOutEvent) String() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Mode: %d", v.Mode))
-	return "FocusOut {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[10] = FocusOutEventNew
-}
-
-type Font uint32
-
-func NewFontId(c *xgb.Conn) (Font, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Font(id), nil
-}
-
-// BadFont is the error number for a BadFont.
-const BadFont = 7
-
-type FontError ValueError
-
-// FontErrorNew constructs a FontError value that implements xgb.Error from a byte slice.
-func FontErrorNew(buf []byte) xgb.Error {
-	v := FontError(ValueErrorNew(buf).(ValueError))
-	v.NiceName = "Font"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadFont error.
-// This is mostly used internally.
-func (err FontError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadFont error. If no bad value exists, 0 is returned.
-func (err FontError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadFont error.
-func (err FontError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadFont {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[7] = FontErrorNew
-}
-
-const (
-	FontNone = 0
-)
-
-const (
-	FontDrawLeftToRight = 0
-	FontDrawRightToLeft = 1
-)
-
-type Fontable uint32
-
-func NewFontableId(c *xgb.Conn) (Fontable, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Fontable(id), nil
-}
-
-type Fontprop struct {
-	Name  Atom
-	Value uint32
-}
-
-// FontpropRead reads a byte slice into a Fontprop value.
-func FontpropRead(buf []byte, v *Fontprop) int {
-	b := 0
-
-	v.Name = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Value = xgb.Get32(buf[b:])
-	b += 4
-
-	return b
-}
-
-// FontpropReadList reads a byte slice into a list of Fontprop values.
-func FontpropReadList(buf []byte, dest []Fontprop) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Fontprop{}
-		b += FontpropRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Fontprop value to a byte slice.
-func (v Fontprop) Bytes() []byte {
-	buf := make([]byte, 8)
-	b := 0
-
-	xgb.Put32(buf[b:], uint32(v.Name))
-	b += 4
-
-	xgb.Put32(buf[b:], v.Value)
-	b += 4
-
-	return buf[:b]
-}
-
-// FontpropListBytes writes a list of Fontprop values to a byte slice.
-func FontpropListBytes(buf []byte, list []Fontprop) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Format struct {
-	Depth        byte
-	BitsPerPixel byte
-	ScanlinePad  byte
-	// padding: 5 bytes
-}
-
-// FormatRead reads a byte slice into a Format value.
-func FormatRead(buf []byte, v *Format) int {
-	b := 0
-
-	v.Depth = buf[b]
-	b += 1
-
-	v.BitsPerPixel = buf[b]
-	b += 1
-
-	v.ScanlinePad = buf[b]
-	b += 1
-
-	b += 5 // padding
-
-	return b
-}
-
-// FormatReadList reads a byte slice into a list of Format values.
-func FormatReadList(buf []byte, dest []Format) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Format{}
-		b += FormatRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Format value to a byte slice.
-func (v Format) Bytes() []byte {
-	buf := make([]byte, 8)
-	b := 0
-
-	buf[b] = v.Depth
-	b += 1
-
-	buf[b] = v.BitsPerPixel
-	b += 1
-
-	buf[b] = v.ScanlinePad
-	b += 1
-
-	b += 5 // padding
-
-	return buf[:b]
-}
-
-// FormatListBytes writes a list of Format values to a byte slice.
-func FormatListBytes(buf []byte, list []Format) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// BadGContext is the error number for a BadGContext.
-const BadGContext = 13
-
-type GContextError ValueError
-
-// GContextErrorNew constructs a GContextError value that implements xgb.Error from a byte slice.
-func GContextErrorNew(buf []byte) xgb.Error {
-	v := GContextError(ValueErrorNew(buf).(ValueError))
-	v.NiceName = "GContext"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadGContext error.
-// This is mostly used internally.
-func (err GContextError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadGContext error. If no bad value exists, 0 is returned.
-func (err GContextError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadGContext error.
-func (err GContextError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadGContext {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[13] = GContextErrorNew
-}
-
-const (
-	GcFunction           = 1
-	GcPlaneMask          = 2
-	GcForeground         = 4
-	GcBackground         = 8
-	GcLineWidth          = 16
-	GcLineStyle          = 32
-	GcCapStyle           = 64
-	GcJoinStyle          = 128
-	GcFillStyle          = 256
-	GcFillRule           = 512
-	GcTile               = 1024
-	GcStipple            = 2048
-	GcTileStippleOriginX = 4096
-	GcTileStippleOriginY = 8192
-	GcFont               = 16384
-	GcSubwindowMode      = 32768
-	GcGraphicsExposures  = 65536
-	GcClipOriginX        = 131072
-	GcClipOriginY        = 262144
-	GcClipMask           = 524288
-	GcDashOffset         = 1048576
-	GcDashList           = 2097152
-	GcArcMode            = 4194304
-)
-
-type Gcontext uint32
-
-func NewGcontextId(c *xgb.Conn) (Gcontext, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Gcontext(id), nil
-}
-
-// GeGeneric is the event number for a GeGenericEvent.
-const GeGeneric = 35
-
-type GeGenericEvent struct {
-	Sequence uint16
-	// padding: 22 bytes
-}
-
-// GeGenericEventNew constructs a GeGenericEvent value that implements xgb.Event from a byte slice.
-func GeGenericEventNew(buf []byte) xgb.Event {
-	v := GeGenericEvent{}
-	b := 1 // don't read event number
-
-	b += 22 // padding
-
-	return v
-}
-
-// Bytes writes a GeGenericEvent value to a byte slice.
-func (v GeGenericEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 35
-	b += 1
-
-	b += 22 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the GeGeneric event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v GeGenericEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of GeGenericEvent.
-func (v GeGenericEvent) String() string {
-	fieldVals := make([]string, 0, 1)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	return "GeGeneric {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[35] = GeGenericEventNew
-}
-
-const (
-	GetPropertyTypeAny = 0
-)
-
-const (
-	GrabAny = 0
-)
-
-const (
-	GrabModeSync  = 0
-	GrabModeAsync = 1
-)
-
-const (
-	GrabStatusSuccess        = 0
-	GrabStatusAlreadyGrabbed = 1
-	GrabStatusInvalidTime    = 2
-	GrabStatusNotViewable    = 3
-	GrabStatusFrozen         = 4
-)
-
-// GraphicsExposure is the event number for a GraphicsExposureEvent.
-const GraphicsExposure = 13
-
-type GraphicsExposureEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Drawable    Drawable
-	X           uint16
-	Y           uint16
-	Width       uint16
-	Height      uint16
-	MinorOpcode uint16
-	Count       uint16
-	MajorOpcode byte
-	// padding: 3 bytes
-}
-
-// GraphicsExposureEventNew constructs a GraphicsExposureEvent value that implements xgb.Event from a byte slice.
-func GraphicsExposureEventNew(buf []byte) xgb.Event {
-	v := GraphicsExposureEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Drawable = Drawable(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.X = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Y = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Width = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Height = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MinorOpcode = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Count = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MajorOpcode = buf[b]
-	b += 1
-
-	b += 3 // padding
-
-	return v
-}
-
-// Bytes writes a GraphicsExposureEvent value to a byte slice.
-func (v GraphicsExposureEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 13
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Drawable))
-	b += 4
-
-	xgb.Put16(buf[b:], v.X)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Y)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Width)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Height)
-	b += 2
-
-	xgb.Put16(buf[b:], v.MinorOpcode)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Count)
-	b += 2
-
-	buf[b] = v.MajorOpcode
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the GraphicsExposure event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v GraphicsExposureEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of GraphicsExposureEvent.
-func (v GraphicsExposureEvent) String() string {
-	fieldVals := make([]string, 0, 10)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable))
-	fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X))
-	fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y))
-	fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width))
-	fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", v.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("Count: %d", v.Count))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", v.MajorOpcode))
-	return "GraphicsExposure {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[13] = GraphicsExposureEventNew
-}
-
-const (
-	GravityBitForget = 0
-	GravityWinUnmap  = 0
-	GravityNorthWest = 1
-	GravityNorth     = 2
-	GravityNorthEast = 3
-	GravityWest      = 4
-	GravityCenter    = 5
-	GravityEast      = 6
-	GravitySouthWest = 7
-	GravitySouth     = 8
-	GravitySouthEast = 9
-	GravityStatic    = 10
-)
-
-// GravityNotify is the event number for a GravityNotifyEvent.
-const GravityNotify = 24
-
-type GravityNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Event  Window
-	Window Window
-	X      int16
-	Y      int16
-}
-
-// GravityNotifyEventNew constructs a GravityNotifyEvent value that implements xgb.Event from a byte slice.
-func GravityNotifyEventNew(buf []byte) xgb.Event {
-	v := GravityNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.X = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	return v
-}
-
-// Bytes writes a GravityNotifyEvent value to a byte slice.
-func (v GravityNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 24
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(v.X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y))
-	b += 2
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the GravityNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v GravityNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of GravityNotifyEvent.
-func (v GravityNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 5)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X))
-	fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y))
-	return "GravityNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[24] = GravityNotifyEventNew
-}
-
-const (
-	GxClear        = 0
-	GxAnd          = 1
-	GxAndReverse   = 2
-	GxCopy         = 3
-	GxAndInverted  = 4
-	GxNoop         = 5
-	GxXor          = 6
-	GxOr           = 7
-	GxNor          = 8
-	GxEquiv        = 9
-	GxInvert       = 10
-	GxOrReverse    = 11
-	GxCopyInverted = 12
-	GxOrInverted   = 13
-	GxNand         = 14
-	GxSet          = 15
-)
-
-type Host struct {
-	Family byte
-	// padding: 1 bytes
-	AddressLen uint16
-	Address    []byte // size: xgb.Pad((int(AddressLen) * 1))
-}
-
-// HostRead reads a byte slice into a Host value.
-func HostRead(buf []byte, v *Host) int {
-	b := 0
-
-	v.Family = buf[b]
-	b += 1
-
-	b += 1 // padding
-
-	v.AddressLen = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Address = make([]byte, v.AddressLen)
-	copy(v.Address[:v.AddressLen], buf[b:])
-	b += int(v.AddressLen)
-
-	return b
-}
-
-// HostReadList reads a byte slice into a list of Host values.
-func HostReadList(buf []byte, dest []Host) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Host{}
-		b += HostRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Host value to a byte slice.
-func (v Host) Bytes() []byte {
-	buf := make([]byte, (4 + xgb.Pad((int(v.AddressLen) * 1))))
-	b := 0
-
-	buf[b] = v.Family
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], v.AddressLen)
-	b += 2
-
-	copy(buf[b:], v.Address[:v.AddressLen])
-	b += int(v.AddressLen)
-
-	return buf[:b]
-}
-
-// HostListBytes writes a list of Host values to a byte slice.
-func HostListBytes(buf []byte, list []Host) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// HostListSize computes the size (bytes) of a list of Host values.
-func HostListSize(list []Host) int {
-	size := 0
-	for _, item := range list {
-		size += (4 + xgb.Pad((int(item.AddressLen) * 1)))
-	}
-	return size
-}
-
-const (
-	HostModeInsert = 0
-	HostModeDelete = 1
-)
-
-// BadIDChoice is the error number for a BadIDChoice.
-const BadIDChoice = 14
-
-type IDChoiceError ValueError
-
-// IDChoiceErrorNew constructs a IDChoiceError value that implements xgb.Error from a byte slice.
-func IDChoiceErrorNew(buf []byte) xgb.Error {
-	v := IDChoiceError(ValueErrorNew(buf).(ValueError))
-	v.NiceName = "IDChoice"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadIDChoice error.
-// This is mostly used internally.
-func (err IDChoiceError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadIDChoice error. If no bad value exists, 0 is returned.
-func (err IDChoiceError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadIDChoice error.
-func (err IDChoiceError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadIDChoice {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[14] = IDChoiceErrorNew
-}
-
-const (
-	ImageFormatXYBitmap = 0
-	ImageFormatXYPixmap = 1
-	ImageFormatZPixmap  = 2
-)
-
-const (
-	ImageOrderLSBFirst = 0
-	ImageOrderMSBFirst = 1
-)
-
-// BadImplementation is the error number for a BadImplementation.
-const BadImplementation = 17
-
-type ImplementationError RequestError
-
-// ImplementationErrorNew constructs a ImplementationError value that implements xgb.Error from a byte slice.
-func ImplementationErrorNew(buf []byte) xgb.Error {
-	v := ImplementationError(RequestErrorNew(buf).(RequestError))
-	v.NiceName = "Implementation"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadImplementation error.
-// This is mostly used internally.
-func (err ImplementationError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadImplementation error. If no bad value exists, 0 is returned.
-func (err ImplementationError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadImplementation error.
-func (err ImplementationError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadImplementation {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[17] = ImplementationErrorNew
-}
-
-const (
-	InputFocusNone           = 0
-	InputFocusPointerRoot    = 1
-	InputFocusParent         = 2
-	InputFocusFollowKeyboard = 3
-)
-
-const (
-	JoinStyleMiter = 0
-	JoinStyleRound = 1
-	JoinStyleBevel = 2
-)
-
-const (
-	KbKeyClickPercent = 1
-	KbBellPercent     = 2
-	KbBellPitch       = 4
-	KbBellDuration    = 8
-	KbLed             = 16
-	KbLedMode         = 32
-	KbKey             = 64
-	KbAutoRepeatMode  = 128
-)
-
-const (
-	KeyButMaskShift   = 1
-	KeyButMaskLock    = 2
-	KeyButMaskControl = 4
-	KeyButMaskMod1    = 8
-	KeyButMaskMod2    = 16
-	KeyButMaskMod3    = 32
-	KeyButMaskMod4    = 64
-	KeyButMaskMod5    = 128
-	KeyButMaskButton1 = 256
-	KeyButMaskButton2 = 512
-	KeyButMaskButton3 = 1024
-	KeyButMaskButton4 = 2048
-	KeyButMaskButton5 = 4096
-)
-
-// KeyPress is the event number for a KeyPressEvent.
-const KeyPress = 2
-
-type KeyPressEvent struct {
-	Sequence   uint16
-	Detail     Keycode
-	Time       Timestamp
-	Root       Window
-	Event      Window
-	Child      Window
-	RootX      int16
-	RootY      int16
-	EventX     int16
-	EventY     int16
-	State      uint16
-	SameScreen bool
-	// padding: 1 bytes
-}
-
-// KeyPressEventNew constructs a KeyPressEvent value that implements xgb.Event from a byte slice.
-func KeyPressEventNew(buf []byte) xgb.Event {
-	v := KeyPressEvent{}
-	b := 1 // don't read event number
-
-	v.Detail = Keycode(buf[b])
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Time = Timestamp(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Root = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Child = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.RootX = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.RootY = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.EventX = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.EventY = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.State = xgb.Get16(buf[b:])
-	b += 2
-
-	if buf[b] == 1 {
-		v.SameScreen = true
-	} else {
-		v.SameScreen = false
-	}
-	b += 1
-
-	b += 1 // padding
-
-	return v
-}
-
-// Bytes writes a KeyPressEvent value to a byte slice.
-func (v KeyPressEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 2
-	b += 1
-
-	buf[b] = byte(v.Detail)
-	b += 1
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Time))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Root))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Child))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(v.RootX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.RootY))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.EventX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.EventY))
-	b += 2
-
-	xgb.Put16(buf[b:], v.State)
-	b += 2
-
-	if v.SameScreen {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	b += 1 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the KeyPress event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v KeyPressEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of KeyPressEvent.
-func (v KeyPressEvent) String() string {
-	fieldVals := make([]string, 0, 12)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail))
-	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
-	fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY))
-	fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State))
-	fieldVals = append(fieldVals, xgb.Sprintf("SameScreen: %t", v.SameScreen))
-	return "KeyPress {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[2] = KeyPressEventNew
-}
-
-// KeyRelease is the event number for a KeyReleaseEvent.
-const KeyRelease = 3
-
-type KeyReleaseEvent KeyPressEvent
-
-// KeyReleaseEventNew constructs a KeyReleaseEvent value that implements xgb.Event from a byte slice.
-func KeyReleaseEventNew(buf []byte) xgb.Event {
-	return KeyReleaseEvent(KeyPressEventNew(buf).(KeyPressEvent))
-}
-
-// Bytes writes a KeyReleaseEvent value to a byte slice.
-func (v KeyReleaseEvent) Bytes() []byte {
-	return KeyPressEvent(v).Bytes()
-}
-
-// SequenceId returns the sequence id attached to the KeyRelease event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v KeyReleaseEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-func (v KeyReleaseEvent) String() string {
-	fieldVals := make([]string, 0, 12)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail))
-	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
-	fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY))
-	fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State))
-	fieldVals = append(fieldVals, xgb.Sprintf("SameScreen: %t", v.SameScreen))
-	return "KeyRelease {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[3] = KeyReleaseEventNew
-}
-
-type Keycode byte
-
-// KeymapNotify is the event number for a KeymapNotifyEvent.
-const KeymapNotify = 11
-
-type KeymapNotifyEvent struct {
-	Keys []byte // size: 32
-}
-
-// KeymapNotifyEventNew constructs a KeymapNotifyEvent value that implements xgb.Event from a byte slice.
-func KeymapNotifyEventNew(buf []byte) xgb.Event {
-	v := KeymapNotifyEvent{}
-	b := 1 // don't read event number
-
-	v.Keys = make([]byte, 31)
-	copy(v.Keys[:31], buf[b:])
-	b += int(31)
-
-	return v
-}
-
-// Bytes writes a KeymapNotifyEvent value to a byte slice.
-func (v KeymapNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 11
-	b += 1
-
-	copy(buf[b:], v.Keys[:31])
-	b += int(31)
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the KeymapNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v KeymapNotifyEvent) SequenceId() uint16 {
-	return uint16(0)
-}
-
-// String is a rudimentary string representation of KeymapNotifyEvent.
-func (v KeymapNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 1)
-	return "KeymapNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[11] = KeymapNotifyEventNew
-}
-
-type Keysym uint32
-
-const (
-	KillAllTemporary = 0
-)
-
-// LeaveNotify is the event number for a LeaveNotifyEvent.
-const LeaveNotify = 8
-
-type LeaveNotifyEvent EnterNotifyEvent
-
-// LeaveNotifyEventNew constructs a LeaveNotifyEvent value that implements xgb.Event from a byte slice.
-func LeaveNotifyEventNew(buf []byte) xgb.Event {
-	return LeaveNotifyEvent(EnterNotifyEventNew(buf).(EnterNotifyEvent))
-}
-
-// Bytes writes a LeaveNotifyEvent value to a byte slice.
-func (v LeaveNotifyEvent) Bytes() []byte {
-	return EnterNotifyEvent(v).Bytes()
-}
-
-// SequenceId returns the sequence id attached to the LeaveNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v LeaveNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-func (v LeaveNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 12)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail))
-	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
-	fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY))
-	fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State))
-	fieldVals = append(fieldVals, xgb.Sprintf("Mode: %d", v.Mode))
-	fieldVals = append(fieldVals, xgb.Sprintf("SameScreenFocus: %d", v.SameScreenFocus))
-	return "LeaveNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[8] = LeaveNotifyEventNew
-}
-
-const (
-	LedModeOff = 0
-	LedModeOn  = 1
-)
-
-// BadLength is the error number for a BadLength.
-const BadLength = 16
-
-type LengthError RequestError
-
-// LengthErrorNew constructs a LengthError value that implements xgb.Error from a byte slice.
-func LengthErrorNew(buf []byte) xgb.Error {
-	v := LengthError(RequestErrorNew(buf).(RequestError))
-	v.NiceName = "Length"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadLength error.
-// This is mostly used internally.
-func (err LengthError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadLength error. If no bad value exists, 0 is returned.
-func (err LengthError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadLength error.
-func (err LengthError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadLength {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[16] = LengthErrorNew
-}
-
-const (
-	LineStyleSolid      = 0
-	LineStyleOnOffDash  = 1
-	LineStyleDoubleDash = 2
-)
-
-const (
-	MapIndexShift   = 0
-	MapIndexLock    = 1
-	MapIndexControl = 2
-	MapIndex1       = 3
-	MapIndex2       = 4
-	MapIndex3       = 5
-	MapIndex4       = 6
-	MapIndex5       = 7
-)
-
-// MapNotify is the event number for a MapNotifyEvent.
-const MapNotify = 19
-
-type MapNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Event            Window
-	Window           Window
-	OverrideRedirect bool
-	// padding: 3 bytes
-}
-
-// MapNotifyEventNew constructs a MapNotifyEvent value that implements xgb.Event from a byte slice.
-func MapNotifyEventNew(buf []byte) xgb.Event {
-	v := MapNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	if buf[b] == 1 {
-		v.OverrideRedirect = true
-	} else {
-		v.OverrideRedirect = false
-	}
-	b += 1
-
-	b += 3 // padding
-
-	return v
-}
-
-// Bytes writes a MapNotifyEvent value to a byte slice.
-func (v MapNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 19
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	if v.OverrideRedirect {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the MapNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v MapNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of MapNotifyEvent.
-func (v MapNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 5)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("OverrideRedirect: %t", v.OverrideRedirect))
-	return "MapNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[19] = MapNotifyEventNew
-}
-
-// MapRequest is the event number for a MapRequestEvent.
-const MapRequest = 20
-
-type MapRequestEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Parent Window
-	Window Window
-}
-
-// MapRequestEventNew constructs a MapRequestEvent value that implements xgb.Event from a byte slice.
-func MapRequestEventNew(buf []byte) xgb.Event {
-	v := MapRequestEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Parent = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	return v
-}
-
-// Bytes writes a MapRequestEvent value to a byte slice.
-func (v MapRequestEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 20
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Parent))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the MapRequest event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v MapRequestEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of MapRequestEvent.
-func (v MapRequestEvent) String() string {
-	fieldVals := make([]string, 0, 3)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Parent: %d", v.Parent))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	return "MapRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[20] = MapRequestEventNew
-}
-
-const (
-	MapStateUnmapped   = 0
-	MapStateUnviewable = 1
-	MapStateViewable   = 2
-)
-
-const (
-	MappingModifier = 0
-	MappingKeyboard = 1
-	MappingPointer  = 2
-)
-
-// MappingNotify is the event number for a MappingNotifyEvent.
-const MappingNotify = 34
-
-type MappingNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Request      byte
-	FirstKeycode Keycode
-	Count        byte
-	// padding: 1 bytes
-}
-
-// MappingNotifyEventNew constructs a MappingNotifyEvent value that implements xgb.Event from a byte slice.
-func MappingNotifyEventNew(buf []byte) xgb.Event {
-	v := MappingNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Request = buf[b]
-	b += 1
-
-	v.FirstKeycode = Keycode(buf[b])
-	b += 1
-
-	v.Count = buf[b]
-	b += 1
-
-	b += 1 // padding
-
-	return v
-}
-
-// Bytes writes a MappingNotifyEvent value to a byte slice.
-func (v MappingNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 34
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	buf[b] = v.Request
-	b += 1
-
-	buf[b] = byte(v.FirstKeycode)
-	b += 1
-
-	buf[b] = v.Count
-	b += 1
-
-	b += 1 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the MappingNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v MappingNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of MappingNotifyEvent.
-func (v MappingNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 5)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Request: %d", v.Request))
-	fieldVals = append(fieldVals, xgb.Sprintf("FirstKeycode: %d", v.FirstKeycode))
-	fieldVals = append(fieldVals, xgb.Sprintf("Count: %d", v.Count))
-	return "MappingNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[34] = MappingNotifyEventNew
-}
-
-const (
-	MappingStatusSuccess = 0
-	MappingStatusBusy    = 1
-	MappingStatusFailure = 2
-)
-
-// BadMatch is the error number for a BadMatch.
-const BadMatch = 8
-
-type MatchError RequestError
-
-// MatchErrorNew constructs a MatchError value that implements xgb.Error from a byte slice.
-func MatchErrorNew(buf []byte) xgb.Error {
-	v := MatchError(RequestErrorNew(buf).(RequestError))
-	v.NiceName = "Match"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadMatch error.
-// This is mostly used internally.
-func (err MatchError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadMatch error. If no bad value exists, 0 is returned.
-func (err MatchError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadMatch error.
-func (err MatchError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadMatch {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[8] = MatchErrorNew
-}
-
-const (
-	ModMaskShift   = 1
-	ModMaskLock    = 2
-	ModMaskControl = 4
-	ModMask1       = 8
-	ModMask2       = 16
-	ModMask3       = 32
-	ModMask4       = 64
-	ModMask5       = 128
-	ModMaskAny     = 32768
-)
-
-const (
-	MotionNormal = 0
-	MotionHint   = 1
-)
-
-// MotionNotify is the event number for a MotionNotifyEvent.
-const MotionNotify = 6
-
-type MotionNotifyEvent struct {
-	Sequence   uint16
-	Detail     byte
-	Time       Timestamp
-	Root       Window
-	Event      Window
-	Child      Window
-	RootX      int16
-	RootY      int16
-	EventX     int16
-	EventY     int16
-	State      uint16
-	SameScreen bool
-	// padding: 1 bytes
-}
-
-// MotionNotifyEventNew constructs a MotionNotifyEvent value that implements xgb.Event from a byte slice.
-func MotionNotifyEventNew(buf []byte) xgb.Event {
-	v := MotionNotifyEvent{}
-	b := 1 // don't read event number
-
-	v.Detail = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Time = Timestamp(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Root = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Child = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.RootX = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.RootY = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.EventX = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.EventY = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.State = xgb.Get16(buf[b:])
-	b += 2
-
-	if buf[b] == 1 {
-		v.SameScreen = true
-	} else {
-		v.SameScreen = false
-	}
-	b += 1
-
-	b += 1 // padding
-
-	return v
-}
-
-// Bytes writes a MotionNotifyEvent value to a byte slice.
-func (v MotionNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 6
-	b += 1
-
-	buf[b] = v.Detail
-	b += 1
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Time))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Root))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Child))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(v.RootX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.RootY))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.EventX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.EventY))
-	b += 2
-
-	xgb.Put16(buf[b:], v.State)
-	b += 2
-
-	if v.SameScreen {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	b += 1 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the MotionNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v MotionNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of MotionNotifyEvent.
-func (v MotionNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 12)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Detail: %d", v.Detail))
-	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
-	fieldVals = append(fieldVals, xgb.Sprintf("Root: %d", v.Root))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Child: %d", v.Child))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootX: %d", v.RootX))
-	fieldVals = append(fieldVals, xgb.Sprintf("RootY: %d", v.RootY))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventX: %d", v.EventX))
-	fieldVals = append(fieldVals, xgb.Sprintf("EventY: %d", v.EventY))
-	fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State))
-	fieldVals = append(fieldVals, xgb.Sprintf("SameScreen: %t", v.SameScreen))
-	return "MotionNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[6] = MotionNotifyEventNew
-}
-
-// BadName is the error number for a BadName.
-const BadName = 15
-
-type NameError RequestError
-
-// NameErrorNew constructs a NameError value that implements xgb.Error from a byte slice.
-func NameErrorNew(buf []byte) xgb.Error {
-	v := NameError(RequestErrorNew(buf).(RequestError))
-	v.NiceName = "Name"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadName error.
-// This is mostly used internally.
-func (err NameError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadName error. If no bad value exists, 0 is returned.
-func (err NameError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadName error.
-func (err NameError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadName {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[15] = NameErrorNew
-}
-
-// NoExposure is the event number for a NoExposureEvent.
-const NoExposure = 14
-
-type NoExposureEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Drawable    Drawable
-	MinorOpcode uint16
-	MajorOpcode byte
-	// padding: 1 bytes
-}
-
-// NoExposureEventNew constructs a NoExposureEvent value that implements xgb.Event from a byte slice.
-func NoExposureEventNew(buf []byte) xgb.Event {
-	v := NoExposureEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Drawable = Drawable(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.MinorOpcode = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MajorOpcode = buf[b]
-	b += 1
-
-	b += 1 // padding
-
-	return v
-}
-
-// Bytes writes a NoExposureEvent value to a byte slice.
-func (v NoExposureEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 14
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Drawable))
-	b += 4
-
-	xgb.Put16(buf[b:], v.MinorOpcode)
-	b += 2
-
-	buf[b] = v.MajorOpcode
-	b += 1
-
-	b += 1 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the NoExposure event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v NoExposureEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of NoExposureEvent.
-func (v NoExposureEvent) String() string {
-	fieldVals := make([]string, 0, 5)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", v.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", v.MajorOpcode))
-	return "NoExposure {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[14] = NoExposureEventNew
-}
-
-const (
-	NotifyDetailAncestor         = 0
-	NotifyDetailVirtual          = 1
-	NotifyDetailInferior         = 2
-	NotifyDetailNonlinear        = 3
-	NotifyDetailNonlinearVirtual = 4
-	NotifyDetailPointer          = 5
-	NotifyDetailPointerRoot      = 6
-	NotifyDetailNone             = 7
-)
-
-const (
-	NotifyModeNormal       = 0
-	NotifyModeGrab         = 1
-	NotifyModeUngrab       = 2
-	NotifyModeWhileGrabbed = 3
-)
-
-type Pixmap uint32
-
-func NewPixmapId(c *xgb.Conn) (Pixmap, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Pixmap(id), nil
-}
-
-// BadPixmap is the error number for a BadPixmap.
-const BadPixmap = 4
-
-type PixmapError ValueError
-
-// PixmapErrorNew constructs a PixmapError value that implements xgb.Error from a byte slice.
-func PixmapErrorNew(buf []byte) xgb.Error {
-	v := PixmapError(ValueErrorNew(buf).(ValueError))
-	v.NiceName = "Pixmap"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadPixmap error.
-// This is mostly used internally.
-func (err PixmapError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadPixmap error. If no bad value exists, 0 is returned.
-func (err PixmapError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadPixmap error.
-func (err PixmapError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadPixmap {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[4] = PixmapErrorNew
-}
-
-const (
-	PixmapNone = 0
-)
-
-const (
-	PlaceOnTop    = 0
-	PlaceOnBottom = 1
-)
-
-type Point struct {
-	X int16
-	Y int16
-}
-
-// PointRead reads a byte slice into a Point value.
-func PointRead(buf []byte, v *Point) int {
-	b := 0
-
-	v.X = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	return b
-}
-
-// PointReadList reads a byte slice into a list of Point values.
-func PointReadList(buf []byte, dest []Point) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Point{}
-		b += PointRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Point value to a byte slice.
-func (v Point) Bytes() []byte {
-	buf := make([]byte, 4)
-	b := 0
-
-	xgb.Put16(buf[b:], uint16(v.X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y))
-	b += 2
-
-	return buf[:b]
-}
-
-// PointListBytes writes a list of Point values to a byte slice.
-func PointListBytes(buf []byte, list []Point) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-const (
-	PolyShapeComplex   = 0
-	PolyShapeNonconvex = 1
-	PolyShapeConvex    = 2
-)
-
-const (
-	PropModeReplace = 0
-	PropModePrepend = 1
-	PropModeAppend  = 2
-)
-
-const (
-	PropertyNewValue = 0
-	PropertyDelete   = 1
-)
-
-// PropertyNotify is the event number for a PropertyNotifyEvent.
-const PropertyNotify = 28
-
-type PropertyNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Window Window
-	Atom   Atom
-	Time   Timestamp
-	State  byte
-	// padding: 3 bytes
-}
-
-// PropertyNotifyEventNew constructs a PropertyNotifyEvent value that implements xgb.Event from a byte slice.
-func PropertyNotifyEventNew(buf []byte) xgb.Event {
-	v := PropertyNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Atom = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Time = Timestamp(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.State = buf[b]
-	b += 1
-
-	b += 3 // padding
-
-	return v
-}
-
-// Bytes writes a PropertyNotifyEvent value to a byte slice.
-func (v PropertyNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 28
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Atom))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Time))
-	b += 4
-
-	buf[b] = v.State
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the PropertyNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v PropertyNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of PropertyNotifyEvent.
-func (v PropertyNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 6)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("Atom: %d", v.Atom))
-	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
-	fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State))
-	return "PropertyNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[28] = PropertyNotifyEventNew
-}
-
-const (
-	QueryShapeOfLargestCursor  = 0
-	QueryShapeOfFastestTile    = 1
-	QueryShapeOfFastestStipple = 2
-)
-
-type Rectangle struct {
-	X      int16
-	Y      int16
-	Width  uint16
-	Height uint16
-}
-
-// RectangleRead reads a byte slice into a Rectangle value.
-func RectangleRead(buf []byte, v *Rectangle) int {
-	b := 0
-
-	v.X = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Width = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Height = xgb.Get16(buf[b:])
-	b += 2
-
-	return b
-}
-
-// RectangleReadList reads a byte slice into a list of Rectangle values.
-func RectangleReadList(buf []byte, dest []Rectangle) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Rectangle{}
-		b += RectangleRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Rectangle value to a byte slice.
-func (v Rectangle) Bytes() []byte {
-	buf := make([]byte, 8)
-	b := 0
-
-	xgb.Put16(buf[b:], uint16(v.X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y))
-	b += 2
-
-	xgb.Put16(buf[b:], v.Width)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Height)
-	b += 2
-
-	return buf[:b]
-}
-
-// RectangleListBytes writes a list of Rectangle values to a byte slice.
-func RectangleListBytes(buf []byte, list []Rectangle) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// ReparentNotify is the event number for a ReparentNotifyEvent.
-const ReparentNotify = 21
-
-type ReparentNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Event            Window
-	Window           Window
-	Parent           Window
-	X                int16
-	Y                int16
-	OverrideRedirect bool
-	// padding: 3 bytes
-}
-
-// ReparentNotifyEventNew constructs a ReparentNotifyEvent value that implements xgb.Event from a byte slice.
-func ReparentNotifyEventNew(buf []byte) xgb.Event {
-	v := ReparentNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Parent = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.X = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	if buf[b] == 1 {
-		v.OverrideRedirect = true
-	} else {
-		v.OverrideRedirect = false
-	}
-	b += 1
-
-	b += 3 // padding
-
-	return v
-}
-
-// Bytes writes a ReparentNotifyEvent value to a byte slice.
-func (v ReparentNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 21
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Parent))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(v.X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y))
-	b += 2
-
-	if v.OverrideRedirect {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the ReparentNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v ReparentNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of ReparentNotifyEvent.
-func (v ReparentNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 8)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("Parent: %d", v.Parent))
-	fieldVals = append(fieldVals, xgb.Sprintf("X: %d", v.X))
-	fieldVals = append(fieldVals, xgb.Sprintf("Y: %d", v.Y))
-	fieldVals = append(fieldVals, xgb.Sprintf("OverrideRedirect: %t", v.OverrideRedirect))
-	return "ReparentNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[21] = ReparentNotifyEventNew
-}
-
-// BadRequest is the error number for a BadRequest.
-const BadRequest = 1
-
-type RequestError struct {
-	Sequence    uint16
-	NiceName    string
-	BadValue    uint32
-	MinorOpcode uint16
-	MajorOpcode byte
-	// padding: 1 bytes
-}
-
-// RequestErrorNew constructs a RequestError value that implements xgb.Error from a byte slice.
-func RequestErrorNew(buf []byte) xgb.Error {
-	v := RequestError{}
-	v.NiceName = "Request"
-
-	b := 1 // skip error determinant
-	b += 1 // don't read error number
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.BadValue = xgb.Get32(buf[b:])
-	b += 4
-
-	v.MinorOpcode = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MajorOpcode = buf[b]
-	b += 1
-
-	b += 1 // padding
-
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadRequest error.
-// This is mostly used internally.
-func (err RequestError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadRequest error. If no bad value exists, 0 is returned.
-func (err RequestError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadRequest error.
-
-func (err RequestError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[1] = RequestErrorNew
-}
-
-// ResizeRequest is the event number for a ResizeRequestEvent.
-const ResizeRequest = 25
-
-type ResizeRequestEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Window Window
-	Width  uint16
-	Height uint16
-}
-
-// ResizeRequestEventNew constructs a ResizeRequestEvent value that implements xgb.Event from a byte slice.
-func ResizeRequestEventNew(buf []byte) xgb.Event {
-	v := ResizeRequestEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Width = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Height = xgb.Get16(buf[b:])
-	b += 2
-
-	return v
-}
-
-// Bytes writes a ResizeRequestEvent value to a byte slice.
-func (v ResizeRequestEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 25
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	xgb.Put16(buf[b:], v.Width)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Height)
-	b += 2
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the ResizeRequest event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v ResizeRequestEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of ResizeRequestEvent.
-func (v ResizeRequestEvent) String() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("Width: %d", v.Width))
-	fieldVals = append(fieldVals, xgb.Sprintf("Height: %d", v.Height))
-	return "ResizeRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[25] = ResizeRequestEventNew
-}
-
-type Rgb struct {
-	Red   uint16
-	Green uint16
-	Blue  uint16
-	// padding: 2 bytes
-}
-
-// RgbRead reads a byte slice into a Rgb value.
-func RgbRead(buf []byte, v *Rgb) int {
-	b := 0
-
-	v.Red = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Green = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Blue = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 2 // padding
-
-	return b
-}
-
-// RgbReadList reads a byte slice into a list of Rgb values.
-func RgbReadList(buf []byte, dest []Rgb) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Rgb{}
-		b += RgbRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Rgb value to a byte slice.
-func (v Rgb) Bytes() []byte {
-	buf := make([]byte, 8)
-	b := 0
-
-	xgb.Put16(buf[b:], v.Red)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Green)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Blue)
-	b += 2
-
-	b += 2 // padding
-
-	return buf[:b]
-}
-
-// RgbListBytes writes a list of Rgb values to a byte slice.
-func RgbListBytes(buf []byte, list []Rgb) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type ScreenInfo struct {
-	Root                Window
-	DefaultColormap     Colormap
-	WhitePixel          uint32
-	BlackPixel          uint32
-	CurrentInputMasks   uint32
-	WidthInPixels       uint16
-	HeightInPixels      uint16
-	WidthInMillimeters  uint16
-	HeightInMillimeters uint16
-	MinInstalledMaps    uint16
-	MaxInstalledMaps    uint16
-	RootVisual          Visualid
-	BackingStores       byte
-	SaveUnders          bool
-	RootDepth           byte
-	AllowedDepthsLen    byte
-	AllowedDepths       []DepthInfo // size: DepthInfoListSize(AllowedDepths)
-}
-
-// ScreenInfoRead reads a byte slice into a ScreenInfo value.
-func ScreenInfoRead(buf []byte, v *ScreenInfo) int {
-	b := 0
-
-	v.Root = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.DefaultColormap = Colormap(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.WhitePixel = xgb.Get32(buf[b:])
-	b += 4
-
-	v.BlackPixel = xgb.Get32(buf[b:])
-	b += 4
-
-	v.CurrentInputMasks = xgb.Get32(buf[b:])
-	b += 4
-
-	v.WidthInPixels = xgb.Get16(buf[b:])
-	b += 2
-
-	v.HeightInPixels = xgb.Get16(buf[b:])
-	b += 2
-
-	v.WidthInMillimeters = xgb.Get16(buf[b:])
-	b += 2
-
-	v.HeightInMillimeters = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MinInstalledMaps = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MaxInstalledMaps = xgb.Get16(buf[b:])
-	b += 2
-
-	v.RootVisual = Visualid(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.BackingStores = buf[b]
-	b += 1
-
-	if buf[b] == 1 {
-		v.SaveUnders = true
-	} else {
-		v.SaveUnders = false
-	}
-	b += 1
-
-	v.RootDepth = buf[b]
-	b += 1
-
-	v.AllowedDepthsLen = buf[b]
-	b += 1
-
-	v.AllowedDepths = make([]DepthInfo, v.AllowedDepthsLen)
-	b += DepthInfoReadList(buf[b:], v.AllowedDepths)
-
-	return b
-}
-
-// ScreenInfoReadList reads a byte slice into a list of ScreenInfo values.
-func ScreenInfoReadList(buf []byte, dest []ScreenInfo) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = ScreenInfo{}
-		b += ScreenInfoRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a ScreenInfo value to a byte slice.
-func (v ScreenInfo) Bytes() []byte {
-	buf := make([]byte, (40 + DepthInfoListSize(v.AllowedDepths)))
-	b := 0
-
-	xgb.Put32(buf[b:], uint32(v.Root))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.DefaultColormap))
-	b += 4
-
-	xgb.Put32(buf[b:], v.WhitePixel)
-	b += 4
-
-	xgb.Put32(buf[b:], v.BlackPixel)
-	b += 4
-
-	xgb.Put32(buf[b:], v.CurrentInputMasks)
-	b += 4
-
-	xgb.Put16(buf[b:], v.WidthInPixels)
-	b += 2
-
-	xgb.Put16(buf[b:], v.HeightInPixels)
-	b += 2
-
-	xgb.Put16(buf[b:], v.WidthInMillimeters)
-	b += 2
-
-	xgb.Put16(buf[b:], v.HeightInMillimeters)
-	b += 2
-
-	xgb.Put16(buf[b:], v.MinInstalledMaps)
-	b += 2
-
-	xgb.Put16(buf[b:], v.MaxInstalledMaps)
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(v.RootVisual))
-	b += 4
-
-	buf[b] = v.BackingStores
-	b += 1
-
-	if v.SaveUnders {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	buf[b] = v.RootDepth
-	b += 1
-
-	buf[b] = v.AllowedDepthsLen
-	b += 1
-
-	b += DepthInfoListBytes(buf[b:], v.AllowedDepths)
-
-	return buf[:b]
-}
-
-// ScreenInfoListBytes writes a list of ScreenInfo values to a byte slice.
-func ScreenInfoListBytes(buf []byte, list []ScreenInfo) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// ScreenInfoListSize computes the size (bytes) of a list of ScreenInfo values.
-func ScreenInfoListSize(list []ScreenInfo) int {
-	size := 0
-	for _, item := range list {
-		size += (40 + DepthInfoListSize(item.AllowedDepths))
-	}
-	return size
-}
-
-const (
-	ScreenSaverReset  = 0
-	ScreenSaverActive = 1
-)
-
-type Segment struct {
-	X1 int16
-	Y1 int16
-	X2 int16
-	Y2 int16
-}
-
-// SegmentRead reads a byte slice into a Segment value.
-func SegmentRead(buf []byte, v *Segment) int {
-	b := 0
-
-	v.X1 = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y1 = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.X2 = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y2 = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	return b
-}
-
-// SegmentReadList reads a byte slice into a list of Segment values.
-func SegmentReadList(buf []byte, dest []Segment) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Segment{}
-		b += SegmentRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Segment value to a byte slice.
-func (v Segment) Bytes() []byte {
-	buf := make([]byte, 8)
-	b := 0
-
-	xgb.Put16(buf[b:], uint16(v.X1))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y1))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.X2))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y2))
-	b += 2
-
-	return buf[:b]
-}
-
-// SegmentListBytes writes a list of Segment values to a byte slice.
-func SegmentListBytes(buf []byte, list []Segment) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// SelectionClear is the event number for a SelectionClearEvent.
-const SelectionClear = 29
-
-type SelectionClearEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Time      Timestamp
-	Owner     Window
-	Selection Atom
-}
-
-// SelectionClearEventNew constructs a SelectionClearEvent value that implements xgb.Event from a byte slice.
-func SelectionClearEventNew(buf []byte) xgb.Event {
-	v := SelectionClearEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Time = Timestamp(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Owner = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Selection = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	return v
-}
-
-// Bytes writes a SelectionClearEvent value to a byte slice.
-func (v SelectionClearEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 29
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Time))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Owner))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Selection))
-	b += 4
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the SelectionClear event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v SelectionClearEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of SelectionClearEvent.
-func (v SelectionClearEvent) String() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
-	fieldVals = append(fieldVals, xgb.Sprintf("Owner: %d", v.Owner))
-	fieldVals = append(fieldVals, xgb.Sprintf("Selection: %d", v.Selection))
-	return "SelectionClear {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[29] = SelectionClearEventNew
-}
-
-// SelectionNotify is the event number for a SelectionNotifyEvent.
-const SelectionNotify = 31
-
-type SelectionNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Time      Timestamp
-	Requestor Window
-	Selection Atom
-	Target    Atom
-	Property  Atom
-}
-
-// SelectionNotifyEventNew constructs a SelectionNotifyEvent value that implements xgb.Event from a byte slice.
-func SelectionNotifyEventNew(buf []byte) xgb.Event {
-	v := SelectionNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Time = Timestamp(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Requestor = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Selection = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Target = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Property = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	return v
-}
-
-// Bytes writes a SelectionNotifyEvent value to a byte slice.
-func (v SelectionNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 31
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Time))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Requestor))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Selection))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Target))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Property))
-	b += 4
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the SelectionNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v SelectionNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of SelectionNotifyEvent.
-func (v SelectionNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 6)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
-	fieldVals = append(fieldVals, xgb.Sprintf("Requestor: %d", v.Requestor))
-	fieldVals = append(fieldVals, xgb.Sprintf("Selection: %d", v.Selection))
-	fieldVals = append(fieldVals, xgb.Sprintf("Target: %d", v.Target))
-	fieldVals = append(fieldVals, xgb.Sprintf("Property: %d", v.Property))
-	return "SelectionNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[31] = SelectionNotifyEventNew
-}
-
-// SelectionRequest is the event number for a SelectionRequestEvent.
-const SelectionRequest = 30
-
-type SelectionRequestEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Time      Timestamp
-	Owner     Window
-	Requestor Window
-	Selection Atom
-	Target    Atom
-	Property  Atom
-}
-
-// SelectionRequestEventNew constructs a SelectionRequestEvent value that implements xgb.Event from a byte slice.
-func SelectionRequestEventNew(buf []byte) xgb.Event {
-	v := SelectionRequestEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Time = Timestamp(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Owner = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Requestor = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Selection = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Target = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Property = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	return v
-}
-
-// Bytes writes a SelectionRequestEvent value to a byte slice.
-func (v SelectionRequestEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 30
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Time))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Owner))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Requestor))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Selection))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Target))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Property))
-	b += 4
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the SelectionRequest event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v SelectionRequestEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of SelectionRequestEvent.
-func (v SelectionRequestEvent) String() string {
-	fieldVals := make([]string, 0, 7)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
-	fieldVals = append(fieldVals, xgb.Sprintf("Owner: %d", v.Owner))
-	fieldVals = append(fieldVals, xgb.Sprintf("Requestor: %d", v.Requestor))
-	fieldVals = append(fieldVals, xgb.Sprintf("Selection: %d", v.Selection))
-	fieldVals = append(fieldVals, xgb.Sprintf("Target: %d", v.Target))
-	fieldVals = append(fieldVals, xgb.Sprintf("Property: %d", v.Property))
-	return "SelectionRequest {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[30] = SelectionRequestEventNew
-}
-
-const (
-	SendEventDestPointerWindow = 0
-	SendEventDestItemFocus     = 1
-)
-
-const (
-	SetModeInsert = 0
-	SetModeDelete = 1
-)
-
-type SetupAuthenticate struct {
-	Status byte
-	// padding: 5 bytes
-	Length uint16
-	Reason string // size: xgb.Pad(((int(Length) * 4) * 1))
-}
-
-// SetupAuthenticateRead reads a byte slice into a SetupAuthenticate value.
-func SetupAuthenticateRead(buf []byte, v *SetupAuthenticate) int {
-	b := 0
-
-	v.Status = buf[b]
-	b += 1
-
-	b += 5 // padding
-
-	v.Length = xgb.Get16(buf[b:])
-	b += 2
-
-	{
-		byteString := make([]byte, (int(v.Length) * 4))
-		copy(byteString[:(int(v.Length)*4)], buf[b:])
-		v.Reason = string(byteString)
-		b += int((int(v.Length) * 4))
-	}
-
-	return b
-}
-
-// SetupAuthenticateReadList reads a byte slice into a list of SetupAuthenticate values.
-func SetupAuthenticateReadList(buf []byte, dest []SetupAuthenticate) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = SetupAuthenticate{}
-		b += SetupAuthenticateRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a SetupAuthenticate value to a byte slice.
-func (v SetupAuthenticate) Bytes() []byte {
-	buf := make([]byte, (8 + xgb.Pad(((int(v.Length) * 4) * 1))))
-	b := 0
-
-	buf[b] = v.Status
-	b += 1
-
-	b += 5 // padding
-
-	xgb.Put16(buf[b:], v.Length)
-	b += 2
-
-	copy(buf[b:], v.Reason[:(int(v.Length)*4)])
-	b += int((int(v.Length) * 4))
-
-	return buf[:b]
-}
-
-// SetupAuthenticateListBytes writes a list of SetupAuthenticate values to a byte slice.
-func SetupAuthenticateListBytes(buf []byte, list []SetupAuthenticate) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// SetupAuthenticateListSize computes the size (bytes) of a list of SetupAuthenticate values.
-func SetupAuthenticateListSize(list []SetupAuthenticate) int {
-	size := 0
-	for _, item := range list {
-		size += (8 + xgb.Pad(((int(item.Length) * 4) * 1)))
-	}
-	return size
-}
-
-type SetupFailed struct {
-	Status               byte
-	ReasonLen            byte
-	ProtocolMajorVersion uint16
-	ProtocolMinorVersion uint16
-	Length               uint16
-	Reason               string // size: xgb.Pad((int(ReasonLen) * 1))
-}
-
-// SetupFailedRead reads a byte slice into a SetupFailed value.
-func SetupFailedRead(buf []byte, v *SetupFailed) int {
-	b := 0
-
-	v.Status = buf[b]
-	b += 1
-
-	v.ReasonLen = buf[b]
-	b += 1
-
-	v.ProtocolMajorVersion = xgb.Get16(buf[b:])
-	b += 2
-
-	v.ProtocolMinorVersion = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get16(buf[b:])
-	b += 2
-
-	{
-		byteString := make([]byte, v.ReasonLen)
-		copy(byteString[:v.ReasonLen], buf[b:])
-		v.Reason = string(byteString)
-		b += int(v.ReasonLen)
-	}
-
-	return b
-}
-
-// SetupFailedReadList reads a byte slice into a list of SetupFailed values.
-func SetupFailedReadList(buf []byte, dest []SetupFailed) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = SetupFailed{}
-		b += SetupFailedRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a SetupFailed value to a byte slice.
-func (v SetupFailed) Bytes() []byte {
-	buf := make([]byte, (8 + xgb.Pad((int(v.ReasonLen) * 1))))
-	b := 0
-
-	buf[b] = v.Status
-	b += 1
-
-	buf[b] = v.ReasonLen
-	b += 1
-
-	xgb.Put16(buf[b:], v.ProtocolMajorVersion)
-	b += 2
-
-	xgb.Put16(buf[b:], v.ProtocolMinorVersion)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Length)
-	b += 2
-
-	copy(buf[b:], v.Reason[:v.ReasonLen])
-	b += int(v.ReasonLen)
-
-	return buf[:b]
-}
-
-// SetupFailedListBytes writes a list of SetupFailed values to a byte slice.
-func SetupFailedListBytes(buf []byte, list []SetupFailed) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// SetupFailedListSize computes the size (bytes) of a list of SetupFailed values.
-func SetupFailedListSize(list []SetupFailed) int {
-	size := 0
-	for _, item := range list {
-		size += (8 + xgb.Pad((int(item.ReasonLen) * 1)))
-	}
-	return size
-}
-
-type SetupInfo struct {
-	Status byte
-	// padding: 1 bytes
-	ProtocolMajorVersion     uint16
-	ProtocolMinorVersion     uint16
-	Length                   uint16
-	ReleaseNumber            uint32
-	ResourceIdBase           uint32
-	ResourceIdMask           uint32
-	MotionBufferSize         uint32
-	VendorLen                uint16
-	MaximumRequestLength     uint16
-	RootsLen                 byte
-	PixmapFormatsLen         byte
-	ImageByteOrder           byte
-	BitmapFormatBitOrder     byte
-	BitmapFormatScanlineUnit byte
-	BitmapFormatScanlinePad  byte
-	MinKeycode               Keycode
-	MaxKeycode               Keycode
-	// padding: 4 bytes
-	Vendor string // size: xgb.Pad((int(VendorLen) * 1))
-	// alignment gap to multiple of 4
-	PixmapFormats []Format // size: xgb.Pad((int(PixmapFormatsLen) * 8))
-	// alignment gap to multiple of 4
-	Roots []ScreenInfo // size: ScreenInfoListSize(Roots)
-}
-
-// SetupInfoRead reads a byte slice into a SetupInfo value.
-func SetupInfoRead(buf []byte, v *SetupInfo) int {
-	b := 0
-
-	v.Status = buf[b]
-	b += 1
-
-	b += 1 // padding
-
-	v.ProtocolMajorVersion = xgb.Get16(buf[b:])
-	b += 2
-
-	v.ProtocolMinorVersion = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get16(buf[b:])
-	b += 2
-
-	v.ReleaseNumber = xgb.Get32(buf[b:])
-	b += 4
-
-	v.ResourceIdBase = xgb.Get32(buf[b:])
-	b += 4
-
-	v.ResourceIdMask = xgb.Get32(buf[b:])
-	b += 4
-
-	v.MotionBufferSize = xgb.Get32(buf[b:])
-	b += 4
-
-	v.VendorLen = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MaximumRequestLength = xgb.Get16(buf[b:])
-	b += 2
-
-	v.RootsLen = buf[b]
-	b += 1
-
-	v.PixmapFormatsLen = buf[b]
-	b += 1
-
-	v.ImageByteOrder = buf[b]
-	b += 1
-
-	v.BitmapFormatBitOrder = buf[b]
-	b += 1
-
-	v.BitmapFormatScanlineUnit = buf[b]
-	b += 1
-
-	v.BitmapFormatScanlinePad = buf[b]
-	b += 1
-
-	v.MinKeycode = Keycode(buf[b])
-	b += 1
-
-	v.MaxKeycode = Keycode(buf[b])
-	b += 1
-
-	b += 4 // padding
-
-	{
-		byteString := make([]byte, v.VendorLen)
-		copy(byteString[:v.VendorLen], buf[b:])
-		v.Vendor = string(byteString)
-		b += int(v.VendorLen)
-	}
-
-	b = (b + 3) & ^3 // alignment gap
-
-	v.PixmapFormats = make([]Format, v.PixmapFormatsLen)
-	b += FormatReadList(buf[b:], v.PixmapFormats)
-
-	b = (b + 3) & ^3 // alignment gap
-
-	v.Roots = make([]ScreenInfo, v.RootsLen)
-	b += ScreenInfoReadList(buf[b:], v.Roots)
-
-	return b
-}
-
-// SetupInfoReadList reads a byte slice into a list of SetupInfo values.
-func SetupInfoReadList(buf []byte, dest []SetupInfo) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = SetupInfo{}
-		b += SetupInfoRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a SetupInfo value to a byte slice.
-func (v SetupInfo) Bytes() []byte {
-	buf := make([]byte, (((((40 + xgb.Pad((int(v.VendorLen) * 1))) + 4) + xgb.Pad((int(v.PixmapFormatsLen) * 8))) + 4) + ScreenInfoListSize(v.Roots)))
-	b := 0
-
-	buf[b] = v.Status
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], v.ProtocolMajorVersion)
-	b += 2
-
-	xgb.Put16(buf[b:], v.ProtocolMinorVersion)
-	b += 2
-
-	xgb.Put16(buf[b:], v.Length)
-	b += 2
-
-	xgb.Put32(buf[b:], v.ReleaseNumber)
-	b += 4
-
-	xgb.Put32(buf[b:], v.ResourceIdBase)
-	b += 4
-
-	xgb.Put32(buf[b:], v.ResourceIdMask)
-	b += 4
-
-	xgb.Put32(buf[b:], v.MotionBufferSize)
-	b += 4
-
-	xgb.Put16(buf[b:], v.VendorLen)
-	b += 2
-
-	xgb.Put16(buf[b:], v.MaximumRequestLength)
-	b += 2
-
-	buf[b] = v.RootsLen
-	b += 1
-
-	buf[b] = v.PixmapFormatsLen
-	b += 1
-
-	buf[b] = v.ImageByteOrder
-	b += 1
-
-	buf[b] = v.BitmapFormatBitOrder
-	b += 1
-
-	buf[b] = v.BitmapFormatScanlineUnit
-	b += 1
-
-	buf[b] = v.BitmapFormatScanlinePad
-	b += 1
-
-	buf[b] = byte(v.MinKeycode)
-	b += 1
-
-	buf[b] = byte(v.MaxKeycode)
-	b += 1
-
-	b += 4 // padding
-
-	copy(buf[b:], v.Vendor[:v.VendorLen])
-	b += int(v.VendorLen)
-
-	b = (b + 3) & ^3 // alignment gap
-
-	b += FormatListBytes(buf[b:], v.PixmapFormats)
-
-	b = (b + 3) & ^3 // alignment gap
-
-	b += ScreenInfoListBytes(buf[b:], v.Roots)
-
-	return buf[:b]
-}
-
-// SetupInfoListBytes writes a list of SetupInfo values to a byte slice.
-func SetupInfoListBytes(buf []byte, list []SetupInfo) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// SetupInfoListSize computes the size (bytes) of a list of SetupInfo values.
-func SetupInfoListSize(list []SetupInfo) int {
-	size := 0
-	for _, item := range list {
-		size += (((((40 + xgb.Pad((int(item.VendorLen) * 1))) + 4) + xgb.Pad((int(item.PixmapFormatsLen) * 8))) + 4) + ScreenInfoListSize(item.Roots))
-	}
-	return size
-}
-
-type SetupRequest struct {
-	ByteOrder byte
-	// padding: 1 bytes
-	ProtocolMajorVersion         uint16
-	ProtocolMinorVersion         uint16
-	AuthorizationProtocolNameLen uint16
-	AuthorizationProtocolDataLen uint16
-	// padding: 2 bytes
-	AuthorizationProtocolName string // size: xgb.Pad((int(AuthorizationProtocolNameLen) * 1))
-	AuthorizationProtocolData string // size: xgb.Pad((int(AuthorizationProtocolDataLen) * 1))
-}
-
-// SetupRequestRead reads a byte slice into a SetupRequest value.
-func SetupRequestRead(buf []byte, v *SetupRequest) int {
-	b := 0
-
-	v.ByteOrder = buf[b]
-	b += 1
-
-	b += 1 // padding
-
-	v.ProtocolMajorVersion = xgb.Get16(buf[b:])
-	b += 2
-
-	v.ProtocolMinorVersion = xgb.Get16(buf[b:])
-	b += 2
-
-	v.AuthorizationProtocolNameLen = xgb.Get16(buf[b:])
-	b += 2
-
-	v.AuthorizationProtocolDataLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 2 // padding
-
-	{
-		byteString := make([]byte, v.AuthorizationProtocolNameLen)
-		copy(byteString[:v.AuthorizationProtocolNameLen], buf[b:])
-		v.AuthorizationProtocolName = string(byteString)
-		b += int(v.AuthorizationProtocolNameLen)
-	}
-
-	{
-		byteString := make([]byte, v.AuthorizationProtocolDataLen)
-		copy(byteString[:v.AuthorizationProtocolDataLen], buf[b:])
-		v.AuthorizationProtocolData = string(byteString)
-		b += int(v.AuthorizationProtocolDataLen)
-	}
-
-	return b
-}
-
-// SetupRequestReadList reads a byte slice into a list of SetupRequest values.
-func SetupRequestReadList(buf []byte, dest []SetupRequest) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = SetupRequest{}
-		b += SetupRequestRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a SetupRequest value to a byte slice.
-func (v SetupRequest) Bytes() []byte {
-	buf := make([]byte, ((12 + xgb.Pad((int(v.AuthorizationProtocolNameLen) * 1))) + xgb.Pad((int(v.AuthorizationProtocolDataLen) * 1))))
-	b := 0
-
-	buf[b] = v.ByteOrder
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], v.ProtocolMajorVersion)
-	b += 2
-
-	xgb.Put16(buf[b:], v.ProtocolMinorVersion)
-	b += 2
-
-	xgb.Put16(buf[b:], v.AuthorizationProtocolNameLen)
-	b += 2
-
-	xgb.Put16(buf[b:], v.AuthorizationProtocolDataLen)
-	b += 2
-
-	b += 2 // padding
-
-	copy(buf[b:], v.AuthorizationProtocolName[:v.AuthorizationProtocolNameLen])
-	b += int(v.AuthorizationProtocolNameLen)
-
-	copy(buf[b:], v.AuthorizationProtocolData[:v.AuthorizationProtocolDataLen])
-	b += int(v.AuthorizationProtocolDataLen)
-
-	return buf[:b]
-}
-
-// SetupRequestListBytes writes a list of SetupRequest values to a byte slice.
-func SetupRequestListBytes(buf []byte, list []SetupRequest) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// SetupRequestListSize computes the size (bytes) of a list of SetupRequest values.
-func SetupRequestListSize(list []SetupRequest) int {
-	size := 0
-	for _, item := range list {
-		size += ((12 + xgb.Pad((int(item.AuthorizationProtocolNameLen) * 1))) + xgb.Pad((int(item.AuthorizationProtocolDataLen) * 1)))
-	}
-	return size
-}
-
-const (
-	StackModeAbove    = 0
-	StackModeBelow    = 1
-	StackModeTopIf    = 2
-	StackModeBottomIf = 3
-	StackModeOpposite = 4
-)
-
-type Str struct {
-	NameLen byte
-	Name    string // size: xgb.Pad((int(NameLen) * 1))
-}
-
-// StrRead reads a byte slice into a Str value.
-func StrRead(buf []byte, v *Str) int {
-	b := 0
-
-	v.NameLen = buf[b]
-	b += 1
-
-	{
-		byteString := make([]byte, v.NameLen)
-		copy(byteString[:v.NameLen], buf[b:])
-		v.Name = string(byteString)
-		b += int(v.NameLen)
-	}
-
-	return b
-}
-
-// StrReadList reads a byte slice into a list of Str values.
-func StrReadList(buf []byte, dest []Str) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Str{}
-		b += StrRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Str value to a byte slice.
-func (v Str) Bytes() []byte {
-	buf := make([]byte, (1 + xgb.Pad((int(v.NameLen) * 1))))
-	b := 0
-
-	buf[b] = v.NameLen
-	b += 1
-
-	copy(buf[b:], v.Name[:v.NameLen])
-	b += int(v.NameLen)
-
-	return buf[:b]
-}
-
-// StrListBytes writes a list of Str values to a byte slice.
-func StrListBytes(buf []byte, list []Str) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-// StrListSize computes the size (bytes) of a list of Str values.
-func StrListSize(list []Str) int {
-	size := 0
-	for _, item := range list {
-		size += (1 + xgb.Pad((int(item.NameLen) * 1)))
-	}
-	return size
-}
-
-const (
-	SubwindowModeClipByChildren   = 0
-	SubwindowModeIncludeInferiors = 1
-)
-
-const (
-	TimeCurrentTime = 0
-)
-
-type Timecoord struct {
-	Time Timestamp
-	X    int16
-	Y    int16
-}
-
-// TimecoordRead reads a byte slice into a Timecoord value.
-func TimecoordRead(buf []byte, v *Timecoord) int {
-	b := 0
-
-	v.Time = Timestamp(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.X = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	return b
-}
-
-// TimecoordReadList reads a byte slice into a list of Timecoord values.
-func TimecoordReadList(buf []byte, dest []Timecoord) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = Timecoord{}
-		b += TimecoordRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a Timecoord value to a byte slice.
-func (v Timecoord) Bytes() []byte {
-	buf := make([]byte, 8)
-	b := 0
-
-	xgb.Put32(buf[b:], uint32(v.Time))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(v.X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(v.Y))
-	b += 2
-
-	return buf[:b]
-}
-
-// TimecoordListBytes writes a list of Timecoord values to a byte slice.
-func TimecoordListBytes(buf []byte, list []Timecoord) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Timestamp uint32
-
-// UnmapNotify is the event number for a UnmapNotifyEvent.
-const UnmapNotify = 18
-
-type UnmapNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Event         Window
-	Window        Window
-	FromConfigure bool
-	// padding: 3 bytes
-}
-
-// UnmapNotifyEventNew constructs a UnmapNotifyEvent value that implements xgb.Event from a byte slice.
-func UnmapNotifyEventNew(buf []byte) xgb.Event {
-	v := UnmapNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Event = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	if buf[b] == 1 {
-		v.FromConfigure = true
-	} else {
-		v.FromConfigure = false
-	}
-	b += 1
-
-	b += 3 // padding
-
-	return v
-}
-
-// Bytes writes a UnmapNotifyEvent value to a byte slice.
-func (v UnmapNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 18
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Event))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	if v.FromConfigure {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the UnmapNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v UnmapNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of UnmapNotifyEvent.
-func (v UnmapNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 5)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Event: %d", v.Event))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("FromConfigure: %t", v.FromConfigure))
-	return "UnmapNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[18] = UnmapNotifyEventNew
-}
-
-// BadValue is the error number for a BadValue.
-const BadValue = 2
-
-type ValueError struct {
-	Sequence    uint16
-	NiceName    string
-	BadValue    uint32
-	MinorOpcode uint16
-	MajorOpcode byte
-	// padding: 1 bytes
-}
-
-// ValueErrorNew constructs a ValueError value that implements xgb.Error from a byte slice.
-func ValueErrorNew(buf []byte) xgb.Error {
-	v := ValueError{}
-	v.NiceName = "Value"
-
-	b := 1 // skip error determinant
-	b += 1 // don't read error number
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.BadValue = xgb.Get32(buf[b:])
-	b += 4
-
-	v.MinorOpcode = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MajorOpcode = buf[b]
-	b += 1
-
-	b += 1 // padding
-
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadValue error.
-// This is mostly used internally.
-func (err ValueError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadValue error. If no bad value exists, 0 is returned.
-func (err ValueError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadValue error.
-
-func (err ValueError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadValue {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[2] = ValueErrorNew
-}
-
-const (
-	VisibilityUnobscured        = 0
-	VisibilityPartiallyObscured = 1
-	VisibilityFullyObscured     = 2
-)
-
-// VisibilityNotify is the event number for a VisibilityNotifyEvent.
-const VisibilityNotify = 15
-
-type VisibilityNotifyEvent struct {
-	Sequence uint16
-	// padding: 1 bytes
-	Window Window
-	State  byte
-	// padding: 3 bytes
-}
-
-// VisibilityNotifyEventNew constructs a VisibilityNotifyEvent value that implements xgb.Event from a byte slice.
-func VisibilityNotifyEventNew(buf []byte) xgb.Event {
-	v := VisibilityNotifyEvent{}
-	b := 1 // don't read event number
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Window = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.State = buf[b]
-	b += 1
-
-	b += 3 // padding
-
-	return v
-}
-
-// Bytes writes a VisibilityNotifyEvent value to a byte slice.
-func (v VisibilityNotifyEvent) Bytes() []byte {
-	buf := make([]byte, 32)
-	b := 0
-
-	// write event number
-	buf[b] = 15
-	b += 1
-
-	b += 1 // padding
-
-	b += 2 // skip sequence number
-
-	xgb.Put32(buf[b:], uint32(v.Window))
-	b += 4
-
-	buf[b] = v.State
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// SequenceId returns the sequence id attached to the VisibilityNotify event.
-// Events without a sequence number (KeymapNotify) return 0.
-// This is mostly used internally.
-func (v VisibilityNotifyEvent) SequenceId() uint16 {
-	return v.Sequence
-}
-
-// String is a rudimentary string representation of VisibilityNotifyEvent.
-func (v VisibilityNotifyEvent) String() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("Window: %d", v.Window))
-	fieldVals = append(fieldVals, xgb.Sprintf("State: %d", v.State))
-	return "VisibilityNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewEventFuncs[15] = VisibilityNotifyEventNew
-}
-
-const (
-	VisualClassStaticGray  = 0
-	VisualClassGrayScale   = 1
-	VisualClassStaticColor = 2
-	VisualClassPseudoColor = 3
-	VisualClassTrueColor   = 4
-	VisualClassDirectColor = 5
-)
-
-type VisualInfo struct {
-	VisualId        Visualid
-	Class           byte
-	BitsPerRgbValue byte
-	ColormapEntries uint16
-	RedMask         uint32
-	GreenMask       uint32
-	BlueMask        uint32
-	// padding: 4 bytes
-}
-
-// VisualInfoRead reads a byte slice into a VisualInfo value.
-func VisualInfoRead(buf []byte, v *VisualInfo) int {
-	b := 0
-
-	v.VisualId = Visualid(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Class = buf[b]
-	b += 1
-
-	v.BitsPerRgbValue = buf[b]
-	b += 1
-
-	v.ColormapEntries = xgb.Get16(buf[b:])
-	b += 2
-
-	v.RedMask = xgb.Get32(buf[b:])
-	b += 4
-
-	v.GreenMask = xgb.Get32(buf[b:])
-	b += 4
-
-	v.BlueMask = xgb.Get32(buf[b:])
-	b += 4
-
-	b += 4 // padding
-
-	return b
-}
-
-// VisualInfoReadList reads a byte slice into a list of VisualInfo values.
-func VisualInfoReadList(buf []byte, dest []VisualInfo) int {
-	b := 0
-	for i := 0; i < len(dest); i++ {
-		dest[i] = VisualInfo{}
-		b += VisualInfoRead(buf[b:], &dest[i])
-	}
-	return xgb.Pad(b)
-}
-
-// Bytes writes a VisualInfo value to a byte slice.
-func (v VisualInfo) Bytes() []byte {
-	buf := make([]byte, 24)
-	b := 0
-
-	xgb.Put32(buf[b:], uint32(v.VisualId))
-	b += 4
-
-	buf[b] = v.Class
-	b += 1
-
-	buf[b] = v.BitsPerRgbValue
-	b += 1
-
-	xgb.Put16(buf[b:], v.ColormapEntries)
-	b += 2
-
-	xgb.Put32(buf[b:], v.RedMask)
-	b += 4
-
-	xgb.Put32(buf[b:], v.GreenMask)
-	b += 4
-
-	xgb.Put32(buf[b:], v.BlueMask)
-	b += 4
-
-	b += 4 // padding
-
-	return buf[:b]
-}
-
-// VisualInfoListBytes writes a list of VisualInfo values to a byte slice.
-func VisualInfoListBytes(buf []byte, list []VisualInfo) int {
-	b := 0
-	var structBytes []byte
-	for _, item := range list {
-		structBytes = item.Bytes()
-		copy(buf[b:], structBytes)
-		b += len(structBytes)
-	}
-	return xgb.Pad(b)
-}
-
-type Visualid uint32
-
-type Window uint32
-
-func NewWindowId(c *xgb.Conn) (Window, error) {
-	id, err := c.NewId()
-	if err != nil {
-		return 0, err
-	}
-	return Window(id), nil
-}
-
-const (
-	WindowNone = 0
-)
-
-// BadWindow is the error number for a BadWindow.
-const BadWindow = 3
-
-type WindowError ValueError
-
-// WindowErrorNew constructs a WindowError value that implements xgb.Error from a byte slice.
-func WindowErrorNew(buf []byte) xgb.Error {
-	v := WindowError(ValueErrorNew(buf).(ValueError))
-	v.NiceName = "Window"
-	return v
-}
-
-// SequenceId returns the sequence id attached to the BadWindow error.
-// This is mostly used internally.
-func (err WindowError) SequenceId() uint16 {
-	return err.Sequence
-}
-
-// BadId returns the 'BadValue' number if one exists for the BadWindow error. If no bad value exists, 0 is returned.
-func (err WindowError) BadId() uint32 {
-	return err.BadValue
-}
-
-// Error returns a rudimentary string representation of the BadWindow error.
-func (err WindowError) Error() string {
-	fieldVals := make([]string, 0, 4)
-	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
-	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
-	fieldVals = append(fieldVals, xgb.Sprintf("BadValue: %d", err.BadValue))
-	fieldVals = append(fieldVals, xgb.Sprintf("MinorOpcode: %d", err.MinorOpcode))
-	fieldVals = append(fieldVals, xgb.Sprintf("MajorOpcode: %d", err.MajorOpcode))
-	return "BadWindow {" + xgb.StringsJoin(fieldVals, ", ") + "}"
-}
-
-func init() {
-	xgb.NewErrorFuncs[3] = WindowErrorNew
-}
-
-const (
-	WindowClassCopyFromParent = 0
-	WindowClassInputOutput    = 1
-	WindowClassInputOnly      = 2
-)
-
-// Skipping definition for base type 'Bool'
-
-// Skipping definition for base type 'Byte'
-
-// Skipping definition for base type 'Card8'
-
-// Skipping definition for base type 'Char'
-
-// Skipping definition for base type 'Void'
-
-// Skipping definition for base type 'Double'
-
-// Skipping definition for base type 'Float'
-
-// Skipping definition for base type 'Int16'
-
-// Skipping definition for base type 'Int32'
-
-// Skipping definition for base type 'Int8'
-
-// Skipping definition for base type 'Card16'
-
-// Skipping definition for base type 'Card32'
-
-// AllocColorCookie is a cookie used only for AllocColor requests.
-type AllocColorCookie struct {
-	*xgb.Cookie
-}
-
-// AllocColor sends a checked request.
-// If an error occurs, it will be returned with the reply by calling AllocColorCookie.Reply()
-func AllocColor(c *xgb.Conn, Cmap Colormap, Red uint16, Green uint16, Blue uint16) AllocColorCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(allocColorRequest(c, Cmap, Red, Green, Blue), cookie)
-	return AllocColorCookie{cookie}
-}
-
-// AllocColorUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func AllocColorUnchecked(c *xgb.Conn, Cmap Colormap, Red uint16, Green uint16, Blue uint16) AllocColorCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(allocColorRequest(c, Cmap, Red, Green, Blue), cookie)
-	return AllocColorCookie{cookie}
-}
-
-// AllocColorReply represents the data returned from a AllocColor request.
-type AllocColorReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	Red   uint16
-	Green uint16
-	Blue  uint16
-	// padding: 2 bytes
-	Pixel uint32
-}
-
-// Reply blocks and returns the reply data for a AllocColor request.
-func (cook AllocColorCookie) Reply() (*AllocColorReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return allocColorReply(buf), nil
-}
-
-// allocColorReply reads a byte slice into a AllocColorReply value.
-func allocColorReply(buf []byte) *AllocColorReply {
-	v := new(AllocColorReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Red = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Green = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Blue = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 2 // padding
-
-	v.Pixel = xgb.Get32(buf[b:])
-	b += 4
-
-	return v
-}
-
-// Write request to wire for AllocColor
-// allocColorRequest writes a AllocColor request to a byte slice.
-func allocColorRequest(c *xgb.Conn, Cmap Colormap, Red uint16, Green uint16, Blue uint16) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 84 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	xgb.Put16(buf[b:], Red)
-	b += 2
-
-	xgb.Put16(buf[b:], Green)
-	b += 2
-
-	xgb.Put16(buf[b:], Blue)
-	b += 2
-
-	b += 2 // padding
-
-	return buf
-}
-
-// AllocColorCellsCookie is a cookie used only for AllocColorCells requests.
-type AllocColorCellsCookie struct {
-	*xgb.Cookie
-}
-
-// AllocColorCells sends a checked request.
-// If an error occurs, it will be returned with the reply by calling AllocColorCellsCookie.Reply()
-func AllocColorCells(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Planes uint16) AllocColorCellsCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(allocColorCellsRequest(c, Contiguous, Cmap, Colors, Planes), cookie)
-	return AllocColorCellsCookie{cookie}
-}
-
-// AllocColorCellsUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func AllocColorCellsUnchecked(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Planes uint16) AllocColorCellsCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(allocColorCellsRequest(c, Contiguous, Cmap, Colors, Planes), cookie)
-	return AllocColorCellsCookie{cookie}
-}
-
-// AllocColorCellsReply represents the data returned from a AllocColorCells request.
-type AllocColorCellsReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	PixelsLen uint16
-	MasksLen  uint16
-	// padding: 20 bytes
-	Pixels []uint32 // size: xgb.Pad((int(PixelsLen) * 4))
-	// alignment gap to multiple of 4
-	Masks []uint32 // size: xgb.Pad((int(MasksLen) * 4))
-}
-
-// Reply blocks and returns the reply data for a AllocColorCells request.
-func (cook AllocColorCellsCookie) Reply() (*AllocColorCellsReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return allocColorCellsReply(buf), nil
-}
-
-// allocColorCellsReply reads a byte slice into a AllocColorCellsReply value.
-func allocColorCellsReply(buf []byte) *AllocColorCellsReply {
-	v := new(AllocColorCellsReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.PixelsLen = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MasksLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 20 // padding
-
-	v.Pixels = make([]uint32, v.PixelsLen)
-	for i := 0; i < int(v.PixelsLen); i++ {
-		v.Pixels[i] = xgb.Get32(buf[b:])
-		b += 4
-	}
-
-	b = (b + 3) & ^3 // alignment gap
-
-	v.Masks = make([]uint32, v.MasksLen)
-	for i := 0; i < int(v.MasksLen); i++ {
-		v.Masks[i] = xgb.Get32(buf[b:])
-		b += 4
-	}
-
-	return v
-}
-
-// Write request to wire for AllocColorCells
-// allocColorCellsRequest writes a AllocColorCells request to a byte slice.
-func allocColorCellsRequest(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Planes uint16) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 86 // request opcode
-	b += 1
-
-	if Contiguous {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	xgb.Put16(buf[b:], Colors)
-	b += 2
-
-	xgb.Put16(buf[b:], Planes)
-	b += 2
-
-	return buf
-}
-
-// AllocColorPlanesCookie is a cookie used only for AllocColorPlanes requests.
-type AllocColorPlanesCookie struct {
-	*xgb.Cookie
-}
-
-// AllocColorPlanes sends a checked request.
-// If an error occurs, it will be returned with the reply by calling AllocColorPlanesCookie.Reply()
-func AllocColorPlanes(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Reds uint16, Greens uint16, Blues uint16) AllocColorPlanesCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(allocColorPlanesRequest(c, Contiguous, Cmap, Colors, Reds, Greens, Blues), cookie)
-	return AllocColorPlanesCookie{cookie}
-}
-
-// AllocColorPlanesUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func AllocColorPlanesUnchecked(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Reds uint16, Greens uint16, Blues uint16) AllocColorPlanesCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(allocColorPlanesRequest(c, Contiguous, Cmap, Colors, Reds, Greens, Blues), cookie)
-	return AllocColorPlanesCookie{cookie}
-}
-
-// AllocColorPlanesReply represents the data returned from a AllocColorPlanes request.
-type AllocColorPlanesReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	PixelsLen uint16
-	// padding: 2 bytes
-	RedMask   uint32
-	GreenMask uint32
-	BlueMask  uint32
-	// padding: 8 bytes
-	Pixels []uint32 // size: xgb.Pad((int(PixelsLen) * 4))
-}
-
-// Reply blocks and returns the reply data for a AllocColorPlanes request.
-func (cook AllocColorPlanesCookie) Reply() (*AllocColorPlanesReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return allocColorPlanesReply(buf), nil
-}
-
-// allocColorPlanesReply reads a byte slice into a AllocColorPlanesReply value.
-func allocColorPlanesReply(buf []byte) *AllocColorPlanesReply {
-	v := new(AllocColorPlanesReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.PixelsLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 2 // padding
-
-	v.RedMask = xgb.Get32(buf[b:])
-	b += 4
-
-	v.GreenMask = xgb.Get32(buf[b:])
-	b += 4
-
-	v.BlueMask = xgb.Get32(buf[b:])
-	b += 4
-
-	b += 8 // padding
-
-	v.Pixels = make([]uint32, v.PixelsLen)
-	for i := 0; i < int(v.PixelsLen); i++ {
-		v.Pixels[i] = xgb.Get32(buf[b:])
-		b += 4
-	}
-
-	return v
-}
-
-// Write request to wire for AllocColorPlanes
-// allocColorPlanesRequest writes a AllocColorPlanes request to a byte slice.
-func allocColorPlanesRequest(c *xgb.Conn, Contiguous bool, Cmap Colormap, Colors uint16, Reds uint16, Greens uint16, Blues uint16) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 87 // request opcode
-	b += 1
-
-	if Contiguous {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	xgb.Put16(buf[b:], Colors)
-	b += 2
-
-	xgb.Put16(buf[b:], Reds)
-	b += 2
-
-	xgb.Put16(buf[b:], Greens)
-	b += 2
-
-	xgb.Put16(buf[b:], Blues)
-	b += 2
-
-	return buf
-}
-
-// AllocNamedColorCookie is a cookie used only for AllocNamedColor requests.
-type AllocNamedColorCookie struct {
-	*xgb.Cookie
-}
-
-// AllocNamedColor sends a checked request.
-// If an error occurs, it will be returned with the reply by calling AllocNamedColorCookie.Reply()
-func AllocNamedColor(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) AllocNamedColorCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(allocNamedColorRequest(c, Cmap, NameLen, Name), cookie)
-	return AllocNamedColorCookie{cookie}
-}
-
-// AllocNamedColorUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func AllocNamedColorUnchecked(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) AllocNamedColorCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(allocNamedColorRequest(c, Cmap, NameLen, Name), cookie)
-	return AllocNamedColorCookie{cookie}
-}
-
-// AllocNamedColorReply represents the data returned from a AllocNamedColor request.
-type AllocNamedColorReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	Pixel       uint32
-	ExactRed    uint16
-	ExactGreen  uint16
-	ExactBlue   uint16
-	VisualRed   uint16
-	VisualGreen uint16
-	VisualBlue  uint16
-}
-
-// Reply blocks and returns the reply data for a AllocNamedColor request.
-func (cook AllocNamedColorCookie) Reply() (*AllocNamedColorReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return allocNamedColorReply(buf), nil
-}
-
-// allocNamedColorReply reads a byte slice into a AllocNamedColorReply value.
-func allocNamedColorReply(buf []byte) *AllocNamedColorReply {
-	v := new(AllocNamedColorReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Pixel = xgb.Get32(buf[b:])
-	b += 4
-
-	v.ExactRed = xgb.Get16(buf[b:])
-	b += 2
-
-	v.ExactGreen = xgb.Get16(buf[b:])
-	b += 2
-
-	v.ExactBlue = xgb.Get16(buf[b:])
-	b += 2
-
-	v.VisualRed = xgb.Get16(buf[b:])
-	b += 2
-
-	v.VisualGreen = xgb.Get16(buf[b:])
-	b += 2
-
-	v.VisualBlue = xgb.Get16(buf[b:])
-	b += 2
-
-	return v
-}
-
-// Write request to wire for AllocNamedColor
-// allocNamedColorRequest writes a AllocNamedColor request to a byte slice.
-func allocNamedColorRequest(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) []byte {
-	size := xgb.Pad((12 + xgb.Pad((int(NameLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 85 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	xgb.Put16(buf[b:], NameLen)
-	b += 2
-
-	b += 2 // padding
-
-	copy(buf[b:], Name[:NameLen])
-	b += int(NameLen)
-
-	return buf
-}
-
-// AllowEventsCookie is a cookie used only for AllowEvents requests.
-type AllowEventsCookie struct {
-	*xgb.Cookie
-}
-
-// AllowEvents sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func AllowEvents(c *xgb.Conn, Mode byte, Time Timestamp) AllowEventsCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(allowEventsRequest(c, Mode, Time), cookie)
-	return AllowEventsCookie{cookie}
-}
-
-// AllowEventsChecked sends a checked request.
-// If an error occurs, it can be retrieved using AllowEventsCookie.Check()
-func AllowEventsChecked(c *xgb.Conn, Mode byte, Time Timestamp) AllowEventsCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(allowEventsRequest(c, Mode, Time), cookie)
-	return AllowEventsCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook AllowEventsCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for AllowEvents
-// allowEventsRequest writes a AllowEvents request to a byte slice.
-func allowEventsRequest(c *xgb.Conn, Mode byte, Time Timestamp) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 35 // request opcode
-	b += 1
-
-	buf[b] = Mode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Time))
-	b += 4
-
-	return buf
-}
-
-// BellCookie is a cookie used only for Bell requests.
-type BellCookie struct {
-	*xgb.Cookie
-}
-
-// Bell sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func Bell(c *xgb.Conn, Percent int8) BellCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(bellRequest(c, Percent), cookie)
-	return BellCookie{cookie}
-}
-
-// BellChecked sends a checked request.
-// If an error occurs, it can be retrieved using BellCookie.Check()
-func BellChecked(c *xgb.Conn, Percent int8) BellCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(bellRequest(c, Percent), cookie)
-	return BellCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook BellCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for Bell
-// bellRequest writes a Bell request to a byte slice.
-func bellRequest(c *xgb.Conn, Percent int8) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 104 // request opcode
-	b += 1
-
-	buf[b] = byte(Percent)
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// ChangeActivePointerGrabCookie is a cookie used only for ChangeActivePointerGrab requests.
-type ChangeActivePointerGrabCookie struct {
-	*xgb.Cookie
-}
-
-// ChangeActivePointerGrab sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ChangeActivePointerGrab(c *xgb.Conn, Cursor Cursor, Time Timestamp, EventMask uint16) ChangeActivePointerGrabCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(changeActivePointerGrabRequest(c, Cursor, Time, EventMask), cookie)
-	return ChangeActivePointerGrabCookie{cookie}
-}
-
-// ChangeActivePointerGrabChecked sends a checked request.
-// If an error occurs, it can be retrieved using ChangeActivePointerGrabCookie.Check()
-func ChangeActivePointerGrabChecked(c *xgb.Conn, Cursor Cursor, Time Timestamp, EventMask uint16) ChangeActivePointerGrabCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(changeActivePointerGrabRequest(c, Cursor, Time, EventMask), cookie)
-	return ChangeActivePointerGrabCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ChangeActivePointerGrabCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ChangeActivePointerGrab
-// changeActivePointerGrabRequest writes a ChangeActivePointerGrab request to a byte slice.
-func changeActivePointerGrabRequest(c *xgb.Conn, Cursor Cursor, Time Timestamp, EventMask uint16) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 30 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cursor))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Time))
-	b += 4
-
-	xgb.Put16(buf[b:], EventMask)
-	b += 2
-
-	b += 2 // padding
-
-	return buf
-}
-
-// ChangeGCCookie is a cookie used only for ChangeGC requests.
-type ChangeGCCookie struct {
-	*xgb.Cookie
-}
-
-// ChangeGC sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ChangeGC(c *xgb.Conn, Gc Gcontext, ValueMask uint32, ValueList []uint32) ChangeGCCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(changeGCRequest(c, Gc, ValueMask, ValueList), cookie)
-	return ChangeGCCookie{cookie}
-}
-
-// ChangeGCChecked sends a checked request.
-// If an error occurs, it can be retrieved using ChangeGCCookie.Check()
-func ChangeGCChecked(c *xgb.Conn, Gc Gcontext, ValueMask uint32, ValueList []uint32) ChangeGCCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(changeGCRequest(c, Gc, ValueMask, ValueList), cookie)
-	return ChangeGCCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ChangeGCCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ChangeGC
-// changeGCRequest writes a ChangeGC request to a byte slice.
-func changeGCRequest(c *xgb.Conn, Gc Gcontext, ValueMask uint32, ValueList []uint32) []byte {
-	size := xgb.Pad((8 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 56 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	xgb.Put32(buf[b:], ValueMask)
-	b += 4
-	for i := 0; i < xgb.PopCount(int(ValueMask)); i++ {
-		xgb.Put32(buf[b:], ValueList[i])
-		b += 4
-	}
-	b = xgb.Pad(b)
-
-	return buf
-}
-
-// ChangeHostsCookie is a cookie used only for ChangeHosts requests.
-type ChangeHostsCookie struct {
-	*xgb.Cookie
-}
-
-// ChangeHosts sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ChangeHosts(c *xgb.Conn, Mode byte, Family byte, AddressLen uint16, Address []byte) ChangeHostsCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(changeHostsRequest(c, Mode, Family, AddressLen, Address), cookie)
-	return ChangeHostsCookie{cookie}
-}
-
-// ChangeHostsChecked sends a checked request.
-// If an error occurs, it can be retrieved using ChangeHostsCookie.Check()
-func ChangeHostsChecked(c *xgb.Conn, Mode byte, Family byte, AddressLen uint16, Address []byte) ChangeHostsCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(changeHostsRequest(c, Mode, Family, AddressLen, Address), cookie)
-	return ChangeHostsCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ChangeHostsCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ChangeHosts
-// changeHostsRequest writes a ChangeHosts request to a byte slice.
-func changeHostsRequest(c *xgb.Conn, Mode byte, Family byte, AddressLen uint16, Address []byte) []byte {
-	size := xgb.Pad((8 + xgb.Pad((int(AddressLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 109 // request opcode
-	b += 1
-
-	buf[b] = Mode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = Family
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], AddressLen)
-	b += 2
-
-	copy(buf[b:], Address[:AddressLen])
-	b += int(AddressLen)
-
-	return buf
-}
-
-// ChangeKeyboardControlCookie is a cookie used only for ChangeKeyboardControl requests.
-type ChangeKeyboardControlCookie struct {
-	*xgb.Cookie
-}
-
-// ChangeKeyboardControl sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ChangeKeyboardControl(c *xgb.Conn, ValueMask uint32, ValueList []uint32) ChangeKeyboardControlCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(changeKeyboardControlRequest(c, ValueMask, ValueList), cookie)
-	return ChangeKeyboardControlCookie{cookie}
-}
-
-// ChangeKeyboardControlChecked sends a checked request.
-// If an error occurs, it can be retrieved using ChangeKeyboardControlCookie.Check()
-func ChangeKeyboardControlChecked(c *xgb.Conn, ValueMask uint32, ValueList []uint32) ChangeKeyboardControlCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(changeKeyboardControlRequest(c, ValueMask, ValueList), cookie)
-	return ChangeKeyboardControlCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ChangeKeyboardControlCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ChangeKeyboardControl
-// changeKeyboardControlRequest writes a ChangeKeyboardControl request to a byte slice.
-func changeKeyboardControlRequest(c *xgb.Conn, ValueMask uint32, ValueList []uint32) []byte {
-	size := xgb.Pad((4 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 102 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], ValueMask)
-	b += 4
-	for i := 0; i < xgb.PopCount(int(ValueMask)); i++ {
-		xgb.Put32(buf[b:], ValueList[i])
-		b += 4
-	}
-	b = xgb.Pad(b)
-
-	return buf
-}
-
-// ChangeKeyboardMappingCookie is a cookie used only for ChangeKeyboardMapping requests.
-type ChangeKeyboardMappingCookie struct {
-	*xgb.Cookie
-}
-
-// ChangeKeyboardMapping sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ChangeKeyboardMapping(c *xgb.Conn, KeycodeCount byte, FirstKeycode Keycode, KeysymsPerKeycode byte, Keysyms []Keysym) ChangeKeyboardMappingCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(changeKeyboardMappingRequest(c, KeycodeCount, FirstKeycode, KeysymsPerKeycode, Keysyms), cookie)
-	return ChangeKeyboardMappingCookie{cookie}
-}
-
-// ChangeKeyboardMappingChecked sends a checked request.
-// If an error occurs, it can be retrieved using ChangeKeyboardMappingCookie.Check()
-func ChangeKeyboardMappingChecked(c *xgb.Conn, KeycodeCount byte, FirstKeycode Keycode, KeysymsPerKeycode byte, Keysyms []Keysym) ChangeKeyboardMappingCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(changeKeyboardMappingRequest(c, KeycodeCount, FirstKeycode, KeysymsPerKeycode, Keysyms), cookie)
-	return ChangeKeyboardMappingCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ChangeKeyboardMappingCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ChangeKeyboardMapping
-// changeKeyboardMappingRequest writes a ChangeKeyboardMapping request to a byte slice.
-func changeKeyboardMappingRequest(c *xgb.Conn, KeycodeCount byte, FirstKeycode Keycode, KeysymsPerKeycode byte, Keysyms []Keysym) []byte {
-	size := xgb.Pad((8 + xgb.Pad(((int(KeycodeCount) * int(KeysymsPerKeycode)) * 4))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 100 // request opcode
-	b += 1
-
-	buf[b] = KeycodeCount
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = byte(FirstKeycode)
-	b += 1
-
-	buf[b] = KeysymsPerKeycode
-	b += 1
-
-	b += 2 // padding
-
-	for i := 0; i < int((int(KeycodeCount) * int(KeysymsPerKeycode))); i++ {
-		xgb.Put32(buf[b:], uint32(Keysyms[i]))
-		b += 4
-	}
-
-	return buf
-}
-
-// ChangePointerControlCookie is a cookie used only for ChangePointerControl requests.
-type ChangePointerControlCookie struct {
-	*xgb.Cookie
-}
-
-// ChangePointerControl sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ChangePointerControl(c *xgb.Conn, AccelerationNumerator int16, AccelerationDenominator int16, Threshold int16, DoAcceleration bool, DoThreshold bool) ChangePointerControlCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(changePointerControlRequest(c, AccelerationNumerator, AccelerationDenominator, Threshold, DoAcceleration, DoThreshold), cookie)
-	return ChangePointerControlCookie{cookie}
-}
-
-// ChangePointerControlChecked sends a checked request.
-// If an error occurs, it can be retrieved using ChangePointerControlCookie.Check()
-func ChangePointerControlChecked(c *xgb.Conn, AccelerationNumerator int16, AccelerationDenominator int16, Threshold int16, DoAcceleration bool, DoThreshold bool) ChangePointerControlCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(changePointerControlRequest(c, AccelerationNumerator, AccelerationDenominator, Threshold, DoAcceleration, DoThreshold), cookie)
-	return ChangePointerControlCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ChangePointerControlCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ChangePointerControl
-// changePointerControlRequest writes a ChangePointerControl request to a byte slice.
-func changePointerControlRequest(c *xgb.Conn, AccelerationNumerator int16, AccelerationDenominator int16, Threshold int16, DoAcceleration bool, DoThreshold bool) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 105 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(AccelerationNumerator))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(AccelerationDenominator))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Threshold))
-	b += 2
-
-	if DoAcceleration {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	if DoThreshold {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	return buf
-}
-
-// ChangePropertyCookie is a cookie used only for ChangeProperty requests.
-type ChangePropertyCookie struct {
-	*xgb.Cookie
-}
-
-// ChangeProperty sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ChangeProperty(c *xgb.Conn, Mode byte, Window Window, Property Atom, Type Atom, Format byte, DataLen uint32, Data []byte) ChangePropertyCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(changePropertyRequest(c, Mode, Window, Property, Type, Format, DataLen, Data), cookie)
-	return ChangePropertyCookie{cookie}
-}
-
-// ChangePropertyChecked sends a checked request.
-// If an error occurs, it can be retrieved using ChangePropertyCookie.Check()
-func ChangePropertyChecked(c *xgb.Conn, Mode byte, Window Window, Property Atom, Type Atom, Format byte, DataLen uint32, Data []byte) ChangePropertyCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(changePropertyRequest(c, Mode, Window, Property, Type, Format, DataLen, Data), cookie)
-	return ChangePropertyCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ChangePropertyCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ChangeProperty
-// changePropertyRequest writes a ChangeProperty request to a byte slice.
-func changePropertyRequest(c *xgb.Conn, Mode byte, Window Window, Property Atom, Type Atom, Format byte, DataLen uint32, Data []byte) []byte {
-	size := xgb.Pad((24 + xgb.Pad((((int(DataLen) * int(Format)) / 8) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 18 // request opcode
-	b += 1
-
-	buf[b] = Mode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Property))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Type))
-	b += 4
-
-	buf[b] = Format
-	b += 1
-
-	b += 3 // padding
-
-	xgb.Put32(buf[b:], DataLen)
-	b += 4
-
-	copy(buf[b:], Data[:((int(DataLen)*int(Format))/8)])
-	b += int(((int(DataLen) * int(Format)) / 8))
-
-	return buf
-}
-
-// ChangeSaveSetCookie is a cookie used only for ChangeSaveSet requests.
-type ChangeSaveSetCookie struct {
-	*xgb.Cookie
-}
-
-// ChangeSaveSet sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ChangeSaveSet(c *xgb.Conn, Mode byte, Window Window) ChangeSaveSetCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(changeSaveSetRequest(c, Mode, Window), cookie)
-	return ChangeSaveSetCookie{cookie}
-}
-
-// ChangeSaveSetChecked sends a checked request.
-// If an error occurs, it can be retrieved using ChangeSaveSetCookie.Check()
-func ChangeSaveSetChecked(c *xgb.Conn, Mode byte, Window Window) ChangeSaveSetCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(changeSaveSetRequest(c, Mode, Window), cookie)
-	return ChangeSaveSetCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ChangeSaveSetCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ChangeSaveSet
-// changeSaveSetRequest writes a ChangeSaveSet request to a byte slice.
-func changeSaveSetRequest(c *xgb.Conn, Mode byte, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 6 // request opcode
-	b += 1
-
-	buf[b] = Mode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// ChangeWindowAttributesCookie is a cookie used only for ChangeWindowAttributes requests.
-type ChangeWindowAttributesCookie struct {
-	*xgb.Cookie
-}
-
-// ChangeWindowAttributes sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ChangeWindowAttributes(c *xgb.Conn, Window Window, ValueMask uint32, ValueList []uint32) ChangeWindowAttributesCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(changeWindowAttributesRequest(c, Window, ValueMask, ValueList), cookie)
-	return ChangeWindowAttributesCookie{cookie}
-}
-
-// ChangeWindowAttributesChecked sends a checked request.
-// If an error occurs, it can be retrieved using ChangeWindowAttributesCookie.Check()
-func ChangeWindowAttributesChecked(c *xgb.Conn, Window Window, ValueMask uint32, ValueList []uint32) ChangeWindowAttributesCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(changeWindowAttributesRequest(c, Window, ValueMask, ValueList), cookie)
-	return ChangeWindowAttributesCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ChangeWindowAttributesCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ChangeWindowAttributes
-// changeWindowAttributesRequest writes a ChangeWindowAttributes request to a byte slice.
-func changeWindowAttributesRequest(c *xgb.Conn, Window Window, ValueMask uint32, ValueList []uint32) []byte {
-	size := xgb.Pad((8 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 2 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	xgb.Put32(buf[b:], ValueMask)
-	b += 4
-	for i := 0; i < xgb.PopCount(int(ValueMask)); i++ {
-		xgb.Put32(buf[b:], ValueList[i])
-		b += 4
-	}
-	b = xgb.Pad(b)
-
-	return buf
-}
-
-// CirculateWindowCookie is a cookie used only for CirculateWindow requests.
-type CirculateWindowCookie struct {
-	*xgb.Cookie
-}
-
-// CirculateWindow sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CirculateWindow(c *xgb.Conn, Direction byte, Window Window) CirculateWindowCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(circulateWindowRequest(c, Direction, Window), cookie)
-	return CirculateWindowCookie{cookie}
-}
-
-// CirculateWindowChecked sends a checked request.
-// If an error occurs, it can be retrieved using CirculateWindowCookie.Check()
-func CirculateWindowChecked(c *xgb.Conn, Direction byte, Window Window) CirculateWindowCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(circulateWindowRequest(c, Direction, Window), cookie)
-	return CirculateWindowCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CirculateWindowCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CirculateWindow
-// circulateWindowRequest writes a CirculateWindow request to a byte slice.
-func circulateWindowRequest(c *xgb.Conn, Direction byte, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 13 // request opcode
-	b += 1
-
-	buf[b] = Direction
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// ClearAreaCookie is a cookie used only for ClearArea requests.
-type ClearAreaCookie struct {
-	*xgb.Cookie
-}
-
-// ClearArea sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ClearArea(c *xgb.Conn, Exposures bool, Window Window, X int16, Y int16, Width uint16, Height uint16) ClearAreaCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(clearAreaRequest(c, Exposures, Window, X, Y, Width, Height), cookie)
-	return ClearAreaCookie{cookie}
-}
-
-// ClearAreaChecked sends a checked request.
-// If an error occurs, it can be retrieved using ClearAreaCookie.Check()
-func ClearAreaChecked(c *xgb.Conn, Exposures bool, Window Window, X int16, Y int16, Width uint16, Height uint16) ClearAreaCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(clearAreaRequest(c, Exposures, Window, X, Y, Width, Height), cookie)
-	return ClearAreaCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ClearAreaCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ClearArea
-// clearAreaRequest writes a ClearArea request to a byte slice.
-func clearAreaRequest(c *xgb.Conn, Exposures bool, Window Window, X int16, Y int16, Width uint16, Height uint16) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 61 // request opcode
-	b += 1
-
-	if Exposures {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Y))
-	b += 2
-
-	xgb.Put16(buf[b:], Width)
-	b += 2
-
-	xgb.Put16(buf[b:], Height)
-	b += 2
-
-	return buf
-}
-
-// CloseFontCookie is a cookie used only for CloseFont requests.
-type CloseFontCookie struct {
-	*xgb.Cookie
-}
-
-// CloseFont sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CloseFont(c *xgb.Conn, Font Font) CloseFontCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(closeFontRequest(c, Font), cookie)
-	return CloseFontCookie{cookie}
-}
-
-// CloseFontChecked sends a checked request.
-// If an error occurs, it can be retrieved using CloseFontCookie.Check()
-func CloseFontChecked(c *xgb.Conn, Font Font) CloseFontCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(closeFontRequest(c, Font), cookie)
-	return CloseFontCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CloseFontCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CloseFont
-// closeFontRequest writes a CloseFont request to a byte slice.
-func closeFontRequest(c *xgb.Conn, Font Font) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 46 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Font))
-	b += 4
-
-	return buf
-}
-
-// ConfigureWindowCookie is a cookie used only for ConfigureWindow requests.
-type ConfigureWindowCookie struct {
-	*xgb.Cookie
-}
-
-// ConfigureWindow sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ConfigureWindow(c *xgb.Conn, Window Window, ValueMask uint16, ValueList []uint32) ConfigureWindowCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(configureWindowRequest(c, Window, ValueMask, ValueList), cookie)
-	return ConfigureWindowCookie{cookie}
-}
-
-// ConfigureWindowChecked sends a checked request.
-// If an error occurs, it can be retrieved using ConfigureWindowCookie.Check()
-func ConfigureWindowChecked(c *xgb.Conn, Window Window, ValueMask uint16, ValueList []uint32) ConfigureWindowCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(configureWindowRequest(c, Window, ValueMask, ValueList), cookie)
-	return ConfigureWindowCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ConfigureWindowCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ConfigureWindow
-// configureWindowRequest writes a ConfigureWindow request to a byte slice.
-func configureWindowRequest(c *xgb.Conn, Window Window, ValueMask uint16, ValueList []uint32) []byte {
-	size := xgb.Pad((10 + (2 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 12 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	xgb.Put16(buf[b:], ValueMask)
-	b += 2
-
-	b += 2 // padding
-
-	for i := 0; i < xgb.PopCount(int(ValueMask)); i++ {
-		xgb.Put32(buf[b:], ValueList[i])
-		b += 4
-	}
-	b = xgb.Pad(b)
-
-	return buf
-}
-
-// ConvertSelectionCookie is a cookie used only for ConvertSelection requests.
-type ConvertSelectionCookie struct {
-	*xgb.Cookie
-}
-
-// ConvertSelection sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ConvertSelection(c *xgb.Conn, Requestor Window, Selection Atom, Target Atom, Property Atom, Time Timestamp) ConvertSelectionCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(convertSelectionRequest(c, Requestor, Selection, Target, Property, Time), cookie)
-	return ConvertSelectionCookie{cookie}
-}
-
-// ConvertSelectionChecked sends a checked request.
-// If an error occurs, it can be retrieved using ConvertSelectionCookie.Check()
-func ConvertSelectionChecked(c *xgb.Conn, Requestor Window, Selection Atom, Target Atom, Property Atom, Time Timestamp) ConvertSelectionCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(convertSelectionRequest(c, Requestor, Selection, Target, Property, Time), cookie)
-	return ConvertSelectionCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ConvertSelectionCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ConvertSelection
-// convertSelectionRequest writes a ConvertSelection request to a byte slice.
-func convertSelectionRequest(c *xgb.Conn, Requestor Window, Selection Atom, Target Atom, Property Atom, Time Timestamp) []byte {
-	size := 24
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 24 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Requestor))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Selection))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Target))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Property))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Time))
-	b += 4
-
-	return buf
-}
-
-// CopyAreaCookie is a cookie used only for CopyArea requests.
-type CopyAreaCookie struct {
-	*xgb.Cookie
-}
-
-// CopyArea sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CopyArea(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16) CopyAreaCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(copyAreaRequest(c, SrcDrawable, DstDrawable, Gc, SrcX, SrcY, DstX, DstY, Width, Height), cookie)
-	return CopyAreaCookie{cookie}
-}
-
-// CopyAreaChecked sends a checked request.
-// If an error occurs, it can be retrieved using CopyAreaCookie.Check()
-func CopyAreaChecked(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16) CopyAreaCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(copyAreaRequest(c, SrcDrawable, DstDrawable, Gc, SrcX, SrcY, DstX, DstY, Width, Height), cookie)
-	return CopyAreaCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CopyAreaCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CopyArea
-// copyAreaRequest writes a CopyArea request to a byte slice.
-func copyAreaRequest(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16) []byte {
-	size := 28
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 62 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(SrcDrawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(DstDrawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstY))
-	b += 2
-
-	xgb.Put16(buf[b:], Width)
-	b += 2
-
-	xgb.Put16(buf[b:], Height)
-	b += 2
-
-	return buf
-}
-
-// CopyColormapAndFreeCookie is a cookie used only for CopyColormapAndFree requests.
-type CopyColormapAndFreeCookie struct {
-	*xgb.Cookie
-}
-
-// CopyColormapAndFree sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CopyColormapAndFree(c *xgb.Conn, Mid Colormap, SrcCmap Colormap) CopyColormapAndFreeCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(copyColormapAndFreeRequest(c, Mid, SrcCmap), cookie)
-	return CopyColormapAndFreeCookie{cookie}
-}
-
-// CopyColormapAndFreeChecked sends a checked request.
-// If an error occurs, it can be retrieved using CopyColormapAndFreeCookie.Check()
-func CopyColormapAndFreeChecked(c *xgb.Conn, Mid Colormap, SrcCmap Colormap) CopyColormapAndFreeCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(copyColormapAndFreeRequest(c, Mid, SrcCmap), cookie)
-	return CopyColormapAndFreeCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CopyColormapAndFreeCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CopyColormapAndFree
-// copyColormapAndFreeRequest writes a CopyColormapAndFree request to a byte slice.
-func copyColormapAndFreeRequest(c *xgb.Conn, Mid Colormap, SrcCmap Colormap) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 80 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Mid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(SrcCmap))
-	b += 4
-
-	return buf
-}
-
-// CopyGCCookie is a cookie used only for CopyGC requests.
-type CopyGCCookie struct {
-	*xgb.Cookie
-}
-
-// CopyGC sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CopyGC(c *xgb.Conn, SrcGc Gcontext, DstGc Gcontext, ValueMask uint32) CopyGCCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(copyGCRequest(c, SrcGc, DstGc, ValueMask), cookie)
-	return CopyGCCookie{cookie}
-}
-
-// CopyGCChecked sends a checked request.
-// If an error occurs, it can be retrieved using CopyGCCookie.Check()
-func CopyGCChecked(c *xgb.Conn, SrcGc Gcontext, DstGc Gcontext, ValueMask uint32) CopyGCCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(copyGCRequest(c, SrcGc, DstGc, ValueMask), cookie)
-	return CopyGCCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CopyGCCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CopyGC
-// copyGCRequest writes a CopyGC request to a byte slice.
-func copyGCRequest(c *xgb.Conn, SrcGc Gcontext, DstGc Gcontext, ValueMask uint32) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 57 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(SrcGc))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(DstGc))
-	b += 4
-
-	xgb.Put32(buf[b:], ValueMask)
-	b += 4
-
-	return buf
-}
-
-// CopyPlaneCookie is a cookie used only for CopyPlane requests.
-type CopyPlaneCookie struct {
-	*xgb.Cookie
-}
-
-// CopyPlane sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CopyPlane(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16, BitPlane uint32) CopyPlaneCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(copyPlaneRequest(c, SrcDrawable, DstDrawable, Gc, SrcX, SrcY, DstX, DstY, Width, Height, BitPlane), cookie)
-	return CopyPlaneCookie{cookie}
-}
-
-// CopyPlaneChecked sends a checked request.
-// If an error occurs, it can be retrieved using CopyPlaneCookie.Check()
-func CopyPlaneChecked(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16, BitPlane uint32) CopyPlaneCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(copyPlaneRequest(c, SrcDrawable, DstDrawable, Gc, SrcX, SrcY, DstX, DstY, Width, Height, BitPlane), cookie)
-	return CopyPlaneCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CopyPlaneCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CopyPlane
-// copyPlaneRequest writes a CopyPlane request to a byte slice.
-func copyPlaneRequest(c *xgb.Conn, SrcDrawable Drawable, DstDrawable Drawable, Gc Gcontext, SrcX int16, SrcY int16, DstX int16, DstY int16, Width uint16, Height uint16, BitPlane uint32) []byte {
-	size := 32
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 63 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(SrcDrawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(DstDrawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstY))
-	b += 2
-
-	xgb.Put16(buf[b:], Width)
-	b += 2
-
-	xgb.Put16(buf[b:], Height)
-	b += 2
-
-	xgb.Put32(buf[b:], BitPlane)
-	b += 4
-
-	return buf
-}
-
-// CreateColormapCookie is a cookie used only for CreateColormap requests.
-type CreateColormapCookie struct {
-	*xgb.Cookie
-}
-
-// CreateColormap sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateColormap(c *xgb.Conn, Alloc byte, Mid Colormap, Window Window, Visual Visualid) CreateColormapCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createColormapRequest(c, Alloc, Mid, Window, Visual), cookie)
-	return CreateColormapCookie{cookie}
-}
-
-// CreateColormapChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateColormapCookie.Check()
-func CreateColormapChecked(c *xgb.Conn, Alloc byte, Mid Colormap, Window Window, Visual Visualid) CreateColormapCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createColormapRequest(c, Alloc, Mid, Window, Visual), cookie)
-	return CreateColormapCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateColormapCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateColormap
-// createColormapRequest writes a CreateColormap request to a byte slice.
-func createColormapRequest(c *xgb.Conn, Alloc byte, Mid Colormap, Window Window, Visual Visualid) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 78 // request opcode
-	b += 1
-
-	buf[b] = Alloc
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Mid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Visual))
-	b += 4
-
-	return buf
-}
-
-// CreateCursorCookie is a cookie used only for CreateCursor requests.
-type CreateCursorCookie struct {
-	*xgb.Cookie
-}
-
-// CreateCursor sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateCursor(c *xgb.Conn, Cid Cursor, Source Pixmap, Mask Pixmap, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16, X uint16, Y uint16) CreateCursorCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createCursorRequest(c, Cid, Source, Mask, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue, X, Y), cookie)
-	return CreateCursorCookie{cookie}
-}
-
-// CreateCursorChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateCursorCookie.Check()
-func CreateCursorChecked(c *xgb.Conn, Cid Cursor, Source Pixmap, Mask Pixmap, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16, X uint16, Y uint16) CreateCursorCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createCursorRequest(c, Cid, Source, Mask, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue, X, Y), cookie)
-	return CreateCursorCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateCursorCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateCursor
-// createCursorRequest writes a CreateCursor request to a byte slice.
-func createCursorRequest(c *xgb.Conn, Cid Cursor, Source Pixmap, Mask Pixmap, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16, X uint16, Y uint16) []byte {
-	size := 32
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 93 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Source))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Mask))
-	b += 4
-
-	xgb.Put16(buf[b:], ForeRed)
-	b += 2
-
-	xgb.Put16(buf[b:], ForeGreen)
-	b += 2
-
-	xgb.Put16(buf[b:], ForeBlue)
-	b += 2
-
-	xgb.Put16(buf[b:], BackRed)
-	b += 2
-
-	xgb.Put16(buf[b:], BackGreen)
-	b += 2
-
-	xgb.Put16(buf[b:], BackBlue)
-	b += 2
-
-	xgb.Put16(buf[b:], X)
-	b += 2
-
-	xgb.Put16(buf[b:], Y)
-	b += 2
-
-	return buf
-}
-
-// CreateGCCookie is a cookie used only for CreateGC requests.
-type CreateGCCookie struct {
-	*xgb.Cookie
-}
-
-// CreateGC sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateGC(c *xgb.Conn, Cid Gcontext, Drawable Drawable, ValueMask uint32, ValueList []uint32) CreateGCCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createGCRequest(c, Cid, Drawable, ValueMask, ValueList), cookie)
-	return CreateGCCookie{cookie}
-}
-
-// CreateGCChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateGCCookie.Check()
-func CreateGCChecked(c *xgb.Conn, Cid Gcontext, Drawable Drawable, ValueMask uint32, ValueList []uint32) CreateGCCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createGCRequest(c, Cid, Drawable, ValueMask, ValueList), cookie)
-	return CreateGCCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateGCCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateGC
-// createGCRequest writes a CreateGC request to a byte slice.
-func createGCRequest(c *xgb.Conn, Cid Gcontext, Drawable Drawable, ValueMask uint32, ValueList []uint32) []byte {
-	size := xgb.Pad((12 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 55 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], ValueMask)
-	b += 4
-	for i := 0; i < xgb.PopCount(int(ValueMask)); i++ {
-		xgb.Put32(buf[b:], ValueList[i])
-		b += 4
-	}
-	b = xgb.Pad(b)
-
-	return buf
-}
-
-// CreateGlyphCursorCookie is a cookie used only for CreateGlyphCursor requests.
-type CreateGlyphCursorCookie struct {
-	*xgb.Cookie
-}
-
-// CreateGlyphCursor sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateGlyphCursor(c *xgb.Conn, Cid Cursor, SourceFont Font, MaskFont Font, SourceChar uint16, MaskChar uint16, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) CreateGlyphCursorCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createGlyphCursorRequest(c, Cid, SourceFont, MaskFont, SourceChar, MaskChar, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue), cookie)
-	return CreateGlyphCursorCookie{cookie}
-}
-
-// CreateGlyphCursorChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateGlyphCursorCookie.Check()
-func CreateGlyphCursorChecked(c *xgb.Conn, Cid Cursor, SourceFont Font, MaskFont Font, SourceChar uint16, MaskChar uint16, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) CreateGlyphCursorCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createGlyphCursorRequest(c, Cid, SourceFont, MaskFont, SourceChar, MaskChar, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue), cookie)
-	return CreateGlyphCursorCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateGlyphCursorCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateGlyphCursor
-// createGlyphCursorRequest writes a CreateGlyphCursor request to a byte slice.
-func createGlyphCursorRequest(c *xgb.Conn, Cid Cursor, SourceFont Font, MaskFont Font, SourceChar uint16, MaskChar uint16, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) []byte {
-	size := 32
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 94 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(SourceFont))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(MaskFont))
-	b += 4
-
-	xgb.Put16(buf[b:], SourceChar)
-	b += 2
-
-	xgb.Put16(buf[b:], MaskChar)
-	b += 2
-
-	xgb.Put16(buf[b:], ForeRed)
-	b += 2
-
-	xgb.Put16(buf[b:], ForeGreen)
-	b += 2
-
-	xgb.Put16(buf[b:], ForeBlue)
-	b += 2
-
-	xgb.Put16(buf[b:], BackRed)
-	b += 2
-
-	xgb.Put16(buf[b:], BackGreen)
-	b += 2
-
-	xgb.Put16(buf[b:], BackBlue)
-	b += 2
-
-	return buf
-}
-
-// CreatePixmapCookie is a cookie used only for CreatePixmap requests.
-type CreatePixmapCookie struct {
-	*xgb.Cookie
-}
-
-// CreatePixmap sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreatePixmap(c *xgb.Conn, Depth byte, Pid Pixmap, Drawable Drawable, Width uint16, Height uint16) CreatePixmapCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createPixmapRequest(c, Depth, Pid, Drawable, Width, Height), cookie)
-	return CreatePixmapCookie{cookie}
-}
-
-// CreatePixmapChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreatePixmapCookie.Check()
-func CreatePixmapChecked(c *xgb.Conn, Depth byte, Pid Pixmap, Drawable Drawable, Width uint16, Height uint16) CreatePixmapCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createPixmapRequest(c, Depth, Pid, Drawable, Width, Height), cookie)
-	return CreatePixmapCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreatePixmapCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreatePixmap
-// createPixmapRequest writes a CreatePixmap request to a byte slice.
-func createPixmapRequest(c *xgb.Conn, Depth byte, Pid Pixmap, Drawable Drawable, Width uint16, Height uint16) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 53 // request opcode
-	b += 1
-
-	buf[b] = Depth
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Pid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put16(buf[b:], Width)
-	b += 2
-
-	xgb.Put16(buf[b:], Height)
-	b += 2
-
-	return buf
-}
-
-// CreateWindowCookie is a cookie used only for CreateWindow requests.
-type CreateWindowCookie struct {
-	*xgb.Cookie
-}
-
-// CreateWindow sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func CreateWindow(c *xgb.Conn, Depth byte, Wid Window, Parent Window, X int16, Y int16, Width uint16, Height uint16, BorderWidth uint16, Class uint16, Visual Visualid, ValueMask uint32, ValueList []uint32) CreateWindowCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(createWindowRequest(c, Depth, Wid, Parent, X, Y, Width, Height, BorderWidth, Class, Visual, ValueMask, ValueList), cookie)
-	return CreateWindowCookie{cookie}
-}
-
-// CreateWindowChecked sends a checked request.
-// If an error occurs, it can be retrieved using CreateWindowCookie.Check()
-func CreateWindowChecked(c *xgb.Conn, Depth byte, Wid Window, Parent Window, X int16, Y int16, Width uint16, Height uint16, BorderWidth uint16, Class uint16, Visual Visualid, ValueMask uint32, ValueList []uint32) CreateWindowCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(createWindowRequest(c, Depth, Wid, Parent, X, Y, Width, Height, BorderWidth, Class, Visual, ValueMask, ValueList), cookie)
-	return CreateWindowCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook CreateWindowCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for CreateWindow
-// createWindowRequest writes a CreateWindow request to a byte slice.
-func createWindowRequest(c *xgb.Conn, Depth byte, Wid Window, Parent Window, X int16, Y int16, Width uint16, Height uint16, BorderWidth uint16, Class uint16, Visual Visualid, ValueMask uint32, ValueList []uint32) []byte {
-	size := xgb.Pad((28 + (4 + xgb.Pad((4 * xgb.PopCount(int(ValueMask)))))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 1 // request opcode
-	b += 1
-
-	buf[b] = Depth
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Wid))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Parent))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Y))
-	b += 2
-
-	xgb.Put16(buf[b:], Width)
-	b += 2
-
-	xgb.Put16(buf[b:], Height)
-	b += 2
-
-	xgb.Put16(buf[b:], BorderWidth)
-	b += 2
-
-	xgb.Put16(buf[b:], Class)
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Visual))
-	b += 4
-
-	xgb.Put32(buf[b:], ValueMask)
-	b += 4
-	for i := 0; i < xgb.PopCount(int(ValueMask)); i++ {
-		xgb.Put32(buf[b:], ValueList[i])
-		b += 4
-	}
-	b = xgb.Pad(b)
-
-	return buf
-}
-
-// DeletePropertyCookie is a cookie used only for DeleteProperty requests.
-type DeletePropertyCookie struct {
-	*xgb.Cookie
-}
-
-// DeleteProperty sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func DeleteProperty(c *xgb.Conn, Window Window, Property Atom) DeletePropertyCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(deletePropertyRequest(c, Window, Property), cookie)
-	return DeletePropertyCookie{cookie}
-}
-
-// DeletePropertyChecked sends a checked request.
-// If an error occurs, it can be retrieved using DeletePropertyCookie.Check()
-func DeletePropertyChecked(c *xgb.Conn, Window Window, Property Atom) DeletePropertyCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(deletePropertyRequest(c, Window, Property), cookie)
-	return DeletePropertyCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook DeletePropertyCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for DeleteProperty
-// deletePropertyRequest writes a DeleteProperty request to a byte slice.
-func deletePropertyRequest(c *xgb.Conn, Window Window, Property Atom) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 19 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Property))
-	b += 4
-
-	return buf
-}
-
-// DestroySubwindowsCookie is a cookie used only for DestroySubwindows requests.
-type DestroySubwindowsCookie struct {
-	*xgb.Cookie
-}
-
-// DestroySubwindows sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func DestroySubwindows(c *xgb.Conn, Window Window) DestroySubwindowsCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(destroySubwindowsRequest(c, Window), cookie)
-	return DestroySubwindowsCookie{cookie}
-}
-
-// DestroySubwindowsChecked sends a checked request.
-// If an error occurs, it can be retrieved using DestroySubwindowsCookie.Check()
-func DestroySubwindowsChecked(c *xgb.Conn, Window Window) DestroySubwindowsCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(destroySubwindowsRequest(c, Window), cookie)
-	return DestroySubwindowsCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook DestroySubwindowsCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for DestroySubwindows
-// destroySubwindowsRequest writes a DestroySubwindows request to a byte slice.
-func destroySubwindowsRequest(c *xgb.Conn, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 5 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// DestroyWindowCookie is a cookie used only for DestroyWindow requests.
-type DestroyWindowCookie struct {
-	*xgb.Cookie
-}
-
-// DestroyWindow sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func DestroyWindow(c *xgb.Conn, Window Window) DestroyWindowCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(destroyWindowRequest(c, Window), cookie)
-	return DestroyWindowCookie{cookie}
-}
-
-// DestroyWindowChecked sends a checked request.
-// If an error occurs, it can be retrieved using DestroyWindowCookie.Check()
-func DestroyWindowChecked(c *xgb.Conn, Window Window) DestroyWindowCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(destroyWindowRequest(c, Window), cookie)
-	return DestroyWindowCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook DestroyWindowCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for DestroyWindow
-// destroyWindowRequest writes a DestroyWindow request to a byte slice.
-func destroyWindowRequest(c *xgb.Conn, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 4 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// FillPolyCookie is a cookie used only for FillPoly requests.
-type FillPolyCookie struct {
-	*xgb.Cookie
-}
-
-// FillPoly sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func FillPoly(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Shape byte, CoordinateMode byte, Points []Point) FillPolyCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(fillPolyRequest(c, Drawable, Gc, Shape, CoordinateMode, Points), cookie)
-	return FillPolyCookie{cookie}
-}
-
-// FillPolyChecked sends a checked request.
-// If an error occurs, it can be retrieved using FillPolyCookie.Check()
-func FillPolyChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Shape byte, CoordinateMode byte, Points []Point) FillPolyCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(fillPolyRequest(c, Drawable, Gc, Shape, CoordinateMode, Points), cookie)
-	return FillPolyCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook FillPolyCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for FillPoly
-// fillPolyRequest writes a FillPoly request to a byte slice.
-func fillPolyRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Shape byte, CoordinateMode byte, Points []Point) []byte {
-	size := xgb.Pad((16 + xgb.Pad((len(Points) * 4))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 69 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	buf[b] = Shape
-	b += 1
-
-	buf[b] = CoordinateMode
-	b += 1
-
-	b += 2 // padding
-
-	b += PointListBytes(buf[b:], Points)
-
-	return buf
-}
-
-// ForceScreenSaverCookie is a cookie used only for ForceScreenSaver requests.
-type ForceScreenSaverCookie struct {
-	*xgb.Cookie
-}
-
-// ForceScreenSaver sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ForceScreenSaver(c *xgb.Conn, Mode byte) ForceScreenSaverCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(forceScreenSaverRequest(c, Mode), cookie)
-	return ForceScreenSaverCookie{cookie}
-}
-
-// ForceScreenSaverChecked sends a checked request.
-// If an error occurs, it can be retrieved using ForceScreenSaverCookie.Check()
-func ForceScreenSaverChecked(c *xgb.Conn, Mode byte) ForceScreenSaverCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(forceScreenSaverRequest(c, Mode), cookie)
-	return ForceScreenSaverCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ForceScreenSaverCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ForceScreenSaver
-// forceScreenSaverRequest writes a ForceScreenSaver request to a byte slice.
-func forceScreenSaverRequest(c *xgb.Conn, Mode byte) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 115 // request opcode
-	b += 1
-
-	buf[b] = Mode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// FreeColormapCookie is a cookie used only for FreeColormap requests.
-type FreeColormapCookie struct {
-	*xgb.Cookie
-}
-
-// FreeColormap sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func FreeColormap(c *xgb.Conn, Cmap Colormap) FreeColormapCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(freeColormapRequest(c, Cmap), cookie)
-	return FreeColormapCookie{cookie}
-}
-
-// FreeColormapChecked sends a checked request.
-// If an error occurs, it can be retrieved using FreeColormapCookie.Check()
-func FreeColormapChecked(c *xgb.Conn, Cmap Colormap) FreeColormapCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(freeColormapRequest(c, Cmap), cookie)
-	return FreeColormapCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook FreeColormapCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for FreeColormap
-// freeColormapRequest writes a FreeColormap request to a byte slice.
-func freeColormapRequest(c *xgb.Conn, Cmap Colormap) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 79 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	return buf
-}
-
-// FreeColorsCookie is a cookie used only for FreeColors requests.
-type FreeColorsCookie struct {
-	*xgb.Cookie
-}
-
-// FreeColors sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func FreeColors(c *xgb.Conn, Cmap Colormap, PlaneMask uint32, Pixels []uint32) FreeColorsCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(freeColorsRequest(c, Cmap, PlaneMask, Pixels), cookie)
-	return FreeColorsCookie{cookie}
-}
-
-// FreeColorsChecked sends a checked request.
-// If an error occurs, it can be retrieved using FreeColorsCookie.Check()
-func FreeColorsChecked(c *xgb.Conn, Cmap Colormap, PlaneMask uint32, Pixels []uint32) FreeColorsCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(freeColorsRequest(c, Cmap, PlaneMask, Pixels), cookie)
-	return FreeColorsCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook FreeColorsCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for FreeColors
-// freeColorsRequest writes a FreeColors request to a byte slice.
-func freeColorsRequest(c *xgb.Conn, Cmap Colormap, PlaneMask uint32, Pixels []uint32) []byte {
-	size := xgb.Pad((12 + xgb.Pad((len(Pixels) * 4))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 88 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	xgb.Put32(buf[b:], PlaneMask)
-	b += 4
-
-	for i := 0; i < int(len(Pixels)); i++ {
-		xgb.Put32(buf[b:], Pixels[i])
-		b += 4
-	}
-
-	return buf
-}
-
-// FreeCursorCookie is a cookie used only for FreeCursor requests.
-type FreeCursorCookie struct {
-	*xgb.Cookie
-}
-
-// FreeCursor sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func FreeCursor(c *xgb.Conn, Cursor Cursor) FreeCursorCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(freeCursorRequest(c, Cursor), cookie)
-	return FreeCursorCookie{cookie}
-}
-
-// FreeCursorChecked sends a checked request.
-// If an error occurs, it can be retrieved using FreeCursorCookie.Check()
-func FreeCursorChecked(c *xgb.Conn, Cursor Cursor) FreeCursorCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(freeCursorRequest(c, Cursor), cookie)
-	return FreeCursorCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook FreeCursorCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for FreeCursor
-// freeCursorRequest writes a FreeCursor request to a byte slice.
-func freeCursorRequest(c *xgb.Conn, Cursor Cursor) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 95 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cursor))
-	b += 4
-
-	return buf
-}
-
-// FreeGCCookie is a cookie used only for FreeGC requests.
-type FreeGCCookie struct {
-	*xgb.Cookie
-}
-
-// FreeGC sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func FreeGC(c *xgb.Conn, Gc Gcontext) FreeGCCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(freeGCRequest(c, Gc), cookie)
-	return FreeGCCookie{cookie}
-}
-
-// FreeGCChecked sends a checked request.
-// If an error occurs, it can be retrieved using FreeGCCookie.Check()
-func FreeGCChecked(c *xgb.Conn, Gc Gcontext) FreeGCCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(freeGCRequest(c, Gc), cookie)
-	return FreeGCCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook FreeGCCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for FreeGC
-// freeGCRequest writes a FreeGC request to a byte slice.
-func freeGCRequest(c *xgb.Conn, Gc Gcontext) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 60 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	return buf
-}
-
-// FreePixmapCookie is a cookie used only for FreePixmap requests.
-type FreePixmapCookie struct {
-	*xgb.Cookie
-}
-
-// FreePixmap sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func FreePixmap(c *xgb.Conn, Pixmap Pixmap) FreePixmapCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(freePixmapRequest(c, Pixmap), cookie)
-	return FreePixmapCookie{cookie}
-}
-
-// FreePixmapChecked sends a checked request.
-// If an error occurs, it can be retrieved using FreePixmapCookie.Check()
-func FreePixmapChecked(c *xgb.Conn, Pixmap Pixmap) FreePixmapCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(freePixmapRequest(c, Pixmap), cookie)
-	return FreePixmapCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook FreePixmapCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for FreePixmap
-// freePixmapRequest writes a FreePixmap request to a byte slice.
-func freePixmapRequest(c *xgb.Conn, Pixmap Pixmap) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 54 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Pixmap))
-	b += 4
-
-	return buf
-}
-
-// GetAtomNameCookie is a cookie used only for GetAtomName requests.
-type GetAtomNameCookie struct {
-	*xgb.Cookie
-}
-
-// GetAtomName sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetAtomNameCookie.Reply()
-func GetAtomName(c *xgb.Conn, Atom Atom) GetAtomNameCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getAtomNameRequest(c, Atom), cookie)
-	return GetAtomNameCookie{cookie}
-}
-
-// GetAtomNameUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetAtomNameUnchecked(c *xgb.Conn, Atom Atom) GetAtomNameCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getAtomNameRequest(c, Atom), cookie)
-	return GetAtomNameCookie{cookie}
-}
-
-// GetAtomNameReply represents the data returned from a GetAtomName request.
-type GetAtomNameReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	NameLen uint16
-	// padding: 22 bytes
-	Name string // size: xgb.Pad((int(NameLen) * 1))
-}
-
-// Reply blocks and returns the reply data for a GetAtomName request.
-func (cook GetAtomNameCookie) Reply() (*GetAtomNameReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getAtomNameReply(buf), nil
-}
-
-// getAtomNameReply reads a byte slice into a GetAtomNameReply value.
-func getAtomNameReply(buf []byte) *GetAtomNameReply {
-	v := new(GetAtomNameReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.NameLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 22 // padding
-
-	{
-		byteString := make([]byte, v.NameLen)
-		copy(byteString[:v.NameLen], buf[b:])
-		v.Name = string(byteString)
-		b += int(v.NameLen)
-	}
-
-	return v
-}
-
-// Write request to wire for GetAtomName
-// getAtomNameRequest writes a GetAtomName request to a byte slice.
-func getAtomNameRequest(c *xgb.Conn, Atom Atom) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 17 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Atom))
-	b += 4
-
-	return buf
-}
-
-// GetFontPathCookie is a cookie used only for GetFontPath requests.
-type GetFontPathCookie struct {
-	*xgb.Cookie
-}
-
-// GetFontPath sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetFontPathCookie.Reply()
-func GetFontPath(c *xgb.Conn) GetFontPathCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getFontPathRequest(c), cookie)
-	return GetFontPathCookie{cookie}
-}
-
-// GetFontPathUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetFontPathUnchecked(c *xgb.Conn) GetFontPathCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getFontPathRequest(c), cookie)
-	return GetFontPathCookie{cookie}
-}
-
-// GetFontPathReply represents the data returned from a GetFontPath request.
-type GetFontPathReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	PathLen uint16
-	// padding: 22 bytes
-	Path []Str // size: StrListSize(Path)
-}
-
-// Reply blocks and returns the reply data for a GetFontPath request.
-func (cook GetFontPathCookie) Reply() (*GetFontPathReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getFontPathReply(buf), nil
-}
-
-// getFontPathReply reads a byte slice into a GetFontPathReply value.
-func getFontPathReply(buf []byte) *GetFontPathReply {
-	v := new(GetFontPathReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.PathLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 22 // padding
-
-	v.Path = make([]Str, v.PathLen)
-	b += StrReadList(buf[b:], v.Path)
-
-	return v
-}
-
-// Write request to wire for GetFontPath
-// getFontPathRequest writes a GetFontPath request to a byte slice.
-func getFontPathRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 52 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// GetGeometryCookie is a cookie used only for GetGeometry requests.
-type GetGeometryCookie struct {
-	*xgb.Cookie
-}
-
-// GetGeometry sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetGeometryCookie.Reply()
-func GetGeometry(c *xgb.Conn, Drawable Drawable) GetGeometryCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getGeometryRequest(c, Drawable), cookie)
-	return GetGeometryCookie{cookie}
-}
-
-// GetGeometryUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetGeometryUnchecked(c *xgb.Conn, Drawable Drawable) GetGeometryCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getGeometryRequest(c, Drawable), cookie)
-	return GetGeometryCookie{cookie}
-}
-
-// GetGeometryReply represents the data returned from a GetGeometry request.
-type GetGeometryReply struct {
-	Sequence    uint16 // sequence number of the request for this reply
-	Length      uint32 // number of bytes in this reply
-	Depth       byte
-	Root        Window
-	X           int16
-	Y           int16
-	Width       uint16
-	Height      uint16
-	BorderWidth uint16
-	// padding: 2 bytes
-}
-
-// Reply blocks and returns the reply data for a GetGeometry request.
-func (cook GetGeometryCookie) Reply() (*GetGeometryReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getGeometryReply(buf), nil
-}
-
-// getGeometryReply reads a byte slice into a GetGeometryReply value.
-func getGeometryReply(buf []byte) *GetGeometryReply {
-	v := new(GetGeometryReply)
-	b := 1 // skip reply determinant
-
-	v.Depth = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Root = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.X = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Y = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Width = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Height = xgb.Get16(buf[b:])
-	b += 2
-
-	v.BorderWidth = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 2 // padding
-
-	return v
-}
-
-// Write request to wire for GetGeometry
-// getGeometryRequest writes a GetGeometry request to a byte slice.
-func getGeometryRequest(c *xgb.Conn, Drawable Drawable) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 14 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	return buf
-}
-
-// GetImageCookie is a cookie used only for GetImage requests.
-type GetImageCookie struct {
-	*xgb.Cookie
-}
-
-// GetImage sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetImageCookie.Reply()
-func GetImage(c *xgb.Conn, Format byte, Drawable Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32) GetImageCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getImageRequest(c, Format, Drawable, X, Y, Width, Height, PlaneMask), cookie)
-	return GetImageCookie{cookie}
-}
-
-// GetImageUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetImageUnchecked(c *xgb.Conn, Format byte, Drawable Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32) GetImageCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getImageRequest(c, Format, Drawable, X, Y, Width, Height, PlaneMask), cookie)
-	return GetImageCookie{cookie}
-}
-
-// GetImageReply represents the data returned from a GetImage request.
-type GetImageReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	Depth    byte
-	Visual   Visualid
-	// padding: 20 bytes
-	Data []byte // size: xgb.Pad(((int(Length) * 4) * 1))
-}
-
-// Reply blocks and returns the reply data for a GetImage request.
-func (cook GetImageCookie) Reply() (*GetImageReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getImageReply(buf), nil
-}
-
-// getImageReply reads a byte slice into a GetImageReply value.
-func getImageReply(buf []byte) *GetImageReply {
-	v := new(GetImageReply)
-	b := 1 // skip reply determinant
-
-	v.Depth = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Visual = Visualid(xgb.Get32(buf[b:]))
-	b += 4
-
-	b += 20 // padding
-
-	v.Data = make([]byte, (int(v.Length) * 4))
-	copy(v.Data[:(int(v.Length)*4)], buf[b:])
-	b += int((int(v.Length) * 4))
-
-	return v
-}
-
-// Write request to wire for GetImage
-// getImageRequest writes a GetImage request to a byte slice.
-func getImageRequest(c *xgb.Conn, Format byte, Drawable Drawable, X int16, Y int16, Width uint16, Height uint16, PlaneMask uint32) []byte {
-	size := 20
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 73 // request opcode
-	b += 1
-
-	buf[b] = Format
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Y))
-	b += 2
-
-	xgb.Put16(buf[b:], Width)
-	b += 2
-
-	xgb.Put16(buf[b:], Height)
-	b += 2
-
-	xgb.Put32(buf[b:], PlaneMask)
-	b += 4
-
-	return buf
-}
-
-// GetInputFocusCookie is a cookie used only for GetInputFocus requests.
-type GetInputFocusCookie struct {
-	*xgb.Cookie
-}
-
-// GetInputFocus sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetInputFocusCookie.Reply()
-func GetInputFocus(c *xgb.Conn) GetInputFocusCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getInputFocusRequest(c), cookie)
-	return GetInputFocusCookie{cookie}
-}
-
-// GetInputFocusUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetInputFocusUnchecked(c *xgb.Conn) GetInputFocusCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getInputFocusRequest(c), cookie)
-	return GetInputFocusCookie{cookie}
-}
-
-// GetInputFocusReply represents the data returned from a GetInputFocus request.
-type GetInputFocusReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	RevertTo byte
-	Focus    Window
-}
-
-// Reply blocks and returns the reply data for a GetInputFocus request.
-func (cook GetInputFocusCookie) Reply() (*GetInputFocusReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getInputFocusReply(buf), nil
-}
-
-// getInputFocusReply reads a byte slice into a GetInputFocusReply value.
-func getInputFocusReply(buf []byte) *GetInputFocusReply {
-	v := new(GetInputFocusReply)
-	b := 1 // skip reply determinant
-
-	v.RevertTo = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Focus = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	return v
-}
-
-// Write request to wire for GetInputFocus
-// getInputFocusRequest writes a GetInputFocus request to a byte slice.
-func getInputFocusRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 43 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// GetKeyboardControlCookie is a cookie used only for GetKeyboardControl requests.
-type GetKeyboardControlCookie struct {
-	*xgb.Cookie
-}
-
-// GetKeyboardControl sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetKeyboardControlCookie.Reply()
-func GetKeyboardControl(c *xgb.Conn) GetKeyboardControlCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getKeyboardControlRequest(c), cookie)
-	return GetKeyboardControlCookie{cookie}
-}
-
-// GetKeyboardControlUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetKeyboardControlUnchecked(c *xgb.Conn) GetKeyboardControlCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getKeyboardControlRequest(c), cookie)
-	return GetKeyboardControlCookie{cookie}
-}
-
-// GetKeyboardControlReply represents the data returned from a GetKeyboardControl request.
-type GetKeyboardControlReply struct {
-	Sequence         uint16 // sequence number of the request for this reply
-	Length           uint32 // number of bytes in this reply
-	GlobalAutoRepeat byte
-	LedMask          uint32
-	KeyClickPercent  byte
-	BellPercent      byte
-	BellPitch        uint16
-	BellDuration     uint16
-	// padding: 2 bytes
-	AutoRepeats []byte // size: 32
-}
-
-// Reply blocks and returns the reply data for a GetKeyboardControl request.
-func (cook GetKeyboardControlCookie) Reply() (*GetKeyboardControlReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getKeyboardControlReply(buf), nil
-}
-
-// getKeyboardControlReply reads a byte slice into a GetKeyboardControlReply value.
-func getKeyboardControlReply(buf []byte) *GetKeyboardControlReply {
-	v := new(GetKeyboardControlReply)
-	b := 1 // skip reply determinant
-
-	v.GlobalAutoRepeat = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.LedMask = xgb.Get32(buf[b:])
-	b += 4
-
-	v.KeyClickPercent = buf[b]
-	b += 1
-
-	v.BellPercent = buf[b]
-	b += 1
-
-	v.BellPitch = xgb.Get16(buf[b:])
-	b += 2
-
-	v.BellDuration = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 2 // padding
-
-	v.AutoRepeats = make([]byte, 32)
-	copy(v.AutoRepeats[:32], buf[b:])
-	b += int(32)
-
-	return v
-}
-
-// Write request to wire for GetKeyboardControl
-// getKeyboardControlRequest writes a GetKeyboardControl request to a byte slice.
-func getKeyboardControlRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 103 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// GetKeyboardMappingCookie is a cookie used only for GetKeyboardMapping requests.
-type GetKeyboardMappingCookie struct {
-	*xgb.Cookie
-}
-
-// GetKeyboardMapping sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetKeyboardMappingCookie.Reply()
-func GetKeyboardMapping(c *xgb.Conn, FirstKeycode Keycode, Count byte) GetKeyboardMappingCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getKeyboardMappingRequest(c, FirstKeycode, Count), cookie)
-	return GetKeyboardMappingCookie{cookie}
-}
-
-// GetKeyboardMappingUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetKeyboardMappingUnchecked(c *xgb.Conn, FirstKeycode Keycode, Count byte) GetKeyboardMappingCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getKeyboardMappingRequest(c, FirstKeycode, Count), cookie)
-	return GetKeyboardMappingCookie{cookie}
-}
-
-// GetKeyboardMappingReply represents the data returned from a GetKeyboardMapping request.
-type GetKeyboardMappingReply struct {
-	Sequence          uint16 // sequence number of the request for this reply
-	Length            uint32 // number of bytes in this reply
-	KeysymsPerKeycode byte
-	// padding: 24 bytes
-	Keysyms []Keysym // size: xgb.Pad((int(Length) * 4))
-}
-
-// Reply blocks and returns the reply data for a GetKeyboardMapping request.
-func (cook GetKeyboardMappingCookie) Reply() (*GetKeyboardMappingReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getKeyboardMappingReply(buf), nil
-}
-
-// getKeyboardMappingReply reads a byte slice into a GetKeyboardMappingReply value.
-func getKeyboardMappingReply(buf []byte) *GetKeyboardMappingReply {
-	v := new(GetKeyboardMappingReply)
-	b := 1 // skip reply determinant
-
-	v.KeysymsPerKeycode = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	b += 24 // padding
-
-	v.Keysyms = make([]Keysym, v.Length)
-	for i := 0; i < int(v.Length); i++ {
-		v.Keysyms[i] = Keysym(xgb.Get32(buf[b:]))
-		b += 4
-	}
-
-	return v
-}
-
-// Write request to wire for GetKeyboardMapping
-// getKeyboardMappingRequest writes a GetKeyboardMapping request to a byte slice.
-func getKeyboardMappingRequest(c *xgb.Conn, FirstKeycode Keycode, Count byte) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 101 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	buf[b] = byte(FirstKeycode)
-	b += 1
-
-	buf[b] = Count
-	b += 1
-
-	return buf
-}
-
-// GetModifierMappingCookie is a cookie used only for GetModifierMapping requests.
-type GetModifierMappingCookie struct {
-	*xgb.Cookie
-}
-
-// GetModifierMapping sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetModifierMappingCookie.Reply()
-func GetModifierMapping(c *xgb.Conn) GetModifierMappingCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getModifierMappingRequest(c), cookie)
-	return GetModifierMappingCookie{cookie}
-}
-
-// GetModifierMappingUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetModifierMappingUnchecked(c *xgb.Conn) GetModifierMappingCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getModifierMappingRequest(c), cookie)
-	return GetModifierMappingCookie{cookie}
-}
-
-// GetModifierMappingReply represents the data returned from a GetModifierMapping request.
-type GetModifierMappingReply struct {
-	Sequence            uint16 // sequence number of the request for this reply
-	Length              uint32 // number of bytes in this reply
-	KeycodesPerModifier byte
-	// padding: 24 bytes
-	Keycodes []Keycode // size: xgb.Pad(((int(KeycodesPerModifier) * 8) * 1))
-}
-
-// Reply blocks and returns the reply data for a GetModifierMapping request.
-func (cook GetModifierMappingCookie) Reply() (*GetModifierMappingReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getModifierMappingReply(buf), nil
-}
-
-// getModifierMappingReply reads a byte slice into a GetModifierMappingReply value.
-func getModifierMappingReply(buf []byte) *GetModifierMappingReply {
-	v := new(GetModifierMappingReply)
-	b := 1 // skip reply determinant
-
-	v.KeycodesPerModifier = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	b += 24 // padding
-
-	v.Keycodes = make([]Keycode, (int(v.KeycodesPerModifier) * 8))
-	for i := 0; i < int((int(v.KeycodesPerModifier) * 8)); i++ {
-		v.Keycodes[i] = Keycode(buf[b])
-		b += 1
-	}
-
-	return v
-}
-
-// Write request to wire for GetModifierMapping
-// getModifierMappingRequest writes a GetModifierMapping request to a byte slice.
-func getModifierMappingRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 119 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// GetMotionEventsCookie is a cookie used only for GetMotionEvents requests.
-type GetMotionEventsCookie struct {
-	*xgb.Cookie
-}
-
-// GetMotionEvents sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetMotionEventsCookie.Reply()
-func GetMotionEvents(c *xgb.Conn, Window Window, Start Timestamp, Stop Timestamp) GetMotionEventsCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getMotionEventsRequest(c, Window, Start, Stop), cookie)
-	return GetMotionEventsCookie{cookie}
-}
-
-// GetMotionEventsUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetMotionEventsUnchecked(c *xgb.Conn, Window Window, Start Timestamp, Stop Timestamp) GetMotionEventsCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getMotionEventsRequest(c, Window, Start, Stop), cookie)
-	return GetMotionEventsCookie{cookie}
-}
-
-// GetMotionEventsReply represents the data returned from a GetMotionEvents request.
-type GetMotionEventsReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	EventsLen uint32
-	// padding: 20 bytes
-	Events []Timecoord // size: xgb.Pad((int(EventsLen) * 8))
-}
-
-// Reply blocks and returns the reply data for a GetMotionEvents request.
-func (cook GetMotionEventsCookie) Reply() (*GetMotionEventsReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getMotionEventsReply(buf), nil
-}
-
-// getMotionEventsReply reads a byte slice into a GetMotionEventsReply value.
-func getMotionEventsReply(buf []byte) *GetMotionEventsReply {
-	v := new(GetMotionEventsReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.EventsLen = xgb.Get32(buf[b:])
-	b += 4
-
-	b += 20 // padding
-
-	v.Events = make([]Timecoord, v.EventsLen)
-	b += TimecoordReadList(buf[b:], v.Events)
-
-	return v
-}
-
-// Write request to wire for GetMotionEvents
-// getMotionEventsRequest writes a GetMotionEvents request to a byte slice.
-func getMotionEventsRequest(c *xgb.Conn, Window Window, Start Timestamp, Stop Timestamp) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 39 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Start))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Stop))
-	b += 4
-
-	return buf
-}
-
-// GetPointerControlCookie is a cookie used only for GetPointerControl requests.
-type GetPointerControlCookie struct {
-	*xgb.Cookie
-}
-
-// GetPointerControl sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetPointerControlCookie.Reply()
-func GetPointerControl(c *xgb.Conn) GetPointerControlCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getPointerControlRequest(c), cookie)
-	return GetPointerControlCookie{cookie}
-}
-
-// GetPointerControlUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetPointerControlUnchecked(c *xgb.Conn) GetPointerControlCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getPointerControlRequest(c), cookie)
-	return GetPointerControlCookie{cookie}
-}
-
-// GetPointerControlReply represents the data returned from a GetPointerControl request.
-type GetPointerControlReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	AccelerationNumerator   uint16
-	AccelerationDenominator uint16
-	Threshold               uint16
-	// padding: 18 bytes
-}
-
-// Reply blocks and returns the reply data for a GetPointerControl request.
-func (cook GetPointerControlCookie) Reply() (*GetPointerControlReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getPointerControlReply(buf), nil
-}
-
-// getPointerControlReply reads a byte slice into a GetPointerControlReply value.
-func getPointerControlReply(buf []byte) *GetPointerControlReply {
-	v := new(GetPointerControlReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.AccelerationNumerator = xgb.Get16(buf[b:])
-	b += 2
-
-	v.AccelerationDenominator = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Threshold = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 18 // padding
-
-	return v
-}
-
-// Write request to wire for GetPointerControl
-// getPointerControlRequest writes a GetPointerControl request to a byte slice.
-func getPointerControlRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 106 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// GetPointerMappingCookie is a cookie used only for GetPointerMapping requests.
-type GetPointerMappingCookie struct {
-	*xgb.Cookie
-}
-
-// GetPointerMapping sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetPointerMappingCookie.Reply()
-func GetPointerMapping(c *xgb.Conn) GetPointerMappingCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getPointerMappingRequest(c), cookie)
-	return GetPointerMappingCookie{cookie}
-}
-
-// GetPointerMappingUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetPointerMappingUnchecked(c *xgb.Conn) GetPointerMappingCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getPointerMappingRequest(c), cookie)
-	return GetPointerMappingCookie{cookie}
-}
-
-// GetPointerMappingReply represents the data returned from a GetPointerMapping request.
-type GetPointerMappingReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	MapLen   byte
-	// padding: 24 bytes
-	Map []byte // size: xgb.Pad((int(MapLen) * 1))
-}
-
-// Reply blocks and returns the reply data for a GetPointerMapping request.
-func (cook GetPointerMappingCookie) Reply() (*GetPointerMappingReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getPointerMappingReply(buf), nil
-}
-
-// getPointerMappingReply reads a byte slice into a GetPointerMappingReply value.
-func getPointerMappingReply(buf []byte) *GetPointerMappingReply {
-	v := new(GetPointerMappingReply)
-	b := 1 // skip reply determinant
-
-	v.MapLen = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	b += 24 // padding
-
-	v.Map = make([]byte, v.MapLen)
-	copy(v.Map[:v.MapLen], buf[b:])
-	b += int(v.MapLen)
-
-	return v
-}
-
-// Write request to wire for GetPointerMapping
-// getPointerMappingRequest writes a GetPointerMapping request to a byte slice.
-func getPointerMappingRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 117 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// GetPropertyCookie is a cookie used only for GetProperty requests.
-type GetPropertyCookie struct {
-	*xgb.Cookie
-}
-
-// GetProperty sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetPropertyCookie.Reply()
-func GetProperty(c *xgb.Conn, Delete bool, Window Window, Property Atom, Type Atom, LongOffset uint32, LongLength uint32) GetPropertyCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getPropertyRequest(c, Delete, Window, Property, Type, LongOffset, LongLength), cookie)
-	return GetPropertyCookie{cookie}
-}
-
-// GetPropertyUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetPropertyUnchecked(c *xgb.Conn, Delete bool, Window Window, Property Atom, Type Atom, LongOffset uint32, LongLength uint32) GetPropertyCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getPropertyRequest(c, Delete, Window, Property, Type, LongOffset, LongLength), cookie)
-	return GetPropertyCookie{cookie}
-}
-
-// GetPropertyReply represents the data returned from a GetProperty request.
-type GetPropertyReply struct {
-	Sequence   uint16 // sequence number of the request for this reply
-	Length     uint32 // number of bytes in this reply
-	Format     byte
-	Type       Atom
-	BytesAfter uint32
-	ValueLen   uint32
-	// padding: 12 bytes
-	Value []byte // size: xgb.Pad(((int(ValueLen) * (int(Format) / 8)) * 1))
-}
-
-// Reply blocks and returns the reply data for a GetProperty request.
-func (cook GetPropertyCookie) Reply() (*GetPropertyReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getPropertyReply(buf), nil
-}
-
-// getPropertyReply reads a byte slice into a GetPropertyReply value.
-func getPropertyReply(buf []byte) *GetPropertyReply {
-	v := new(GetPropertyReply)
-	b := 1 // skip reply determinant
-
-	v.Format = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Type = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.BytesAfter = xgb.Get32(buf[b:])
-	b += 4
-
-	v.ValueLen = xgb.Get32(buf[b:])
-	b += 4
-
-	b += 12 // padding
-
-	v.Value = make([]byte, (int(v.ValueLen) * (int(v.Format) / 8)))
-	copy(v.Value[:(int(v.ValueLen)*(int(v.Format)/8))], buf[b:])
-	b += int((int(v.ValueLen) * (int(v.Format) / 8)))
-
-	return v
-}
-
-// Write request to wire for GetProperty
-// getPropertyRequest writes a GetProperty request to a byte slice.
-func getPropertyRequest(c *xgb.Conn, Delete bool, Window Window, Property Atom, Type Atom, LongOffset uint32, LongLength uint32) []byte {
-	size := 24
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 20 // request opcode
-	b += 1
-
-	if Delete {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Property))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Type))
-	b += 4
-
-	xgb.Put32(buf[b:], LongOffset)
-	b += 4
-
-	xgb.Put32(buf[b:], LongLength)
-	b += 4
-
-	return buf
-}
-
-// GetScreenSaverCookie is a cookie used only for GetScreenSaver requests.
-type GetScreenSaverCookie struct {
-	*xgb.Cookie
-}
-
-// GetScreenSaver sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetScreenSaverCookie.Reply()
-func GetScreenSaver(c *xgb.Conn) GetScreenSaverCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getScreenSaverRequest(c), cookie)
-	return GetScreenSaverCookie{cookie}
-}
-
-// GetScreenSaverUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetScreenSaverUnchecked(c *xgb.Conn) GetScreenSaverCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getScreenSaverRequest(c), cookie)
-	return GetScreenSaverCookie{cookie}
-}
-
-// GetScreenSaverReply represents the data returned from a GetScreenSaver request.
-type GetScreenSaverReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	Timeout        uint16
-	Interval       uint16
-	PreferBlanking byte
-	AllowExposures byte
-	// padding: 18 bytes
-}
-
-// Reply blocks and returns the reply data for a GetScreenSaver request.
-func (cook GetScreenSaverCookie) Reply() (*GetScreenSaverReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getScreenSaverReply(buf), nil
-}
-
-// getScreenSaverReply reads a byte slice into a GetScreenSaverReply value.
-func getScreenSaverReply(buf []byte) *GetScreenSaverReply {
-	v := new(GetScreenSaverReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Timeout = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Interval = xgb.Get16(buf[b:])
-	b += 2
-
-	v.PreferBlanking = buf[b]
-	b += 1
-
-	v.AllowExposures = buf[b]
-	b += 1
-
-	b += 18 // padding
-
-	return v
-}
-
-// Write request to wire for GetScreenSaver
-// getScreenSaverRequest writes a GetScreenSaver request to a byte slice.
-func getScreenSaverRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 108 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// GetSelectionOwnerCookie is a cookie used only for GetSelectionOwner requests.
-type GetSelectionOwnerCookie struct {
-	*xgb.Cookie
-}
-
-// GetSelectionOwner sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetSelectionOwnerCookie.Reply()
-func GetSelectionOwner(c *xgb.Conn, Selection Atom) GetSelectionOwnerCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getSelectionOwnerRequest(c, Selection), cookie)
-	return GetSelectionOwnerCookie{cookie}
-}
-
-// GetSelectionOwnerUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetSelectionOwnerUnchecked(c *xgb.Conn, Selection Atom) GetSelectionOwnerCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getSelectionOwnerRequest(c, Selection), cookie)
-	return GetSelectionOwnerCookie{cookie}
-}
-
-// GetSelectionOwnerReply represents the data returned from a GetSelectionOwner request.
-type GetSelectionOwnerReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	Owner Window
-}
-
-// Reply blocks and returns the reply data for a GetSelectionOwner request.
-func (cook GetSelectionOwnerCookie) Reply() (*GetSelectionOwnerReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getSelectionOwnerReply(buf), nil
-}
-
-// getSelectionOwnerReply reads a byte slice into a GetSelectionOwnerReply value.
-func getSelectionOwnerReply(buf []byte) *GetSelectionOwnerReply {
-	v := new(GetSelectionOwnerReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Owner = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	return v
-}
-
-// Write request to wire for GetSelectionOwner
-// getSelectionOwnerRequest writes a GetSelectionOwner request to a byte slice.
-func getSelectionOwnerRequest(c *xgb.Conn, Selection Atom) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 23 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Selection))
-	b += 4
-
-	return buf
-}
-
-// GetWindowAttributesCookie is a cookie used only for GetWindowAttributes requests.
-type GetWindowAttributesCookie struct {
-	*xgb.Cookie
-}
-
-// GetWindowAttributes sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GetWindowAttributesCookie.Reply()
-func GetWindowAttributes(c *xgb.Conn, Window Window) GetWindowAttributesCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(getWindowAttributesRequest(c, Window), cookie)
-	return GetWindowAttributesCookie{cookie}
-}
-
-// GetWindowAttributesUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GetWindowAttributesUnchecked(c *xgb.Conn, Window Window) GetWindowAttributesCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(getWindowAttributesRequest(c, Window), cookie)
-	return GetWindowAttributesCookie{cookie}
-}
-
-// GetWindowAttributesReply represents the data returned from a GetWindowAttributes request.
-type GetWindowAttributesReply struct {
-	Sequence           uint16 // sequence number of the request for this reply
-	Length             uint32 // number of bytes in this reply
-	BackingStore       byte
-	Visual             Visualid
-	Class              uint16
-	BitGravity         byte
-	WinGravity         byte
-	BackingPlanes      uint32
-	BackingPixel       uint32
-	SaveUnder          bool
-	MapIsInstalled     bool
-	MapState           byte
-	OverrideRedirect   bool
-	Colormap           Colormap
-	AllEventMasks      uint32
-	YourEventMask      uint32
-	DoNotPropagateMask uint16
-	// padding: 2 bytes
-}
-
-// Reply blocks and returns the reply data for a GetWindowAttributes request.
-func (cook GetWindowAttributesCookie) Reply() (*GetWindowAttributesReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return getWindowAttributesReply(buf), nil
-}
-
-// getWindowAttributesReply reads a byte slice into a GetWindowAttributesReply value.
-func getWindowAttributesReply(buf []byte) *GetWindowAttributesReply {
-	v := new(GetWindowAttributesReply)
-	b := 1 // skip reply determinant
-
-	v.BackingStore = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Visual = Visualid(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Class = xgb.Get16(buf[b:])
-	b += 2
-
-	v.BitGravity = buf[b]
-	b += 1
-
-	v.WinGravity = buf[b]
-	b += 1
-
-	v.BackingPlanes = xgb.Get32(buf[b:])
-	b += 4
-
-	v.BackingPixel = xgb.Get32(buf[b:])
-	b += 4
-
-	if buf[b] == 1 {
-		v.SaveUnder = true
-	} else {
-		v.SaveUnder = false
-	}
-	b += 1
-
-	if buf[b] == 1 {
-		v.MapIsInstalled = true
-	} else {
-		v.MapIsInstalled = false
-	}
-	b += 1
-
-	v.MapState = buf[b]
-	b += 1
-
-	if buf[b] == 1 {
-		v.OverrideRedirect = true
-	} else {
-		v.OverrideRedirect = false
-	}
-	b += 1
-
-	v.Colormap = Colormap(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.AllEventMasks = xgb.Get32(buf[b:])
-	b += 4
-
-	v.YourEventMask = xgb.Get32(buf[b:])
-	b += 4
-
-	v.DoNotPropagateMask = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 2 // padding
-
-	return v
-}
-
-// Write request to wire for GetWindowAttributes
-// getWindowAttributesRequest writes a GetWindowAttributes request to a byte slice.
-func getWindowAttributesRequest(c *xgb.Conn, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 3 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// GrabButtonCookie is a cookie used only for GrabButton requests.
-type GrabButtonCookie struct {
-	*xgb.Cookie
-}
-
-// GrabButton sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GrabButton(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Button byte, Modifiers uint16) GrabButtonCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(grabButtonRequest(c, OwnerEvents, GrabWindow, EventMask, PointerMode, KeyboardMode, ConfineTo, Cursor, Button, Modifiers), cookie)
-	return GrabButtonCookie{cookie}
-}
-
-// GrabButtonChecked sends a checked request.
-// If an error occurs, it can be retrieved using GrabButtonCookie.Check()
-func GrabButtonChecked(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Button byte, Modifiers uint16) GrabButtonCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(grabButtonRequest(c, OwnerEvents, GrabWindow, EventMask, PointerMode, KeyboardMode, ConfineTo, Cursor, Button, Modifiers), cookie)
-	return GrabButtonCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook GrabButtonCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for GrabButton
-// grabButtonRequest writes a GrabButton request to a byte slice.
-func grabButtonRequest(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Button byte, Modifiers uint16) []byte {
-	size := 24
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 28 // request opcode
-	b += 1
-
-	if OwnerEvents {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(GrabWindow))
-	b += 4
-
-	xgb.Put16(buf[b:], EventMask)
-	b += 2
-
-	buf[b] = PointerMode
-	b += 1
-
-	buf[b] = KeyboardMode
-	b += 1
-
-	xgb.Put32(buf[b:], uint32(ConfineTo))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Cursor))
-	b += 4
-
-	buf[b] = Button
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], Modifiers)
-	b += 2
-
-	return buf
-}
-
-// GrabKeyCookie is a cookie used only for GrabKey requests.
-type GrabKeyCookie struct {
-	*xgb.Cookie
-}
-
-// GrabKey sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GrabKey(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Modifiers uint16, Key Keycode, PointerMode byte, KeyboardMode byte) GrabKeyCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(grabKeyRequest(c, OwnerEvents, GrabWindow, Modifiers, Key, PointerMode, KeyboardMode), cookie)
-	return GrabKeyCookie{cookie}
-}
-
-// GrabKeyChecked sends a checked request.
-// If an error occurs, it can be retrieved using GrabKeyCookie.Check()
-func GrabKeyChecked(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Modifiers uint16, Key Keycode, PointerMode byte, KeyboardMode byte) GrabKeyCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(grabKeyRequest(c, OwnerEvents, GrabWindow, Modifiers, Key, PointerMode, KeyboardMode), cookie)
-	return GrabKeyCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook GrabKeyCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for GrabKey
-// grabKeyRequest writes a GrabKey request to a byte slice.
-func grabKeyRequest(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Modifiers uint16, Key Keycode, PointerMode byte, KeyboardMode byte) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 33 // request opcode
-	b += 1
-
-	if OwnerEvents {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(GrabWindow))
-	b += 4
-
-	xgb.Put16(buf[b:], Modifiers)
-	b += 2
-
-	buf[b] = byte(Key)
-	b += 1
-
-	buf[b] = PointerMode
-	b += 1
-
-	buf[b] = KeyboardMode
-	b += 1
-
-	b += 3 // padding
-
-	return buf
-}
-
-// GrabKeyboardCookie is a cookie used only for GrabKeyboard requests.
-type GrabKeyboardCookie struct {
-	*xgb.Cookie
-}
-
-// GrabKeyboard sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GrabKeyboardCookie.Reply()
-func GrabKeyboard(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Time Timestamp, PointerMode byte, KeyboardMode byte) GrabKeyboardCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(grabKeyboardRequest(c, OwnerEvents, GrabWindow, Time, PointerMode, KeyboardMode), cookie)
-	return GrabKeyboardCookie{cookie}
-}
-
-// GrabKeyboardUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GrabKeyboardUnchecked(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Time Timestamp, PointerMode byte, KeyboardMode byte) GrabKeyboardCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(grabKeyboardRequest(c, OwnerEvents, GrabWindow, Time, PointerMode, KeyboardMode), cookie)
-	return GrabKeyboardCookie{cookie}
-}
-
-// GrabKeyboardReply represents the data returned from a GrabKeyboard request.
-type GrabKeyboardReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	Status   byte
-}
-
-// Reply blocks and returns the reply data for a GrabKeyboard request.
-func (cook GrabKeyboardCookie) Reply() (*GrabKeyboardReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return grabKeyboardReply(buf), nil
-}
-
-// grabKeyboardReply reads a byte slice into a GrabKeyboardReply value.
-func grabKeyboardReply(buf []byte) *GrabKeyboardReply {
-	v := new(GrabKeyboardReply)
-	b := 1 // skip reply determinant
-
-	v.Status = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	return v
-}
-
-// Write request to wire for GrabKeyboard
-// grabKeyboardRequest writes a GrabKeyboard request to a byte slice.
-func grabKeyboardRequest(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, Time Timestamp, PointerMode byte, KeyboardMode byte) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 31 // request opcode
-	b += 1
-
-	if OwnerEvents {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(GrabWindow))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Time))
-	b += 4
-
-	buf[b] = PointerMode
-	b += 1
-
-	buf[b] = KeyboardMode
-	b += 1
-
-	b += 2 // padding
-
-	return buf
-}
-
-// GrabPointerCookie is a cookie used only for GrabPointer requests.
-type GrabPointerCookie struct {
-	*xgb.Cookie
-}
-
-// GrabPointer sends a checked request.
-// If an error occurs, it will be returned with the reply by calling GrabPointerCookie.Reply()
-func GrabPointer(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Time Timestamp) GrabPointerCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(grabPointerRequest(c, OwnerEvents, GrabWindow, EventMask, PointerMode, KeyboardMode, ConfineTo, Cursor, Time), cookie)
-	return GrabPointerCookie{cookie}
-}
-
-// GrabPointerUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GrabPointerUnchecked(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Time Timestamp) GrabPointerCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(grabPointerRequest(c, OwnerEvents, GrabWindow, EventMask, PointerMode, KeyboardMode, ConfineTo, Cursor, Time), cookie)
-	return GrabPointerCookie{cookie}
-}
-
-// GrabPointerReply represents the data returned from a GrabPointer request.
-type GrabPointerReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	Status   byte
-}
-
-// Reply blocks and returns the reply data for a GrabPointer request.
-func (cook GrabPointerCookie) Reply() (*GrabPointerReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return grabPointerReply(buf), nil
-}
-
-// grabPointerReply reads a byte slice into a GrabPointerReply value.
-func grabPointerReply(buf []byte) *GrabPointerReply {
-	v := new(GrabPointerReply)
-	b := 1 // skip reply determinant
-
-	v.Status = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	return v
-}
-
-// Write request to wire for GrabPointer
-// grabPointerRequest writes a GrabPointer request to a byte slice.
-func grabPointerRequest(c *xgb.Conn, OwnerEvents bool, GrabWindow Window, EventMask uint16, PointerMode byte, KeyboardMode byte, ConfineTo Window, Cursor Cursor, Time Timestamp) []byte {
-	size := 24
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 26 // request opcode
-	b += 1
-
-	if OwnerEvents {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(GrabWindow))
-	b += 4
-
-	xgb.Put16(buf[b:], EventMask)
-	b += 2
-
-	buf[b] = PointerMode
-	b += 1
-
-	buf[b] = KeyboardMode
-	b += 1
-
-	xgb.Put32(buf[b:], uint32(ConfineTo))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Cursor))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Time))
-	b += 4
-
-	return buf
-}
-
-// GrabServerCookie is a cookie used only for GrabServer requests.
-type GrabServerCookie struct {
-	*xgb.Cookie
-}
-
-// GrabServer sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func GrabServer(c *xgb.Conn) GrabServerCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(grabServerRequest(c), cookie)
-	return GrabServerCookie{cookie}
-}
-
-// GrabServerChecked sends a checked request.
-// If an error occurs, it can be retrieved using GrabServerCookie.Check()
-func GrabServerChecked(c *xgb.Conn) GrabServerCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(grabServerRequest(c), cookie)
-	return GrabServerCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook GrabServerCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for GrabServer
-// grabServerRequest writes a GrabServer request to a byte slice.
-func grabServerRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 36 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// ImageText16Cookie is a cookie used only for ImageText16 requests.
-type ImageText16Cookie struct {
-	*xgb.Cookie
-}
-
-// ImageText16 sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ImageText16(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String []Char2b) ImageText16Cookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(imageText16Request(c, StringLen, Drawable, Gc, X, Y, String), cookie)
-	return ImageText16Cookie{cookie}
-}
-
-// ImageText16Checked sends a checked request.
-// If an error occurs, it can be retrieved using ImageText16Cookie.Check()
-func ImageText16Checked(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String []Char2b) ImageText16Cookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(imageText16Request(c, StringLen, Drawable, Gc, X, Y, String), cookie)
-	return ImageText16Cookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ImageText16Cookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ImageText16
-// imageText16Request writes a ImageText16 request to a byte slice.
-func imageText16Request(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String []Char2b) []byte {
-	size := xgb.Pad((16 + xgb.Pad((int(StringLen) * 2))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 77 // request opcode
-	b += 1
-
-	buf[b] = StringLen
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Y))
-	b += 2
-
-	b += Char2bListBytes(buf[b:], String)
-
-	return buf
-}
-
-// ImageText8Cookie is a cookie used only for ImageText8 requests.
-type ImageText8Cookie struct {
-	*xgb.Cookie
-}
-
-// ImageText8 sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ImageText8(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String string) ImageText8Cookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(imageText8Request(c, StringLen, Drawable, Gc, X, Y, String), cookie)
-	return ImageText8Cookie{cookie}
-}
-
-// ImageText8Checked sends a checked request.
-// If an error occurs, it can be retrieved using ImageText8Cookie.Check()
-func ImageText8Checked(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String string) ImageText8Cookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(imageText8Request(c, StringLen, Drawable, Gc, X, Y, String), cookie)
-	return ImageText8Cookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ImageText8Cookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ImageText8
-// imageText8Request writes a ImageText8 request to a byte slice.
-func imageText8Request(c *xgb.Conn, StringLen byte, Drawable Drawable, Gc Gcontext, X int16, Y int16, String string) []byte {
-	size := xgb.Pad((16 + xgb.Pad((int(StringLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 76 // request opcode
-	b += 1
-
-	buf[b] = StringLen
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Y))
-	b += 2
-
-	copy(buf[b:], String[:StringLen])
-	b += int(StringLen)
-
-	return buf
-}
-
-// InstallColormapCookie is a cookie used only for InstallColormap requests.
-type InstallColormapCookie struct {
-	*xgb.Cookie
-}
-
-// InstallColormap sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func InstallColormap(c *xgb.Conn, Cmap Colormap) InstallColormapCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(installColormapRequest(c, Cmap), cookie)
-	return InstallColormapCookie{cookie}
-}
-
-// InstallColormapChecked sends a checked request.
-// If an error occurs, it can be retrieved using InstallColormapCookie.Check()
-func InstallColormapChecked(c *xgb.Conn, Cmap Colormap) InstallColormapCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(installColormapRequest(c, Cmap), cookie)
-	return InstallColormapCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook InstallColormapCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for InstallColormap
-// installColormapRequest writes a InstallColormap request to a byte slice.
-func installColormapRequest(c *xgb.Conn, Cmap Colormap) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 81 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	return buf
-}
-
-// InternAtomCookie is a cookie used only for InternAtom requests.
-type InternAtomCookie struct {
-	*xgb.Cookie
-}
-
-// InternAtom sends a checked request.
-// If an error occurs, it will be returned with the reply by calling InternAtomCookie.Reply()
-func InternAtom(c *xgb.Conn, OnlyIfExists bool, NameLen uint16, Name string) InternAtomCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(internAtomRequest(c, OnlyIfExists, NameLen, Name), cookie)
-	return InternAtomCookie{cookie}
-}
-
-// InternAtomUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func InternAtomUnchecked(c *xgb.Conn, OnlyIfExists bool, NameLen uint16, Name string) InternAtomCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(internAtomRequest(c, OnlyIfExists, NameLen, Name), cookie)
-	return InternAtomCookie{cookie}
-}
-
-// InternAtomReply represents the data returned from a InternAtom request.
-type InternAtomReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	Atom Atom
-}
-
-// Reply blocks and returns the reply data for a InternAtom request.
-func (cook InternAtomCookie) Reply() (*InternAtomReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return internAtomReply(buf), nil
-}
-
-// internAtomReply reads a byte slice into a InternAtomReply value.
-func internAtomReply(buf []byte) *InternAtomReply {
-	v := new(InternAtomReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Atom = Atom(xgb.Get32(buf[b:]))
-	b += 4
-
-	return v
-}
-
-// Write request to wire for InternAtom
-// internAtomRequest writes a InternAtom request to a byte slice.
-func internAtomRequest(c *xgb.Conn, OnlyIfExists bool, NameLen uint16, Name string) []byte {
-	size := xgb.Pad((8 + xgb.Pad((int(NameLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 16 // request opcode
-	b += 1
-
-	if OnlyIfExists {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put16(buf[b:], NameLen)
-	b += 2
-
-	b += 2 // padding
-
-	copy(buf[b:], Name[:NameLen])
-	b += int(NameLen)
-
-	return buf
-}
-
-// KillClientCookie is a cookie used only for KillClient requests.
-type KillClientCookie struct {
-	*xgb.Cookie
-}
-
-// KillClient sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func KillClient(c *xgb.Conn, Resource uint32) KillClientCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(killClientRequest(c, Resource), cookie)
-	return KillClientCookie{cookie}
-}
-
-// KillClientChecked sends a checked request.
-// If an error occurs, it can be retrieved using KillClientCookie.Check()
-func KillClientChecked(c *xgb.Conn, Resource uint32) KillClientCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(killClientRequest(c, Resource), cookie)
-	return KillClientCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook KillClientCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for KillClient
-// killClientRequest writes a KillClient request to a byte slice.
-func killClientRequest(c *xgb.Conn, Resource uint32) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 113 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], Resource)
-	b += 4
-
-	return buf
-}
-
-// ListExtensionsCookie is a cookie used only for ListExtensions requests.
-type ListExtensionsCookie struct {
-	*xgb.Cookie
-}
-
-// ListExtensions sends a checked request.
-// If an error occurs, it will be returned with the reply by calling ListExtensionsCookie.Reply()
-func ListExtensions(c *xgb.Conn) ListExtensionsCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(listExtensionsRequest(c), cookie)
-	return ListExtensionsCookie{cookie}
-}
-
-// ListExtensionsUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ListExtensionsUnchecked(c *xgb.Conn) ListExtensionsCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(listExtensionsRequest(c), cookie)
-	return ListExtensionsCookie{cookie}
-}
-
-// ListExtensionsReply represents the data returned from a ListExtensions request.
-type ListExtensionsReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	NamesLen byte
-	// padding: 24 bytes
-	Names []Str // size: StrListSize(Names)
-}
-
-// Reply blocks and returns the reply data for a ListExtensions request.
-func (cook ListExtensionsCookie) Reply() (*ListExtensionsReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return listExtensionsReply(buf), nil
-}
-
-// listExtensionsReply reads a byte slice into a ListExtensionsReply value.
-func listExtensionsReply(buf []byte) *ListExtensionsReply {
-	v := new(ListExtensionsReply)
-	b := 1 // skip reply determinant
-
-	v.NamesLen = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	b += 24 // padding
-
-	v.Names = make([]Str, v.NamesLen)
-	b += StrReadList(buf[b:], v.Names)
-
-	return v
-}
-
-// Write request to wire for ListExtensions
-// listExtensionsRequest writes a ListExtensions request to a byte slice.
-func listExtensionsRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 99 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// ListFontsCookie is a cookie used only for ListFonts requests.
-type ListFontsCookie struct {
-	*xgb.Cookie
-}
-
-// ListFonts sends a checked request.
-// If an error occurs, it will be returned with the reply by calling ListFontsCookie.Reply()
-func ListFonts(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) ListFontsCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(listFontsRequest(c, MaxNames, PatternLen, Pattern), cookie)
-	return ListFontsCookie{cookie}
-}
-
-// ListFontsUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ListFontsUnchecked(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) ListFontsCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(listFontsRequest(c, MaxNames, PatternLen, Pattern), cookie)
-	return ListFontsCookie{cookie}
-}
-
-// ListFontsReply represents the data returned from a ListFonts request.
-type ListFontsReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	NamesLen uint16
-	// padding: 22 bytes
-	Names []Str // size: StrListSize(Names)
-}
-
-// Reply blocks and returns the reply data for a ListFonts request.
-func (cook ListFontsCookie) Reply() (*ListFontsReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return listFontsReply(buf), nil
-}
-
-// listFontsReply reads a byte slice into a ListFontsReply value.
-func listFontsReply(buf []byte) *ListFontsReply {
-	v := new(ListFontsReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.NamesLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 22 // padding
-
-	v.Names = make([]Str, v.NamesLen)
-	b += StrReadList(buf[b:], v.Names)
-
-	return v
-}
-
-// Write request to wire for ListFonts
-// listFontsRequest writes a ListFonts request to a byte slice.
-func listFontsRequest(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) []byte {
-	size := xgb.Pad((8 + xgb.Pad((int(PatternLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 49 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put16(buf[b:], MaxNames)
-	b += 2
-
-	xgb.Put16(buf[b:], PatternLen)
-	b += 2
-
-	copy(buf[b:], Pattern[:PatternLen])
-	b += int(PatternLen)
-
-	return buf
-}
-
-// ListFontsWithInfoCookie is a cookie used only for ListFontsWithInfo requests.
-type ListFontsWithInfoCookie struct {
-	*xgb.Cookie
-}
-
-// ListFontsWithInfo sends a checked request.
-// If an error occurs, it will be returned with the reply by calling ListFontsWithInfoCookie.Reply()
-func ListFontsWithInfo(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) ListFontsWithInfoCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(listFontsWithInfoRequest(c, MaxNames, PatternLen, Pattern), cookie)
-	return ListFontsWithInfoCookie{cookie}
-}
-
-// ListFontsWithInfoUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ListFontsWithInfoUnchecked(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) ListFontsWithInfoCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(listFontsWithInfoRequest(c, MaxNames, PatternLen, Pattern), cookie)
-	return ListFontsWithInfoCookie{cookie}
-}
-
-// ListFontsWithInfoReply represents the data returned from a ListFontsWithInfo request.
-type ListFontsWithInfoReply struct {
-	Sequence  uint16 // sequence number of the request for this reply
-	Length    uint32 // number of bytes in this reply
-	NameLen   byte
-	MinBounds Charinfo
-	// padding: 4 bytes
-	MaxBounds Charinfo
-	// padding: 4 bytes
-	MinCharOrByte2 uint16
-	MaxCharOrByte2 uint16
-	DefaultChar    uint16
-	PropertiesLen  uint16
-	DrawDirection  byte
-	MinByte1       byte
-	MaxByte1       byte
-	AllCharsExist  bool
-	FontAscent     int16
-	FontDescent    int16
-	RepliesHint    uint32
-	Properties     []Fontprop // size: xgb.Pad((int(PropertiesLen) * 8))
-	Name           string     // size: xgb.Pad((int(NameLen) * 1))
-}
-
-// Reply blocks and returns the reply data for a ListFontsWithInfo request.
-func (cook ListFontsWithInfoCookie) Reply() (*ListFontsWithInfoReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return listFontsWithInfoReply(buf), nil
-}
-
-// listFontsWithInfoReply reads a byte slice into a ListFontsWithInfoReply value.
-func listFontsWithInfoReply(buf []byte) *ListFontsWithInfoReply {
-	v := new(ListFontsWithInfoReply)
-	b := 1 // skip reply determinant
-
-	v.NameLen = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.MinBounds = Charinfo{}
-	b += CharinfoRead(buf[b:], &v.MinBounds)
-
-	b += 4 // padding
-
-	v.MaxBounds = Charinfo{}
-	b += CharinfoRead(buf[b:], &v.MaxBounds)
-
-	b += 4 // padding
-
-	v.MinCharOrByte2 = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MaxCharOrByte2 = xgb.Get16(buf[b:])
-	b += 2
-
-	v.DefaultChar = xgb.Get16(buf[b:])
-	b += 2
-
-	v.PropertiesLen = xgb.Get16(buf[b:])
-	b += 2
-
-	v.DrawDirection = buf[b]
-	b += 1
-
-	v.MinByte1 = buf[b]
-	b += 1
-
-	v.MaxByte1 = buf[b]
-	b += 1
-
-	if buf[b] == 1 {
-		v.AllCharsExist = true
-	} else {
-		v.AllCharsExist = false
-	}
-	b += 1
-
-	v.FontAscent = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.FontDescent = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.RepliesHint = xgb.Get32(buf[b:])
-	b += 4
-
-	v.Properties = make([]Fontprop, v.PropertiesLen)
-	b += FontpropReadList(buf[b:], v.Properties)
-
-	{
-		byteString := make([]byte, v.NameLen)
-		copy(byteString[:v.NameLen], buf[b:])
-		v.Name = string(byteString)
-		b += int(v.NameLen)
-	}
-
-	return v
-}
-
-// Write request to wire for ListFontsWithInfo
-// listFontsWithInfoRequest writes a ListFontsWithInfo request to a byte slice.
-func listFontsWithInfoRequest(c *xgb.Conn, MaxNames uint16, PatternLen uint16, Pattern string) []byte {
-	size := xgb.Pad((8 + xgb.Pad((int(PatternLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 50 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put16(buf[b:], MaxNames)
-	b += 2
-
-	xgb.Put16(buf[b:], PatternLen)
-	b += 2
-
-	copy(buf[b:], Pattern[:PatternLen])
-	b += int(PatternLen)
-
-	return buf
-}
-
-// ListHostsCookie is a cookie used only for ListHosts requests.
-type ListHostsCookie struct {
-	*xgb.Cookie
-}
-
-// ListHosts sends a checked request.
-// If an error occurs, it will be returned with the reply by calling ListHostsCookie.Reply()
-func ListHosts(c *xgb.Conn) ListHostsCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(listHostsRequest(c), cookie)
-	return ListHostsCookie{cookie}
-}
-
-// ListHostsUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ListHostsUnchecked(c *xgb.Conn) ListHostsCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(listHostsRequest(c), cookie)
-	return ListHostsCookie{cookie}
-}
-
-// ListHostsReply represents the data returned from a ListHosts request.
-type ListHostsReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	Mode     byte
-	HostsLen uint16
-	// padding: 22 bytes
-	Hosts []Host // size: HostListSize(Hosts)
-}
-
-// Reply blocks and returns the reply data for a ListHosts request.
-func (cook ListHostsCookie) Reply() (*ListHostsReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return listHostsReply(buf), nil
-}
-
-// listHostsReply reads a byte slice into a ListHostsReply value.
-func listHostsReply(buf []byte) *ListHostsReply {
-	v := new(ListHostsReply)
-	b := 1 // skip reply determinant
-
-	v.Mode = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.HostsLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 22 // padding
-
-	v.Hosts = make([]Host, v.HostsLen)
-	b += HostReadList(buf[b:], v.Hosts)
-
-	return v
-}
-
-// Write request to wire for ListHosts
-// listHostsRequest writes a ListHosts request to a byte slice.
-func listHostsRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 110 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// ListInstalledColormapsCookie is a cookie used only for ListInstalledColormaps requests.
-type ListInstalledColormapsCookie struct {
-	*xgb.Cookie
-}
-
-// ListInstalledColormaps sends a checked request.
-// If an error occurs, it will be returned with the reply by calling ListInstalledColormapsCookie.Reply()
-func ListInstalledColormaps(c *xgb.Conn, Window Window) ListInstalledColormapsCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(listInstalledColormapsRequest(c, Window), cookie)
-	return ListInstalledColormapsCookie{cookie}
-}
-
-// ListInstalledColormapsUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ListInstalledColormapsUnchecked(c *xgb.Conn, Window Window) ListInstalledColormapsCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(listInstalledColormapsRequest(c, Window), cookie)
-	return ListInstalledColormapsCookie{cookie}
-}
-
-// ListInstalledColormapsReply represents the data returned from a ListInstalledColormaps request.
-type ListInstalledColormapsReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	CmapsLen uint16
-	// padding: 22 bytes
-	Cmaps []Colormap // size: xgb.Pad((int(CmapsLen) * 4))
-}
-
-// Reply blocks and returns the reply data for a ListInstalledColormaps request.
-func (cook ListInstalledColormapsCookie) Reply() (*ListInstalledColormapsReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return listInstalledColormapsReply(buf), nil
-}
-
-// listInstalledColormapsReply reads a byte slice into a ListInstalledColormapsReply value.
-func listInstalledColormapsReply(buf []byte) *ListInstalledColormapsReply {
-	v := new(ListInstalledColormapsReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.CmapsLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 22 // padding
-
-	v.Cmaps = make([]Colormap, v.CmapsLen)
-	for i := 0; i < int(v.CmapsLen); i++ {
-		v.Cmaps[i] = Colormap(xgb.Get32(buf[b:]))
-		b += 4
-	}
-
-	return v
-}
-
-// Write request to wire for ListInstalledColormaps
-// listInstalledColormapsRequest writes a ListInstalledColormaps request to a byte slice.
-func listInstalledColormapsRequest(c *xgb.Conn, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 83 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// ListPropertiesCookie is a cookie used only for ListProperties requests.
-type ListPropertiesCookie struct {
-	*xgb.Cookie
-}
-
-// ListProperties sends a checked request.
-// If an error occurs, it will be returned with the reply by calling ListPropertiesCookie.Reply()
-func ListProperties(c *xgb.Conn, Window Window) ListPropertiesCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(listPropertiesRequest(c, Window), cookie)
-	return ListPropertiesCookie{cookie}
-}
-
-// ListPropertiesUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ListPropertiesUnchecked(c *xgb.Conn, Window Window) ListPropertiesCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(listPropertiesRequest(c, Window), cookie)
-	return ListPropertiesCookie{cookie}
-}
-
-// ListPropertiesReply represents the data returned from a ListProperties request.
-type ListPropertiesReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	AtomsLen uint16
-	// padding: 22 bytes
-	Atoms []Atom // size: xgb.Pad((int(AtomsLen) * 4))
-}
-
-// Reply blocks and returns the reply data for a ListProperties request.
-func (cook ListPropertiesCookie) Reply() (*ListPropertiesReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return listPropertiesReply(buf), nil
-}
-
-// listPropertiesReply reads a byte slice into a ListPropertiesReply value.
-func listPropertiesReply(buf []byte) *ListPropertiesReply {
-	v := new(ListPropertiesReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.AtomsLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 22 // padding
-
-	v.Atoms = make([]Atom, v.AtomsLen)
-	for i := 0; i < int(v.AtomsLen); i++ {
-		v.Atoms[i] = Atom(xgb.Get32(buf[b:]))
-		b += 4
-	}
-
-	return v
-}
-
-// Write request to wire for ListProperties
-// listPropertiesRequest writes a ListProperties request to a byte slice.
-func listPropertiesRequest(c *xgb.Conn, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 21 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// LookupColorCookie is a cookie used only for LookupColor requests.
-type LookupColorCookie struct {
-	*xgb.Cookie
-}
-
-// LookupColor sends a checked request.
-// If an error occurs, it will be returned with the reply by calling LookupColorCookie.Reply()
-func LookupColor(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) LookupColorCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(lookupColorRequest(c, Cmap, NameLen, Name), cookie)
-	return LookupColorCookie{cookie}
-}
-
-// LookupColorUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func LookupColorUnchecked(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) LookupColorCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(lookupColorRequest(c, Cmap, NameLen, Name), cookie)
-	return LookupColorCookie{cookie}
-}
-
-// LookupColorReply represents the data returned from a LookupColor request.
-type LookupColorReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	ExactRed    uint16
-	ExactGreen  uint16
-	ExactBlue   uint16
-	VisualRed   uint16
-	VisualGreen uint16
-	VisualBlue  uint16
-}
-
-// Reply blocks and returns the reply data for a LookupColor request.
-func (cook LookupColorCookie) Reply() (*LookupColorReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return lookupColorReply(buf), nil
-}
-
-// lookupColorReply reads a byte slice into a LookupColorReply value.
-func lookupColorReply(buf []byte) *LookupColorReply {
-	v := new(LookupColorReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.ExactRed = xgb.Get16(buf[b:])
-	b += 2
-
-	v.ExactGreen = xgb.Get16(buf[b:])
-	b += 2
-
-	v.ExactBlue = xgb.Get16(buf[b:])
-	b += 2
-
-	v.VisualRed = xgb.Get16(buf[b:])
-	b += 2
-
-	v.VisualGreen = xgb.Get16(buf[b:])
-	b += 2
-
-	v.VisualBlue = xgb.Get16(buf[b:])
-	b += 2
-
-	return v
-}
-
-// Write request to wire for LookupColor
-// lookupColorRequest writes a LookupColor request to a byte slice.
-func lookupColorRequest(c *xgb.Conn, Cmap Colormap, NameLen uint16, Name string) []byte {
-	size := xgb.Pad((12 + xgb.Pad((int(NameLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 92 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	xgb.Put16(buf[b:], NameLen)
-	b += 2
-
-	b += 2 // padding
-
-	copy(buf[b:], Name[:NameLen])
-	b += int(NameLen)
-
-	return buf
-}
-
-// MapSubwindowsCookie is a cookie used only for MapSubwindows requests.
-type MapSubwindowsCookie struct {
-	*xgb.Cookie
-}
-
-// MapSubwindows sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func MapSubwindows(c *xgb.Conn, Window Window) MapSubwindowsCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(mapSubwindowsRequest(c, Window), cookie)
-	return MapSubwindowsCookie{cookie}
-}
-
-// MapSubwindowsChecked sends a checked request.
-// If an error occurs, it can be retrieved using MapSubwindowsCookie.Check()
-func MapSubwindowsChecked(c *xgb.Conn, Window Window) MapSubwindowsCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(mapSubwindowsRequest(c, Window), cookie)
-	return MapSubwindowsCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook MapSubwindowsCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for MapSubwindows
-// mapSubwindowsRequest writes a MapSubwindows request to a byte slice.
-func mapSubwindowsRequest(c *xgb.Conn, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 9 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// MapWindowCookie is a cookie used only for MapWindow requests.
-type MapWindowCookie struct {
-	*xgb.Cookie
-}
-
-// MapWindow sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func MapWindow(c *xgb.Conn, Window Window) MapWindowCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(mapWindowRequest(c, Window), cookie)
-	return MapWindowCookie{cookie}
-}
-
-// MapWindowChecked sends a checked request.
-// If an error occurs, it can be retrieved using MapWindowCookie.Check()
-func MapWindowChecked(c *xgb.Conn, Window Window) MapWindowCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(mapWindowRequest(c, Window), cookie)
-	return MapWindowCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook MapWindowCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for MapWindow
-// mapWindowRequest writes a MapWindow request to a byte slice.
-func mapWindowRequest(c *xgb.Conn, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 8 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// NoOperationCookie is a cookie used only for NoOperation requests.
-type NoOperationCookie struct {
-	*xgb.Cookie
-}
-
-// NoOperation sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func NoOperation(c *xgb.Conn) NoOperationCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(noOperationRequest(c), cookie)
-	return NoOperationCookie{cookie}
-}
-
-// NoOperationChecked sends a checked request.
-// If an error occurs, it can be retrieved using NoOperationCookie.Check()
-func NoOperationChecked(c *xgb.Conn) NoOperationCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(noOperationRequest(c), cookie)
-	return NoOperationCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook NoOperationCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for NoOperation
-// noOperationRequest writes a NoOperation request to a byte slice.
-func noOperationRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 127 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// OpenFontCookie is a cookie used only for OpenFont requests.
-type OpenFontCookie struct {
-	*xgb.Cookie
-}
-
-// OpenFont sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func OpenFont(c *xgb.Conn, Fid Font, NameLen uint16, Name string) OpenFontCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(openFontRequest(c, Fid, NameLen, Name), cookie)
-	return OpenFontCookie{cookie}
-}
-
-// OpenFontChecked sends a checked request.
-// If an error occurs, it can be retrieved using OpenFontCookie.Check()
-func OpenFontChecked(c *xgb.Conn, Fid Font, NameLen uint16, Name string) OpenFontCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(openFontRequest(c, Fid, NameLen, Name), cookie)
-	return OpenFontCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook OpenFontCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for OpenFont
-// openFontRequest writes a OpenFont request to a byte slice.
-func openFontRequest(c *xgb.Conn, Fid Font, NameLen uint16, Name string) []byte {
-	size := xgb.Pad((12 + xgb.Pad((int(NameLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 45 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Fid))
-	b += 4
-
-	xgb.Put16(buf[b:], NameLen)
-	b += 2
-
-	b += 2 // padding
-
-	copy(buf[b:], Name[:NameLen])
-	b += int(NameLen)
-
-	return buf
-}
-
-// PolyArcCookie is a cookie used only for PolyArc requests.
-type PolyArcCookie struct {
-	*xgb.Cookie
-}
-
-// PolyArc sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func PolyArc(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) PolyArcCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(polyArcRequest(c, Drawable, Gc, Arcs), cookie)
-	return PolyArcCookie{cookie}
-}
-
-// PolyArcChecked sends a checked request.
-// If an error occurs, it can be retrieved using PolyArcCookie.Check()
-func PolyArcChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) PolyArcCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(polyArcRequest(c, Drawable, Gc, Arcs), cookie)
-	return PolyArcCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook PolyArcCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for PolyArc
-// polyArcRequest writes a PolyArc request to a byte slice.
-func polyArcRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) []byte {
-	size := xgb.Pad((12 + xgb.Pad((len(Arcs) * 12))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 68 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	b += ArcListBytes(buf[b:], Arcs)
-
-	return buf
-}
-
-// PolyFillArcCookie is a cookie used only for PolyFillArc requests.
-type PolyFillArcCookie struct {
-	*xgb.Cookie
-}
-
-// PolyFillArc sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func PolyFillArc(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) PolyFillArcCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(polyFillArcRequest(c, Drawable, Gc, Arcs), cookie)
-	return PolyFillArcCookie{cookie}
-}
-
-// PolyFillArcChecked sends a checked request.
-// If an error occurs, it can be retrieved using PolyFillArcCookie.Check()
-func PolyFillArcChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) PolyFillArcCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(polyFillArcRequest(c, Drawable, Gc, Arcs), cookie)
-	return PolyFillArcCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook PolyFillArcCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for PolyFillArc
-// polyFillArcRequest writes a PolyFillArc request to a byte slice.
-func polyFillArcRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Arcs []Arc) []byte {
-	size := xgb.Pad((12 + xgb.Pad((len(Arcs) * 12))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 71 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	b += ArcListBytes(buf[b:], Arcs)
-
-	return buf
-}
-
-// PolyFillRectangleCookie is a cookie used only for PolyFillRectangle requests.
-type PolyFillRectangleCookie struct {
-	*xgb.Cookie
-}
-
-// PolyFillRectangle sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func PolyFillRectangle(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) PolyFillRectangleCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(polyFillRectangleRequest(c, Drawable, Gc, Rectangles), cookie)
-	return PolyFillRectangleCookie{cookie}
-}
-
-// PolyFillRectangleChecked sends a checked request.
-// If an error occurs, it can be retrieved using PolyFillRectangleCookie.Check()
-func PolyFillRectangleChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) PolyFillRectangleCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(polyFillRectangleRequest(c, Drawable, Gc, Rectangles), cookie)
-	return PolyFillRectangleCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook PolyFillRectangleCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for PolyFillRectangle
-// polyFillRectangleRequest writes a PolyFillRectangle request to a byte slice.
-func polyFillRectangleRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) []byte {
-	size := xgb.Pad((12 + xgb.Pad((len(Rectangles) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 70 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	b += RectangleListBytes(buf[b:], Rectangles)
-
-	return buf
-}
-
-// PolyLineCookie is a cookie used only for PolyLine requests.
-type PolyLineCookie struct {
-	*xgb.Cookie
-}
-
-// PolyLine sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func PolyLine(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) PolyLineCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(polyLineRequest(c, CoordinateMode, Drawable, Gc, Points), cookie)
-	return PolyLineCookie{cookie}
-}
-
-// PolyLineChecked sends a checked request.
-// If an error occurs, it can be retrieved using PolyLineCookie.Check()
-func PolyLineChecked(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) PolyLineCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(polyLineRequest(c, CoordinateMode, Drawable, Gc, Points), cookie)
-	return PolyLineCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook PolyLineCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for PolyLine
-// polyLineRequest writes a PolyLine request to a byte slice.
-func polyLineRequest(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) []byte {
-	size := xgb.Pad((12 + xgb.Pad((len(Points) * 4))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 65 // request opcode
-	b += 1
-
-	buf[b] = CoordinateMode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	b += PointListBytes(buf[b:], Points)
-
-	return buf
-}
-
-// PolyPointCookie is a cookie used only for PolyPoint requests.
-type PolyPointCookie struct {
-	*xgb.Cookie
-}
-
-// PolyPoint sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func PolyPoint(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) PolyPointCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(polyPointRequest(c, CoordinateMode, Drawable, Gc, Points), cookie)
-	return PolyPointCookie{cookie}
-}
-
-// PolyPointChecked sends a checked request.
-// If an error occurs, it can be retrieved using PolyPointCookie.Check()
-func PolyPointChecked(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) PolyPointCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(polyPointRequest(c, CoordinateMode, Drawable, Gc, Points), cookie)
-	return PolyPointCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook PolyPointCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for PolyPoint
-// polyPointRequest writes a PolyPoint request to a byte slice.
-func polyPointRequest(c *xgb.Conn, CoordinateMode byte, Drawable Drawable, Gc Gcontext, Points []Point) []byte {
-	size := xgb.Pad((12 + xgb.Pad((len(Points) * 4))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 64 // request opcode
-	b += 1
-
-	buf[b] = CoordinateMode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	b += PointListBytes(buf[b:], Points)
-
-	return buf
-}
-
-// PolyRectangleCookie is a cookie used only for PolyRectangle requests.
-type PolyRectangleCookie struct {
-	*xgb.Cookie
-}
-
-// PolyRectangle sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func PolyRectangle(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) PolyRectangleCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(polyRectangleRequest(c, Drawable, Gc, Rectangles), cookie)
-	return PolyRectangleCookie{cookie}
-}
-
-// PolyRectangleChecked sends a checked request.
-// If an error occurs, it can be retrieved using PolyRectangleCookie.Check()
-func PolyRectangleChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) PolyRectangleCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(polyRectangleRequest(c, Drawable, Gc, Rectangles), cookie)
-	return PolyRectangleCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook PolyRectangleCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for PolyRectangle
-// polyRectangleRequest writes a PolyRectangle request to a byte slice.
-func polyRectangleRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Rectangles []Rectangle) []byte {
-	size := xgb.Pad((12 + xgb.Pad((len(Rectangles) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 67 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	b += RectangleListBytes(buf[b:], Rectangles)
-
-	return buf
-}
-
-// PolySegmentCookie is a cookie used only for PolySegment requests.
-type PolySegmentCookie struct {
-	*xgb.Cookie
-}
-
-// PolySegment sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func PolySegment(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Segments []Segment) PolySegmentCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(polySegmentRequest(c, Drawable, Gc, Segments), cookie)
-	return PolySegmentCookie{cookie}
-}
-
-// PolySegmentChecked sends a checked request.
-// If an error occurs, it can be retrieved using PolySegmentCookie.Check()
-func PolySegmentChecked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Segments []Segment) PolySegmentCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(polySegmentRequest(c, Drawable, Gc, Segments), cookie)
-	return PolySegmentCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook PolySegmentCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for PolySegment
-// polySegmentRequest writes a PolySegment request to a byte slice.
-func polySegmentRequest(c *xgb.Conn, Drawable Drawable, Gc Gcontext, Segments []Segment) []byte {
-	size := xgb.Pad((12 + xgb.Pad((len(Segments) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 66 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	b += SegmentListBytes(buf[b:], Segments)
-
-	return buf
-}
-
-// PolyText16Cookie is a cookie used only for PolyText16 requests.
-type PolyText16Cookie struct {
-	*xgb.Cookie
-}
-
-// PolyText16 sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func PolyText16(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) PolyText16Cookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(polyText16Request(c, Drawable, Gc, X, Y, Items), cookie)
-	return PolyText16Cookie{cookie}
-}
-
-// PolyText16Checked sends a checked request.
-// If an error occurs, it can be retrieved using PolyText16Cookie.Check()
-func PolyText16Checked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) PolyText16Cookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(polyText16Request(c, Drawable, Gc, X, Y, Items), cookie)
-	return PolyText16Cookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook PolyText16Cookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for PolyText16
-// polyText16Request writes a PolyText16 request to a byte slice.
-func polyText16Request(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) []byte {
-	size := xgb.Pad((16 + xgb.Pad((len(Items) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 75 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Y))
-	b += 2
-
-	copy(buf[b:], Items[:len(Items)])
-	b += int(len(Items))
-
-	return buf
-}
-
-// PolyText8Cookie is a cookie used only for PolyText8 requests.
-type PolyText8Cookie struct {
-	*xgb.Cookie
-}
-
-// PolyText8 sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func PolyText8(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) PolyText8Cookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(polyText8Request(c, Drawable, Gc, X, Y, Items), cookie)
-	return PolyText8Cookie{cookie}
-}
-
-// PolyText8Checked sends a checked request.
-// If an error occurs, it can be retrieved using PolyText8Cookie.Check()
-func PolyText8Checked(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) PolyText8Cookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(polyText8Request(c, Drawable, Gc, X, Y, Items), cookie)
-	return PolyText8Cookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook PolyText8Cookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for PolyText8
-// polyText8Request writes a PolyText8 request to a byte slice.
-func polyText8Request(c *xgb.Conn, Drawable Drawable, Gc Gcontext, X int16, Y int16, Items []byte) []byte {
-	size := xgb.Pad((16 + xgb.Pad((len(Items) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 74 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Y))
-	b += 2
-
-	copy(buf[b:], Items[:len(Items)])
-	b += int(len(Items))
-
-	return buf
-}
-
-// PutImageCookie is a cookie used only for PutImage requests.
-type PutImageCookie struct {
-	*xgb.Cookie
-}
-
-// PutImage sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func PutImage(c *xgb.Conn, Format byte, Drawable Drawable, Gc Gcontext, Width uint16, Height uint16, DstX int16, DstY int16, LeftPad byte, Depth byte, Data []byte) PutImageCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(putImageRequest(c, Format, Drawable, Gc, Width, Height, DstX, DstY, LeftPad, Depth, Data), cookie)
-	return PutImageCookie{cookie}
-}
-
-// PutImageChecked sends a checked request.
-// If an error occurs, it can be retrieved using PutImageCookie.Check()
-func PutImageChecked(c *xgb.Conn, Format byte, Drawable Drawable, Gc Gcontext, Width uint16, Height uint16, DstX int16, DstY int16, LeftPad byte, Depth byte, Data []byte) PutImageCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(putImageRequest(c, Format, Drawable, Gc, Width, Height, DstX, DstY, LeftPad, Depth, Data), cookie)
-	return PutImageCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook PutImageCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for PutImage
-// putImageRequest writes a PutImage request to a byte slice.
-func putImageRequest(c *xgb.Conn, Format byte, Drawable Drawable, Gc Gcontext, Width uint16, Height uint16, DstX int16, DstY int16, LeftPad byte, Depth byte, Data []byte) []byte {
-	size := xgb.Pad((24 + xgb.Pad((len(Data) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 72 // request opcode
-	b += 1
-
-	buf[b] = Format
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	xgb.Put16(buf[b:], Width)
-	b += 2
-
-	xgb.Put16(buf[b:], Height)
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstY))
-	b += 2
-
-	buf[b] = LeftPad
-	b += 1
-
-	buf[b] = Depth
-	b += 1
-
-	b += 2 // padding
-
-	copy(buf[b:], Data[:len(Data)])
-	b += int(len(Data))
-
-	return buf
-}
-
-// QueryBestSizeCookie is a cookie used only for QueryBestSize requests.
-type QueryBestSizeCookie struct {
-	*xgb.Cookie
-}
-
-// QueryBestSize sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryBestSizeCookie.Reply()
-func QueryBestSize(c *xgb.Conn, Class byte, Drawable Drawable, Width uint16, Height uint16) QueryBestSizeCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryBestSizeRequest(c, Class, Drawable, Width, Height), cookie)
-	return QueryBestSizeCookie{cookie}
-}
-
-// QueryBestSizeUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryBestSizeUnchecked(c *xgb.Conn, Class byte, Drawable Drawable, Width uint16, Height uint16) QueryBestSizeCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryBestSizeRequest(c, Class, Drawable, Width, Height), cookie)
-	return QueryBestSizeCookie{cookie}
-}
-
-// QueryBestSizeReply represents the data returned from a QueryBestSize request.
-type QueryBestSizeReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	Width  uint16
-	Height uint16
-}
-
-// Reply blocks and returns the reply data for a QueryBestSize request.
-func (cook QueryBestSizeCookie) Reply() (*QueryBestSizeReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryBestSizeReply(buf), nil
-}
-
-// queryBestSizeReply reads a byte slice into a QueryBestSizeReply value.
-func queryBestSizeReply(buf []byte) *QueryBestSizeReply {
-	v := new(QueryBestSizeReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Width = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Height = xgb.Get16(buf[b:])
-	b += 2
-
-	return v
-}
-
-// Write request to wire for QueryBestSize
-// queryBestSizeRequest writes a QueryBestSize request to a byte slice.
-func queryBestSizeRequest(c *xgb.Conn, Class byte, Drawable Drawable, Width uint16, Height uint16) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 97 // request opcode
-	b += 1
-
-	buf[b] = Class
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Drawable))
-	b += 4
-
-	xgb.Put16(buf[b:], Width)
-	b += 2
-
-	xgb.Put16(buf[b:], Height)
-	b += 2
-
-	return buf
-}
-
-// QueryColorsCookie is a cookie used only for QueryColors requests.
-type QueryColorsCookie struct {
-	*xgb.Cookie
-}
-
-// QueryColors sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryColorsCookie.Reply()
-func QueryColors(c *xgb.Conn, Cmap Colormap, Pixels []uint32) QueryColorsCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryColorsRequest(c, Cmap, Pixels), cookie)
-	return QueryColorsCookie{cookie}
-}
-
-// QueryColorsUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryColorsUnchecked(c *xgb.Conn, Cmap Colormap, Pixels []uint32) QueryColorsCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryColorsRequest(c, Cmap, Pixels), cookie)
-	return QueryColorsCookie{cookie}
-}
-
-// QueryColorsReply represents the data returned from a QueryColors request.
-type QueryColorsReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	ColorsLen uint16
-	// padding: 22 bytes
-	Colors []Rgb // size: xgb.Pad((int(ColorsLen) * 8))
-}
-
-// Reply blocks and returns the reply data for a QueryColors request.
-func (cook QueryColorsCookie) Reply() (*QueryColorsReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryColorsReply(buf), nil
-}
-
-// queryColorsReply reads a byte slice into a QueryColorsReply value.
-func queryColorsReply(buf []byte) *QueryColorsReply {
-	v := new(QueryColorsReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.ColorsLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 22 // padding
-
-	v.Colors = make([]Rgb, v.ColorsLen)
-	b += RgbReadList(buf[b:], v.Colors)
-
-	return v
-}
-
-// Write request to wire for QueryColors
-// queryColorsRequest writes a QueryColors request to a byte slice.
-func queryColorsRequest(c *xgb.Conn, Cmap Colormap, Pixels []uint32) []byte {
-	size := xgb.Pad((8 + xgb.Pad((len(Pixels) * 4))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 91 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	for i := 0; i < int(len(Pixels)); i++ {
-		xgb.Put32(buf[b:], Pixels[i])
-		b += 4
-	}
-
-	return buf
-}
-
-// QueryExtensionCookie is a cookie used only for QueryExtension requests.
-type QueryExtensionCookie struct {
-	*xgb.Cookie
-}
-
-// QueryExtension sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryExtensionCookie.Reply()
-func QueryExtension(c *xgb.Conn, NameLen uint16, Name string) QueryExtensionCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryExtensionRequest(c, NameLen, Name), cookie)
-	return QueryExtensionCookie{cookie}
-}
-
-// QueryExtensionUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryExtensionUnchecked(c *xgb.Conn, NameLen uint16, Name string) QueryExtensionCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryExtensionRequest(c, NameLen, Name), cookie)
-	return QueryExtensionCookie{cookie}
-}
-
-// QueryExtensionReply represents the data returned from a QueryExtension request.
-type QueryExtensionReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	Present     bool
-	MajorOpcode byte
-	FirstEvent  byte
-	FirstError  byte
-}
-
-// Reply blocks and returns the reply data for a QueryExtension request.
-func (cook QueryExtensionCookie) Reply() (*QueryExtensionReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryExtensionReply(buf), nil
-}
-
-// queryExtensionReply reads a byte slice into a QueryExtensionReply value.
-func queryExtensionReply(buf []byte) *QueryExtensionReply {
-	v := new(QueryExtensionReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	if buf[b] == 1 {
-		v.Present = true
-	} else {
-		v.Present = false
-	}
-	b += 1
-
-	v.MajorOpcode = buf[b]
-	b += 1
-
-	v.FirstEvent = buf[b]
-	b += 1
-
-	v.FirstError = buf[b]
-	b += 1
-
-	return v
-}
-
-// Write request to wire for QueryExtension
-// queryExtensionRequest writes a QueryExtension request to a byte slice.
-func queryExtensionRequest(c *xgb.Conn, NameLen uint16, Name string) []byte {
-	size := xgb.Pad((8 + xgb.Pad((int(NameLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 98 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put16(buf[b:], NameLen)
-	b += 2
-
-	b += 2 // padding
-
-	copy(buf[b:], Name[:NameLen])
-	b += int(NameLen)
-
-	return buf
-}
-
-// QueryFontCookie is a cookie used only for QueryFont requests.
-type QueryFontCookie struct {
-	*xgb.Cookie
-}
-
-// QueryFont sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryFontCookie.Reply()
-func QueryFont(c *xgb.Conn, Font Fontable) QueryFontCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryFontRequest(c, Font), cookie)
-	return QueryFontCookie{cookie}
-}
-
-// QueryFontUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryFontUnchecked(c *xgb.Conn, Font Fontable) QueryFontCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryFontRequest(c, Font), cookie)
-	return QueryFontCookie{cookie}
-}
-
-// QueryFontReply represents the data returned from a QueryFont request.
-type QueryFontReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	MinBounds Charinfo
-	// padding: 4 bytes
-	MaxBounds Charinfo
-	// padding: 4 bytes
-	MinCharOrByte2 uint16
-	MaxCharOrByte2 uint16
-	DefaultChar    uint16
-	PropertiesLen  uint16
-	DrawDirection  byte
-	MinByte1       byte
-	MaxByte1       byte
-	AllCharsExist  bool
-	FontAscent     int16
-	FontDescent    int16
-	CharInfosLen   uint32
-	Properties     []Fontprop // size: xgb.Pad((int(PropertiesLen) * 8))
-	// alignment gap to multiple of 4
-	CharInfos []Charinfo // size: xgb.Pad((int(CharInfosLen) * 12))
-}
-
-// Reply blocks and returns the reply data for a QueryFont request.
-func (cook QueryFontCookie) Reply() (*QueryFontReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryFontReply(buf), nil
-}
-
-// queryFontReply reads a byte slice into a QueryFontReply value.
-func queryFontReply(buf []byte) *QueryFontReply {
-	v := new(QueryFontReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.MinBounds = Charinfo{}
-	b += CharinfoRead(buf[b:], &v.MinBounds)
-
-	b += 4 // padding
-
-	v.MaxBounds = Charinfo{}
-	b += CharinfoRead(buf[b:], &v.MaxBounds)
-
-	b += 4 // padding
-
-	v.MinCharOrByte2 = xgb.Get16(buf[b:])
-	b += 2
-
-	v.MaxCharOrByte2 = xgb.Get16(buf[b:])
-	b += 2
-
-	v.DefaultChar = xgb.Get16(buf[b:])
-	b += 2
-
-	v.PropertiesLen = xgb.Get16(buf[b:])
-	b += 2
-
-	v.DrawDirection = buf[b]
-	b += 1
-
-	v.MinByte1 = buf[b]
-	b += 1
-
-	v.MaxByte1 = buf[b]
-	b += 1
-
-	if buf[b] == 1 {
-		v.AllCharsExist = true
-	} else {
-		v.AllCharsExist = false
-	}
-	b += 1
-
-	v.FontAscent = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.FontDescent = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.CharInfosLen = xgb.Get32(buf[b:])
-	b += 4
-
-	v.Properties = make([]Fontprop, v.PropertiesLen)
-	b += FontpropReadList(buf[b:], v.Properties)
-
-	b = (b + 3) & ^3 // alignment gap
-
-	v.CharInfos = make([]Charinfo, v.CharInfosLen)
-	b += CharinfoReadList(buf[b:], v.CharInfos)
-
-	return v
-}
-
-// Write request to wire for QueryFont
-// queryFontRequest writes a QueryFont request to a byte slice.
-func queryFontRequest(c *xgb.Conn, Font Fontable) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 47 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Font))
-	b += 4
-
-	return buf
-}
-
-// QueryKeymapCookie is a cookie used only for QueryKeymap requests.
-type QueryKeymapCookie struct {
-	*xgb.Cookie
-}
-
-// QueryKeymap sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryKeymapCookie.Reply()
-func QueryKeymap(c *xgb.Conn) QueryKeymapCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryKeymapRequest(c), cookie)
-	return QueryKeymapCookie{cookie}
-}
-
-// QueryKeymapUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryKeymapUnchecked(c *xgb.Conn) QueryKeymapCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryKeymapRequest(c), cookie)
-	return QueryKeymapCookie{cookie}
-}
-
-// QueryKeymapReply represents the data returned from a QueryKeymap request.
-type QueryKeymapReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	Keys []byte // size: 32
-}
-
-// Reply blocks and returns the reply data for a QueryKeymap request.
-func (cook QueryKeymapCookie) Reply() (*QueryKeymapReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryKeymapReply(buf), nil
-}
-
-// queryKeymapReply reads a byte slice into a QueryKeymapReply value.
-func queryKeymapReply(buf []byte) *QueryKeymapReply {
-	v := new(QueryKeymapReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Keys = make([]byte, 32)
-	copy(v.Keys[:32], buf[b:])
-	b += int(32)
-
-	return v
-}
-
-// Write request to wire for QueryKeymap
-// queryKeymapRequest writes a QueryKeymap request to a byte slice.
-func queryKeymapRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 44 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// QueryPointerCookie is a cookie used only for QueryPointer requests.
-type QueryPointerCookie struct {
-	*xgb.Cookie
-}
-
-// QueryPointer sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryPointerCookie.Reply()
-func QueryPointer(c *xgb.Conn, Window Window) QueryPointerCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryPointerRequest(c, Window), cookie)
-	return QueryPointerCookie{cookie}
-}
-
-// QueryPointerUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryPointerUnchecked(c *xgb.Conn, Window Window) QueryPointerCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryPointerRequest(c, Window), cookie)
-	return QueryPointerCookie{cookie}
-}
-
-// QueryPointerReply represents the data returned from a QueryPointer request.
-type QueryPointerReply struct {
-	Sequence   uint16 // sequence number of the request for this reply
-	Length     uint32 // number of bytes in this reply
-	SameScreen bool
-	Root       Window
-	Child      Window
-	RootX      int16
-	RootY      int16
-	WinX       int16
-	WinY       int16
-	Mask       uint16
-	// padding: 2 bytes
-}
-
-// Reply blocks and returns the reply data for a QueryPointer request.
-func (cook QueryPointerCookie) Reply() (*QueryPointerReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryPointerReply(buf), nil
-}
-
-// queryPointerReply reads a byte slice into a QueryPointerReply value.
-func queryPointerReply(buf []byte) *QueryPointerReply {
-	v := new(QueryPointerReply)
-	b := 1 // skip reply determinant
-
-	if buf[b] == 1 {
-		v.SameScreen = true
-	} else {
-		v.SameScreen = false
-	}
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Root = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Child = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.RootX = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.RootY = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.WinX = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.WinY = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.Mask = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 2 // padding
-
-	return v
-}
-
-// Write request to wire for QueryPointer
-// queryPointerRequest writes a QueryPointer request to a byte slice.
-func queryPointerRequest(c *xgb.Conn, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 38 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// QueryTextExtentsCookie is a cookie used only for QueryTextExtents requests.
-type QueryTextExtentsCookie struct {
-	*xgb.Cookie
-}
-
-// QueryTextExtents sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryTextExtentsCookie.Reply()
-func QueryTextExtents(c *xgb.Conn, Font Fontable, String []Char2b, StringLen uint16) QueryTextExtentsCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryTextExtentsRequest(c, Font, String, StringLen), cookie)
-	return QueryTextExtentsCookie{cookie}
-}
-
-// QueryTextExtentsUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryTextExtentsUnchecked(c *xgb.Conn, Font Fontable, String []Char2b, StringLen uint16) QueryTextExtentsCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryTextExtentsRequest(c, Font, String, StringLen), cookie)
-	return QueryTextExtentsCookie{cookie}
-}
-
-// QueryTextExtentsReply represents the data returned from a QueryTextExtents request.
-type QueryTextExtentsReply struct {
-	Sequence       uint16 // sequence number of the request for this reply
-	Length         uint32 // number of bytes in this reply
-	DrawDirection  byte
-	FontAscent     int16
-	FontDescent    int16
-	OverallAscent  int16
-	OverallDescent int16
-	OverallWidth   int32
-	OverallLeft    int32
-	OverallRight   int32
-}
-
-// Reply blocks and returns the reply data for a QueryTextExtents request.
-func (cook QueryTextExtentsCookie) Reply() (*QueryTextExtentsReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryTextExtentsReply(buf), nil
-}
-
-// queryTextExtentsReply reads a byte slice into a QueryTextExtentsReply value.
-func queryTextExtentsReply(buf []byte) *QueryTextExtentsReply {
-	v := new(QueryTextExtentsReply)
-	b := 1 // skip reply determinant
-
-	v.DrawDirection = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.FontAscent = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.FontDescent = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.OverallAscent = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.OverallDescent = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.OverallWidth = int32(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.OverallLeft = int32(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.OverallRight = int32(xgb.Get32(buf[b:]))
-	b += 4
-
-	return v
-}
-
-// Write request to wire for QueryTextExtents
-// queryTextExtentsRequest writes a QueryTextExtents request to a byte slice.
-func queryTextExtentsRequest(c *xgb.Conn, Font Fontable, String []Char2b, StringLen uint16) []byte {
-	size := xgb.Pad((8 + xgb.Pad((len(String) * 2))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 48 // request opcode
-	b += 1
-
-	buf[b] = byte((int(StringLen) & 1))
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Font))
-	b += 4
-
-	b += Char2bListBytes(buf[b:], String)
-
-	// skip writing local field: StringLen (2) :: uint16
-
-	return buf
-}
-
-// QueryTreeCookie is a cookie used only for QueryTree requests.
-type QueryTreeCookie struct {
-	*xgb.Cookie
-}
-
-// QueryTree sends a checked request.
-// If an error occurs, it will be returned with the reply by calling QueryTreeCookie.Reply()
-func QueryTree(c *xgb.Conn, Window Window) QueryTreeCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(queryTreeRequest(c, Window), cookie)
-	return QueryTreeCookie{cookie}
-}
-
-// QueryTreeUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func QueryTreeUnchecked(c *xgb.Conn, Window Window) QueryTreeCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(queryTreeRequest(c, Window), cookie)
-	return QueryTreeCookie{cookie}
-}
-
-// QueryTreeReply represents the data returned from a QueryTree request.
-type QueryTreeReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	// padding: 1 bytes
-	Root        Window
-	Parent      Window
-	ChildrenLen uint16
-	// padding: 14 bytes
-	Children []Window // size: xgb.Pad((int(ChildrenLen) * 4))
-}
-
-// Reply blocks and returns the reply data for a QueryTree request.
-func (cook QueryTreeCookie) Reply() (*QueryTreeReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return queryTreeReply(buf), nil
-}
-
-// queryTreeReply reads a byte slice into a QueryTreeReply value.
-func queryTreeReply(buf []byte) *QueryTreeReply {
-	v := new(QueryTreeReply)
-	b := 1 // skip reply determinant
-
-	b += 1 // padding
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Root = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.Parent = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.ChildrenLen = xgb.Get16(buf[b:])
-	b += 2
-
-	b += 14 // padding
-
-	v.Children = make([]Window, v.ChildrenLen)
-	for i := 0; i < int(v.ChildrenLen); i++ {
-		v.Children[i] = Window(xgb.Get32(buf[b:]))
-		b += 4
-	}
-
-	return v
-}
-
-// Write request to wire for QueryTree
-// queryTreeRequest writes a QueryTree request to a byte slice.
-func queryTreeRequest(c *xgb.Conn, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 15 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// RecolorCursorCookie is a cookie used only for RecolorCursor requests.
-type RecolorCursorCookie struct {
-	*xgb.Cookie
-}
-
-// RecolorCursor sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func RecolorCursor(c *xgb.Conn, Cursor Cursor, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) RecolorCursorCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(recolorCursorRequest(c, Cursor, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue), cookie)
-	return RecolorCursorCookie{cookie}
-}
-
-// RecolorCursorChecked sends a checked request.
-// If an error occurs, it can be retrieved using RecolorCursorCookie.Check()
-func RecolorCursorChecked(c *xgb.Conn, Cursor Cursor, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) RecolorCursorCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(recolorCursorRequest(c, Cursor, ForeRed, ForeGreen, ForeBlue, BackRed, BackGreen, BackBlue), cookie)
-	return RecolorCursorCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook RecolorCursorCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for RecolorCursor
-// recolorCursorRequest writes a RecolorCursor request to a byte slice.
-func recolorCursorRequest(c *xgb.Conn, Cursor Cursor, ForeRed uint16, ForeGreen uint16, ForeBlue uint16, BackRed uint16, BackGreen uint16, BackBlue uint16) []byte {
-	size := 20
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 96 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cursor))
-	b += 4
-
-	xgb.Put16(buf[b:], ForeRed)
-	b += 2
-
-	xgb.Put16(buf[b:], ForeGreen)
-	b += 2
-
-	xgb.Put16(buf[b:], ForeBlue)
-	b += 2
-
-	xgb.Put16(buf[b:], BackRed)
-	b += 2
-
-	xgb.Put16(buf[b:], BackGreen)
-	b += 2
-
-	xgb.Put16(buf[b:], BackBlue)
-	b += 2
-
-	return buf
-}
-
-// ReparentWindowCookie is a cookie used only for ReparentWindow requests.
-type ReparentWindowCookie struct {
-	*xgb.Cookie
-}
-
-// ReparentWindow sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func ReparentWindow(c *xgb.Conn, Window Window, Parent Window, X int16, Y int16) ReparentWindowCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(reparentWindowRequest(c, Window, Parent, X, Y), cookie)
-	return ReparentWindowCookie{cookie}
-}
-
-// ReparentWindowChecked sends a checked request.
-// If an error occurs, it can be retrieved using ReparentWindowCookie.Check()
-func ReparentWindowChecked(c *xgb.Conn, Window Window, Parent Window, X int16, Y int16) ReparentWindowCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(reparentWindowRequest(c, Window, Parent, X, Y), cookie)
-	return ReparentWindowCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook ReparentWindowCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for ReparentWindow
-// reparentWindowRequest writes a ReparentWindow request to a byte slice.
-func reparentWindowRequest(c *xgb.Conn, Window Window, Parent Window, X int16, Y int16) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 7 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Parent))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(X))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Y))
-	b += 2
-
-	return buf
-}
-
-// RotatePropertiesCookie is a cookie used only for RotateProperties requests.
-type RotatePropertiesCookie struct {
-	*xgb.Cookie
-}
-
-// RotateProperties sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func RotateProperties(c *xgb.Conn, Window Window, AtomsLen uint16, Delta int16, Atoms []Atom) RotatePropertiesCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(rotatePropertiesRequest(c, Window, AtomsLen, Delta, Atoms), cookie)
-	return RotatePropertiesCookie{cookie}
-}
-
-// RotatePropertiesChecked sends a checked request.
-// If an error occurs, it can be retrieved using RotatePropertiesCookie.Check()
-func RotatePropertiesChecked(c *xgb.Conn, Window Window, AtomsLen uint16, Delta int16, Atoms []Atom) RotatePropertiesCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(rotatePropertiesRequest(c, Window, AtomsLen, Delta, Atoms), cookie)
-	return RotatePropertiesCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook RotatePropertiesCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for RotateProperties
-// rotatePropertiesRequest writes a RotateProperties request to a byte slice.
-func rotatePropertiesRequest(c *xgb.Conn, Window Window, AtomsLen uint16, Delta int16, Atoms []Atom) []byte {
-	size := xgb.Pad((12 + xgb.Pad((int(AtomsLen) * 4))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 114 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	xgb.Put16(buf[b:], AtomsLen)
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Delta))
-	b += 2
-
-	for i := 0; i < int(AtomsLen); i++ {
-		xgb.Put32(buf[b:], uint32(Atoms[i]))
-		b += 4
-	}
-
-	return buf
-}
-
-// SendEventCookie is a cookie used only for SendEvent requests.
-type SendEventCookie struct {
-	*xgb.Cookie
-}
-
-// SendEvent sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SendEvent(c *xgb.Conn, Propagate bool, Destination Window, EventMask uint32, Event string) SendEventCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(sendEventRequest(c, Propagate, Destination, EventMask, Event), cookie)
-	return SendEventCookie{cookie}
-}
-
-// SendEventChecked sends a checked request.
-// If an error occurs, it can be retrieved using SendEventCookie.Check()
-func SendEventChecked(c *xgb.Conn, Propagate bool, Destination Window, EventMask uint32, Event string) SendEventCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(sendEventRequest(c, Propagate, Destination, EventMask, Event), cookie)
-	return SendEventCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SendEventCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SendEvent
-// sendEventRequest writes a SendEvent request to a byte slice.
-func sendEventRequest(c *xgb.Conn, Propagate bool, Destination Window, EventMask uint32, Event string) []byte {
-	size := 44
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 25 // request opcode
-	b += 1
-
-	if Propagate {
-		buf[b] = 1
-	} else {
-		buf[b] = 0
-	}
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Destination))
-	b += 4
-
-	xgb.Put32(buf[b:], EventMask)
-	b += 4
-
-	copy(buf[b:], Event[:32])
-	b += int(32)
-
-	return buf
-}
-
-// SetAccessControlCookie is a cookie used only for SetAccessControl requests.
-type SetAccessControlCookie struct {
-	*xgb.Cookie
-}
-
-// SetAccessControl sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetAccessControl(c *xgb.Conn, Mode byte) SetAccessControlCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(setAccessControlRequest(c, Mode), cookie)
-	return SetAccessControlCookie{cookie}
-}
-
-// SetAccessControlChecked sends a checked request.
-// If an error occurs, it can be retrieved using SetAccessControlCookie.Check()
-func SetAccessControlChecked(c *xgb.Conn, Mode byte) SetAccessControlCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(setAccessControlRequest(c, Mode), cookie)
-	return SetAccessControlCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SetAccessControlCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SetAccessControl
-// setAccessControlRequest writes a SetAccessControl request to a byte slice.
-func setAccessControlRequest(c *xgb.Conn, Mode byte) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 111 // request opcode
-	b += 1
-
-	buf[b] = Mode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// SetClipRectanglesCookie is a cookie used only for SetClipRectangles requests.
-type SetClipRectanglesCookie struct {
-	*xgb.Cookie
-}
-
-// SetClipRectangles sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetClipRectangles(c *xgb.Conn, Ordering byte, Gc Gcontext, ClipXOrigin int16, ClipYOrigin int16, Rectangles []Rectangle) SetClipRectanglesCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(setClipRectanglesRequest(c, Ordering, Gc, ClipXOrigin, ClipYOrigin, Rectangles), cookie)
-	return SetClipRectanglesCookie{cookie}
-}
-
-// SetClipRectanglesChecked sends a checked request.
-// If an error occurs, it can be retrieved using SetClipRectanglesCookie.Check()
-func SetClipRectanglesChecked(c *xgb.Conn, Ordering byte, Gc Gcontext, ClipXOrigin int16, ClipYOrigin int16, Rectangles []Rectangle) SetClipRectanglesCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(setClipRectanglesRequest(c, Ordering, Gc, ClipXOrigin, ClipYOrigin, Rectangles), cookie)
-	return SetClipRectanglesCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SetClipRectanglesCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SetClipRectangles
-// setClipRectanglesRequest writes a SetClipRectangles request to a byte slice.
-func setClipRectanglesRequest(c *xgb.Conn, Ordering byte, Gc Gcontext, ClipXOrigin int16, ClipYOrigin int16, Rectangles []Rectangle) []byte {
-	size := xgb.Pad((12 + xgb.Pad((len(Rectangles) * 8))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 59 // request opcode
-	b += 1
-
-	buf[b] = Ordering
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(ClipXOrigin))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(ClipYOrigin))
-	b += 2
-
-	b += RectangleListBytes(buf[b:], Rectangles)
-
-	return buf
-}
-
-// SetCloseDownModeCookie is a cookie used only for SetCloseDownMode requests.
-type SetCloseDownModeCookie struct {
-	*xgb.Cookie
-}
-
-// SetCloseDownMode sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetCloseDownMode(c *xgb.Conn, Mode byte) SetCloseDownModeCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(setCloseDownModeRequest(c, Mode), cookie)
-	return SetCloseDownModeCookie{cookie}
-}
-
-// SetCloseDownModeChecked sends a checked request.
-// If an error occurs, it can be retrieved using SetCloseDownModeCookie.Check()
-func SetCloseDownModeChecked(c *xgb.Conn, Mode byte) SetCloseDownModeCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(setCloseDownModeRequest(c, Mode), cookie)
-	return SetCloseDownModeCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SetCloseDownModeCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SetCloseDownMode
-// setCloseDownModeRequest writes a SetCloseDownMode request to a byte slice.
-func setCloseDownModeRequest(c *xgb.Conn, Mode byte) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 112 // request opcode
-	b += 1
-
-	buf[b] = Mode
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// SetDashesCookie is a cookie used only for SetDashes requests.
-type SetDashesCookie struct {
-	*xgb.Cookie
-}
-
-// SetDashes sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetDashes(c *xgb.Conn, Gc Gcontext, DashOffset uint16, DashesLen uint16, Dashes []byte) SetDashesCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(setDashesRequest(c, Gc, DashOffset, DashesLen, Dashes), cookie)
-	return SetDashesCookie{cookie}
-}
-
-// SetDashesChecked sends a checked request.
-// If an error occurs, it can be retrieved using SetDashesCookie.Check()
-func SetDashesChecked(c *xgb.Conn, Gc Gcontext, DashOffset uint16, DashesLen uint16, Dashes []byte) SetDashesCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(setDashesRequest(c, Gc, DashOffset, DashesLen, Dashes), cookie)
-	return SetDashesCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SetDashesCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SetDashes
-// setDashesRequest writes a SetDashes request to a byte slice.
-func setDashesRequest(c *xgb.Conn, Gc Gcontext, DashOffset uint16, DashesLen uint16, Dashes []byte) []byte {
-	size := xgb.Pad((12 + xgb.Pad((int(DashesLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 58 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Gc))
-	b += 4
-
-	xgb.Put16(buf[b:], DashOffset)
-	b += 2
-
-	xgb.Put16(buf[b:], DashesLen)
-	b += 2
-
-	copy(buf[b:], Dashes[:DashesLen])
-	b += int(DashesLen)
-
-	return buf
-}
-
-// SetFontPathCookie is a cookie used only for SetFontPath requests.
-type SetFontPathCookie struct {
-	*xgb.Cookie
-}
-
-// SetFontPath sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetFontPath(c *xgb.Conn, FontQty uint16, Font []Str) SetFontPathCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(setFontPathRequest(c, FontQty, Font), cookie)
-	return SetFontPathCookie{cookie}
-}
-
-// SetFontPathChecked sends a checked request.
-// If an error occurs, it can be retrieved using SetFontPathCookie.Check()
-func SetFontPathChecked(c *xgb.Conn, FontQty uint16, Font []Str) SetFontPathCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(setFontPathRequest(c, FontQty, Font), cookie)
-	return SetFontPathCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SetFontPathCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SetFontPath
-// setFontPathRequest writes a SetFontPath request to a byte slice.
-func setFontPathRequest(c *xgb.Conn, FontQty uint16, Font []Str) []byte {
-	size := xgb.Pad((8 + StrListSize(Font)))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 51 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put16(buf[b:], FontQty)
-	b += 2
-
-	b += 2 // padding
-
-	b += StrListBytes(buf[b:], Font)
-
-	return buf
-}
-
-// SetInputFocusCookie is a cookie used only for SetInputFocus requests.
-type SetInputFocusCookie struct {
-	*xgb.Cookie
-}
-
-// SetInputFocus sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetInputFocus(c *xgb.Conn, RevertTo byte, Focus Window, Time Timestamp) SetInputFocusCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(setInputFocusRequest(c, RevertTo, Focus, Time), cookie)
-	return SetInputFocusCookie{cookie}
-}
-
-// SetInputFocusChecked sends a checked request.
-// If an error occurs, it can be retrieved using SetInputFocusCookie.Check()
-func SetInputFocusChecked(c *xgb.Conn, RevertTo byte, Focus Window, Time Timestamp) SetInputFocusCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(setInputFocusRequest(c, RevertTo, Focus, Time), cookie)
-	return SetInputFocusCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SetInputFocusCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SetInputFocus
-// setInputFocusRequest writes a SetInputFocus request to a byte slice.
-func setInputFocusRequest(c *xgb.Conn, RevertTo byte, Focus Window, Time Timestamp) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 42 // request opcode
-	b += 1
-
-	buf[b] = RevertTo
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Focus))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Time))
-	b += 4
-
-	return buf
-}
-
-// SetModifierMappingCookie is a cookie used only for SetModifierMapping requests.
-type SetModifierMappingCookie struct {
-	*xgb.Cookie
-}
-
-// SetModifierMapping sends a checked request.
-// If an error occurs, it will be returned with the reply by calling SetModifierMappingCookie.Reply()
-func SetModifierMapping(c *xgb.Conn, KeycodesPerModifier byte, Keycodes []Keycode) SetModifierMappingCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(setModifierMappingRequest(c, KeycodesPerModifier, Keycodes), cookie)
-	return SetModifierMappingCookie{cookie}
-}
-
-// SetModifierMappingUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetModifierMappingUnchecked(c *xgb.Conn, KeycodesPerModifier byte, Keycodes []Keycode) SetModifierMappingCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(setModifierMappingRequest(c, KeycodesPerModifier, Keycodes), cookie)
-	return SetModifierMappingCookie{cookie}
-}
-
-// SetModifierMappingReply represents the data returned from a SetModifierMapping request.
-type SetModifierMappingReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	Status   byte
-}
-
-// Reply blocks and returns the reply data for a SetModifierMapping request.
-func (cook SetModifierMappingCookie) Reply() (*SetModifierMappingReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return setModifierMappingReply(buf), nil
-}
-
-// setModifierMappingReply reads a byte slice into a SetModifierMappingReply value.
-func setModifierMappingReply(buf []byte) *SetModifierMappingReply {
-	v := new(SetModifierMappingReply)
-	b := 1 // skip reply determinant
-
-	v.Status = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	return v
-}
-
-// Write request to wire for SetModifierMapping
-// setModifierMappingRequest writes a SetModifierMapping request to a byte slice.
-func setModifierMappingRequest(c *xgb.Conn, KeycodesPerModifier byte, Keycodes []Keycode) []byte {
-	size := xgb.Pad((4 + xgb.Pad(((int(KeycodesPerModifier) * 8) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 118 // request opcode
-	b += 1
-
-	buf[b] = KeycodesPerModifier
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	for i := 0; i < int((int(KeycodesPerModifier) * 8)); i++ {
-		buf[b] = byte(Keycodes[i])
-		b += 1
-	}
-
-	return buf
-}
-
-// SetPointerMappingCookie is a cookie used only for SetPointerMapping requests.
-type SetPointerMappingCookie struct {
-	*xgb.Cookie
-}
-
-// SetPointerMapping sends a checked request.
-// If an error occurs, it will be returned with the reply by calling SetPointerMappingCookie.Reply()
-func SetPointerMapping(c *xgb.Conn, MapLen byte, Map []byte) SetPointerMappingCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(setPointerMappingRequest(c, MapLen, Map), cookie)
-	return SetPointerMappingCookie{cookie}
-}
-
-// SetPointerMappingUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetPointerMappingUnchecked(c *xgb.Conn, MapLen byte, Map []byte) SetPointerMappingCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(setPointerMappingRequest(c, MapLen, Map), cookie)
-	return SetPointerMappingCookie{cookie}
-}
-
-// SetPointerMappingReply represents the data returned from a SetPointerMapping request.
-type SetPointerMappingReply struct {
-	Sequence uint16 // sequence number of the request for this reply
-	Length   uint32 // number of bytes in this reply
-	Status   byte
-}
-
-// Reply blocks and returns the reply data for a SetPointerMapping request.
-func (cook SetPointerMappingCookie) Reply() (*SetPointerMappingReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return setPointerMappingReply(buf), nil
-}
-
-// setPointerMappingReply reads a byte slice into a SetPointerMappingReply value.
-func setPointerMappingReply(buf []byte) *SetPointerMappingReply {
-	v := new(SetPointerMappingReply)
-	b := 1 // skip reply determinant
-
-	v.Status = buf[b]
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	return v
-}
-
-// Write request to wire for SetPointerMapping
-// setPointerMappingRequest writes a SetPointerMapping request to a byte slice.
-func setPointerMappingRequest(c *xgb.Conn, MapLen byte, Map []byte) []byte {
-	size := xgb.Pad((4 + xgb.Pad((int(MapLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 116 // request opcode
-	b += 1
-
-	buf[b] = MapLen
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	copy(buf[b:], Map[:MapLen])
-	b += int(MapLen)
-
-	return buf
-}
-
-// SetScreenSaverCookie is a cookie used only for SetScreenSaver requests.
-type SetScreenSaverCookie struct {
-	*xgb.Cookie
-}
-
-// SetScreenSaver sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetScreenSaver(c *xgb.Conn, Timeout int16, Interval int16, PreferBlanking byte, AllowExposures byte) SetScreenSaverCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(setScreenSaverRequest(c, Timeout, Interval, PreferBlanking, AllowExposures), cookie)
-	return SetScreenSaverCookie{cookie}
-}
-
-// SetScreenSaverChecked sends a checked request.
-// If an error occurs, it can be retrieved using SetScreenSaverCookie.Check()
-func SetScreenSaverChecked(c *xgb.Conn, Timeout int16, Interval int16, PreferBlanking byte, AllowExposures byte) SetScreenSaverCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(setScreenSaverRequest(c, Timeout, Interval, PreferBlanking, AllowExposures), cookie)
-	return SetScreenSaverCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SetScreenSaverCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SetScreenSaver
-// setScreenSaverRequest writes a SetScreenSaver request to a byte slice.
-func setScreenSaverRequest(c *xgb.Conn, Timeout int16, Interval int16, PreferBlanking byte, AllowExposures byte) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 107 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Timeout))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(Interval))
-	b += 2
-
-	buf[b] = PreferBlanking
-	b += 1
-
-	buf[b] = AllowExposures
-	b += 1
-
-	return buf
-}
-
-// SetSelectionOwnerCookie is a cookie used only for SetSelectionOwner requests.
-type SetSelectionOwnerCookie struct {
-	*xgb.Cookie
-}
-
-// SetSelectionOwner sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func SetSelectionOwner(c *xgb.Conn, Owner Window, Selection Atom, Time Timestamp) SetSelectionOwnerCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(setSelectionOwnerRequest(c, Owner, Selection, Time), cookie)
-	return SetSelectionOwnerCookie{cookie}
-}
-
-// SetSelectionOwnerChecked sends a checked request.
-// If an error occurs, it can be retrieved using SetSelectionOwnerCookie.Check()
-func SetSelectionOwnerChecked(c *xgb.Conn, Owner Window, Selection Atom, Time Timestamp) SetSelectionOwnerCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(setSelectionOwnerRequest(c, Owner, Selection, Time), cookie)
-	return SetSelectionOwnerCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook SetSelectionOwnerCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for SetSelectionOwner
-// setSelectionOwnerRequest writes a SetSelectionOwner request to a byte slice.
-func setSelectionOwnerRequest(c *xgb.Conn, Owner Window, Selection Atom, Time Timestamp) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 22 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Owner))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Selection))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(Time))
-	b += 4
-
-	return buf
-}
-
-// StoreColorsCookie is a cookie used only for StoreColors requests.
-type StoreColorsCookie struct {
-	*xgb.Cookie
-}
-
-// StoreColors sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func StoreColors(c *xgb.Conn, Cmap Colormap, Items []Coloritem) StoreColorsCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(storeColorsRequest(c, Cmap, Items), cookie)
-	return StoreColorsCookie{cookie}
-}
-
-// StoreColorsChecked sends a checked request.
-// If an error occurs, it can be retrieved using StoreColorsCookie.Check()
-func StoreColorsChecked(c *xgb.Conn, Cmap Colormap, Items []Coloritem) StoreColorsCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(storeColorsRequest(c, Cmap, Items), cookie)
-	return StoreColorsCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook StoreColorsCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for StoreColors
-// storeColorsRequest writes a StoreColors request to a byte slice.
-func storeColorsRequest(c *xgb.Conn, Cmap Colormap, Items []Coloritem) []byte {
-	size := xgb.Pad((8 + xgb.Pad((len(Items) * 12))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 89 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	b += ColoritemListBytes(buf[b:], Items)
-
-	return buf
-}
-
-// StoreNamedColorCookie is a cookie used only for StoreNamedColor requests.
-type StoreNamedColorCookie struct {
-	*xgb.Cookie
-}
-
-// StoreNamedColor sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func StoreNamedColor(c *xgb.Conn, Flags byte, Cmap Colormap, Pixel uint32, NameLen uint16, Name string) StoreNamedColorCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(storeNamedColorRequest(c, Flags, Cmap, Pixel, NameLen, Name), cookie)
-	return StoreNamedColorCookie{cookie}
-}
-
-// StoreNamedColorChecked sends a checked request.
-// If an error occurs, it can be retrieved using StoreNamedColorCookie.Check()
-func StoreNamedColorChecked(c *xgb.Conn, Flags byte, Cmap Colormap, Pixel uint32, NameLen uint16, Name string) StoreNamedColorCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(storeNamedColorRequest(c, Flags, Cmap, Pixel, NameLen, Name), cookie)
-	return StoreNamedColorCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook StoreNamedColorCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for StoreNamedColor
-// storeNamedColorRequest writes a StoreNamedColor request to a byte slice.
-func storeNamedColorRequest(c *xgb.Conn, Flags byte, Cmap Colormap, Pixel uint32, NameLen uint16, Name string) []byte {
-	size := xgb.Pad((16 + xgb.Pad((int(NameLen) * 1))))
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 90 // request opcode
-	b += 1
-
-	buf[b] = Flags
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	xgb.Put32(buf[b:], Pixel)
-	b += 4
-
-	xgb.Put16(buf[b:], NameLen)
-	b += 2
-
-	b += 2 // padding
-
-	copy(buf[b:], Name[:NameLen])
-	b += int(NameLen)
-
-	return buf
-}
-
-// TranslateCoordinatesCookie is a cookie used only for TranslateCoordinates requests.
-type TranslateCoordinatesCookie struct {
-	*xgb.Cookie
-}
-
-// TranslateCoordinates sends a checked request.
-// If an error occurs, it will be returned with the reply by calling TranslateCoordinatesCookie.Reply()
-func TranslateCoordinates(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16) TranslateCoordinatesCookie {
-	cookie := c.NewCookie(true, true)
-	c.NewRequest(translateCoordinatesRequest(c, SrcWindow, DstWindow, SrcX, SrcY), cookie)
-	return TranslateCoordinatesCookie{cookie}
-}
-
-// TranslateCoordinatesUnchecked sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func TranslateCoordinatesUnchecked(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16) TranslateCoordinatesCookie {
-	cookie := c.NewCookie(false, true)
-	c.NewRequest(translateCoordinatesRequest(c, SrcWindow, DstWindow, SrcX, SrcY), cookie)
-	return TranslateCoordinatesCookie{cookie}
-}
-
-// TranslateCoordinatesReply represents the data returned from a TranslateCoordinates request.
-type TranslateCoordinatesReply struct {
-	Sequence   uint16 // sequence number of the request for this reply
-	Length     uint32 // number of bytes in this reply
-	SameScreen bool
-	Child      Window
-	DstX       int16
-	DstY       int16
-}
-
-// Reply blocks and returns the reply data for a TranslateCoordinates request.
-func (cook TranslateCoordinatesCookie) Reply() (*TranslateCoordinatesReply, error) {
-	buf, err := cook.Cookie.Reply()
-	if err != nil {
-		return nil, err
-	}
-	if buf == nil {
-		return nil, nil
-	}
-	return translateCoordinatesReply(buf), nil
-}
-
-// translateCoordinatesReply reads a byte slice into a TranslateCoordinatesReply value.
-func translateCoordinatesReply(buf []byte) *TranslateCoordinatesReply {
-	v := new(TranslateCoordinatesReply)
-	b := 1 // skip reply determinant
-
-	if buf[b] == 1 {
-		v.SameScreen = true
-	} else {
-		v.SameScreen = false
-	}
-	b += 1
-
-	v.Sequence = xgb.Get16(buf[b:])
-	b += 2
-
-	v.Length = xgb.Get32(buf[b:]) // 4-byte units
-	b += 4
-
-	v.Child = Window(xgb.Get32(buf[b:]))
-	b += 4
-
-	v.DstX = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	v.DstY = int16(xgb.Get16(buf[b:]))
-	b += 2
-
-	return v
-}
-
-// Write request to wire for TranslateCoordinates
-// translateCoordinatesRequest writes a TranslateCoordinates request to a byte slice.
-func translateCoordinatesRequest(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16) []byte {
-	size := 16
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 40 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(SrcWindow))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(DstWindow))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	return buf
-}
-
-// UngrabButtonCookie is a cookie used only for UngrabButton requests.
-type UngrabButtonCookie struct {
-	*xgb.Cookie
-}
-
-// UngrabButton sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func UngrabButton(c *xgb.Conn, Button byte, GrabWindow Window, Modifiers uint16) UngrabButtonCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(ungrabButtonRequest(c, Button, GrabWindow, Modifiers), cookie)
-	return UngrabButtonCookie{cookie}
-}
-
-// UngrabButtonChecked sends a checked request.
-// If an error occurs, it can be retrieved using UngrabButtonCookie.Check()
-func UngrabButtonChecked(c *xgb.Conn, Button byte, GrabWindow Window, Modifiers uint16) UngrabButtonCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(ungrabButtonRequest(c, Button, GrabWindow, Modifiers), cookie)
-	return UngrabButtonCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook UngrabButtonCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for UngrabButton
-// ungrabButtonRequest writes a UngrabButton request to a byte slice.
-func ungrabButtonRequest(c *xgb.Conn, Button byte, GrabWindow Window, Modifiers uint16) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 29 // request opcode
-	b += 1
-
-	buf[b] = Button
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(GrabWindow))
-	b += 4
-
-	xgb.Put16(buf[b:], Modifiers)
-	b += 2
-
-	b += 2 // padding
-
-	return buf
-}
-
-// UngrabKeyCookie is a cookie used only for UngrabKey requests.
-type UngrabKeyCookie struct {
-	*xgb.Cookie
-}
-
-// UngrabKey sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func UngrabKey(c *xgb.Conn, Key Keycode, GrabWindow Window, Modifiers uint16) UngrabKeyCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(ungrabKeyRequest(c, Key, GrabWindow, Modifiers), cookie)
-	return UngrabKeyCookie{cookie}
-}
-
-// UngrabKeyChecked sends a checked request.
-// If an error occurs, it can be retrieved using UngrabKeyCookie.Check()
-func UngrabKeyChecked(c *xgb.Conn, Key Keycode, GrabWindow Window, Modifiers uint16) UngrabKeyCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(ungrabKeyRequest(c, Key, GrabWindow, Modifiers), cookie)
-	return UngrabKeyCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook UngrabKeyCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for UngrabKey
-// ungrabKeyRequest writes a UngrabKey request to a byte slice.
-func ungrabKeyRequest(c *xgb.Conn, Key Keycode, GrabWindow Window, Modifiers uint16) []byte {
-	size := 12
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 34 // request opcode
-	b += 1
-
-	buf[b] = byte(Key)
-	b += 1
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(GrabWindow))
-	b += 4
-
-	xgb.Put16(buf[b:], Modifiers)
-	b += 2
-
-	b += 2 // padding
-
-	return buf
-}
-
-// UngrabKeyboardCookie is a cookie used only for UngrabKeyboard requests.
-type UngrabKeyboardCookie struct {
-	*xgb.Cookie
-}
-
-// UngrabKeyboard sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func UngrabKeyboard(c *xgb.Conn, Time Timestamp) UngrabKeyboardCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(ungrabKeyboardRequest(c, Time), cookie)
-	return UngrabKeyboardCookie{cookie}
-}
-
-// UngrabKeyboardChecked sends a checked request.
-// If an error occurs, it can be retrieved using UngrabKeyboardCookie.Check()
-func UngrabKeyboardChecked(c *xgb.Conn, Time Timestamp) UngrabKeyboardCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(ungrabKeyboardRequest(c, Time), cookie)
-	return UngrabKeyboardCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook UngrabKeyboardCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for UngrabKeyboard
-// ungrabKeyboardRequest writes a UngrabKeyboard request to a byte slice.
-func ungrabKeyboardRequest(c *xgb.Conn, Time Timestamp) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 32 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Time))
-	b += 4
-
-	return buf
-}
-
-// UngrabPointerCookie is a cookie used only for UngrabPointer requests.
-type UngrabPointerCookie struct {
-	*xgb.Cookie
-}
-
-// UngrabPointer sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func UngrabPointer(c *xgb.Conn, Time Timestamp) UngrabPointerCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(ungrabPointerRequest(c, Time), cookie)
-	return UngrabPointerCookie{cookie}
-}
-
-// UngrabPointerChecked sends a checked request.
-// If an error occurs, it can be retrieved using UngrabPointerCookie.Check()
-func UngrabPointerChecked(c *xgb.Conn, Time Timestamp) UngrabPointerCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(ungrabPointerRequest(c, Time), cookie)
-	return UngrabPointerCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook UngrabPointerCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for UngrabPointer
-// ungrabPointerRequest writes a UngrabPointer request to a byte slice.
-func ungrabPointerRequest(c *xgb.Conn, Time Timestamp) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 27 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Time))
-	b += 4
-
-	return buf
-}
-
-// UngrabServerCookie is a cookie used only for UngrabServer requests.
-type UngrabServerCookie struct {
-	*xgb.Cookie
-}
-
-// UngrabServer sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func UngrabServer(c *xgb.Conn) UngrabServerCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(ungrabServerRequest(c), cookie)
-	return UngrabServerCookie{cookie}
-}
-
-// UngrabServerChecked sends a checked request.
-// If an error occurs, it can be retrieved using UngrabServerCookie.Check()
-func UngrabServerChecked(c *xgb.Conn) UngrabServerCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(ungrabServerRequest(c), cookie)
-	return UngrabServerCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook UngrabServerCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for UngrabServer
-// ungrabServerRequest writes a UngrabServer request to a byte slice.
-func ungrabServerRequest(c *xgb.Conn) []byte {
-	size := 4
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 37 // request opcode
-	b += 1
-
-	b += 1                             // padding
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	return buf
-}
-
-// UninstallColormapCookie is a cookie used only for UninstallColormap requests.
-type UninstallColormapCookie struct {
-	*xgb.Cookie
-}
-
-// UninstallColormap sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func UninstallColormap(c *xgb.Conn, Cmap Colormap) UninstallColormapCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(uninstallColormapRequest(c, Cmap), cookie)
-	return UninstallColormapCookie{cookie}
-}
-
-// UninstallColormapChecked sends a checked request.
-// If an error occurs, it can be retrieved using UninstallColormapCookie.Check()
-func UninstallColormapChecked(c *xgb.Conn, Cmap Colormap) UninstallColormapCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(uninstallColormapRequest(c, Cmap), cookie)
-	return UninstallColormapCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook UninstallColormapCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for UninstallColormap
-// uninstallColormapRequest writes a UninstallColormap request to a byte slice.
-func uninstallColormapRequest(c *xgb.Conn, Cmap Colormap) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 82 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Cmap))
-	b += 4
-
-	return buf
-}
-
-// UnmapSubwindowsCookie is a cookie used only for UnmapSubwindows requests.
-type UnmapSubwindowsCookie struct {
-	*xgb.Cookie
-}
-
-// UnmapSubwindows sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func UnmapSubwindows(c *xgb.Conn, Window Window) UnmapSubwindowsCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(unmapSubwindowsRequest(c, Window), cookie)
-	return UnmapSubwindowsCookie{cookie}
-}
-
-// UnmapSubwindowsChecked sends a checked request.
-// If an error occurs, it can be retrieved using UnmapSubwindowsCookie.Check()
-func UnmapSubwindowsChecked(c *xgb.Conn, Window Window) UnmapSubwindowsCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(unmapSubwindowsRequest(c, Window), cookie)
-	return UnmapSubwindowsCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook UnmapSubwindowsCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for UnmapSubwindows
-// unmapSubwindowsRequest writes a UnmapSubwindows request to a byte slice.
-func unmapSubwindowsRequest(c *xgb.Conn, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 11 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// UnmapWindowCookie is a cookie used only for UnmapWindow requests.
-type UnmapWindowCookie struct {
-	*xgb.Cookie
-}
-
-// UnmapWindow sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func UnmapWindow(c *xgb.Conn, Window Window) UnmapWindowCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(unmapWindowRequest(c, Window), cookie)
-	return UnmapWindowCookie{cookie}
-}
-
-// UnmapWindowChecked sends a checked request.
-// If an error occurs, it can be retrieved using UnmapWindowCookie.Check()
-func UnmapWindowChecked(c *xgb.Conn, Window Window) UnmapWindowCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(unmapWindowRequest(c, Window), cookie)
-	return UnmapWindowCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook UnmapWindowCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for UnmapWindow
-// unmapWindowRequest writes a UnmapWindow request to a byte slice.
-func unmapWindowRequest(c *xgb.Conn, Window Window) []byte {
-	size := 8
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 10 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(Window))
-	b += 4
-
-	return buf
-}
-
-// WarpPointerCookie is a cookie used only for WarpPointer requests.
-type WarpPointerCookie struct {
-	*xgb.Cookie
-}
-
-// WarpPointer sends an unchecked request.
-// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
-func WarpPointer(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16) WarpPointerCookie {
-	cookie := c.NewCookie(false, false)
-	c.NewRequest(warpPointerRequest(c, SrcWindow, DstWindow, SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY), cookie)
-	return WarpPointerCookie{cookie}
-}
-
-// WarpPointerChecked sends a checked request.
-// If an error occurs, it can be retrieved using WarpPointerCookie.Check()
-func WarpPointerChecked(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16) WarpPointerCookie {
-	cookie := c.NewCookie(true, false)
-	c.NewRequest(warpPointerRequest(c, SrcWindow, DstWindow, SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY), cookie)
-	return WarpPointerCookie{cookie}
-}
-
-// Check returns an error if one occurred for checked requests that are not expecting a reply.
-// This cannot be called for requests expecting a reply, nor for unchecked requests.
-func (cook WarpPointerCookie) Check() error {
-	return cook.Cookie.Check()
-}
-
-// Write request to wire for WarpPointer
-// warpPointerRequest writes a WarpPointer request to a byte slice.
-func warpPointerRequest(c *xgb.Conn, SrcWindow Window, DstWindow Window, SrcX int16, SrcY int16, SrcWidth uint16, SrcHeight uint16, DstX int16, DstY int16) []byte {
-	size := 24
-	b := 0
-	buf := make([]byte, size)
-
-	buf[b] = 41 // request opcode
-	b += 1
-
-	b += 1 // padding
-
-	xgb.Put16(buf[b:], uint16(size/4)) // write request size in 4-byte units
-	b += 2
-
-	xgb.Put32(buf[b:], uint32(SrcWindow))
-	b += 4
-
-	xgb.Put32(buf[b:], uint32(DstWindow))
-	b += 4
-
-	xgb.Put16(buf[b:], uint16(SrcX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(SrcY))
-	b += 2
-
-	xgb.Put16(buf[b:], SrcWidth)
-	b += 2
-
-	xgb.Put16(buf[b:], SrcHeight)
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstX))
-	b += 2
-
-	xgb.Put16(buf[b:], uint16(DstY))
-	b += 2
-
-	return buf
-}
diff --git a/shiny/internal/xgb/xproto/xproto_test.go b/shiny/internal/xgb/xproto/xproto_test.go
deleted file mode 100644
index 56dc417..0000000
--- a/shiny/internal/xgb/xproto/xproto_test.go
+++ /dev/null
@@ -1,387 +0,0 @@
-package xproto
-
-/*
-	Tests for XGB.
-
-	These tests only test the core X protocol at the moment. It isn't even
-	close to complete coverage (and probably never will be), but it does test
-	a number of different corners: requests with no replies, requests without
-	replies, checked (i.e., synchronous) errors, unchecked (i.e., asynchronous)
-	errors, and sequence number wrapping.
-
-	There are also a couple of benchmarks that show the difference between
-	correctly issuing lots of requests and gathering replies and
-	incorrectly doing the same. (This particular difference is one of the
-	claimed advantages of the XCB, and therefore XGB, family.)
-
-	In sum, these tests are more focused on testing the core xgb package itself,
-	rather than whether xproto has properly implemented the core X client
-	protocol.
-*/
-
-import (
-	"fmt"
-	"log"
-	"math/rand"
-	"os"
-	"testing"
-	"time"
-
-	"golang.org/x/exp/shiny/internal/xgb"
-)
-
-// The X connection used throughout testing.
-var X *xgb.Conn
-
-func TestMain(m *testing.M) {
-	if os.Getenv("DISPLAY") == "" {
-		log.Printf("No X; Skipping tests")
-		os.Exit(0)
-	}
-
-	var err error
-	X, err = xgb.NewConn()
-	if err != nil {
-		log.Fatal(err)
-	}
-	rand.Seed(time.Now().UnixNano())
-	go grabEvents()
-
-	os.Exit(m.Run())
-}
-
-/******************************************************************************/
-// Tests
-/******************************************************************************/
-
-// TestSynchronousError purposefully causes a BadWindow error in a
-// MapWindow request, and checks it synchronously.
-func TestSynchronousError(t *testing.T) {
-	err := MapWindowChecked(X, 0).Check() // resource 0 is always invalid
-	if err == nil {
-		t.Fatalf("MapWindow: A MapWindow request that should return an " +
-			"error has returned a nil error.")
-	}
-	verifyMapWindowError(t, err)
-}
-
-// TestAsynchronousError does the same thing as TestSynchronousError, but
-// grabs the error asynchronously instead.
-func TestAsynchronousError(t *testing.T) {
-	MapWindow(X, 0) // resource id 0 is always invalid
-
-	evOrErr := waitForEvent(t, 5)
-	if evOrErr.ev != nil {
-		t.Fatalf("After issuing an erroneous MapWindow request, we have "+
-			"received an event rather than an error: %s", evOrErr.ev)
-	}
-	verifyMapWindowError(t, evOrErr.err)
-}
-
-// TestCookieBuffer issues (2^16) + n requets *without* replies to guarantee
-// that the sequence number wraps and that the cookie buffer will have to
-// flush itself (since there are no replies coming in to flush it).
-// And just like TestSequenceWrap, we issue another request with a reply
-// at the end to make sure XGB is still working properly.
-func TestCookieBuffer(t *testing.T) {
-	n := (1 << 16) + 10
-	for i := 0; i < n; i++ {
-		NoOperation(X)
-	}
-	TestProperty(t)
-}
-
-// TestSequenceWrap issues (2^16) + n requests w/ replies to guarantee that the
-// sequence number (which is a 16 bit integer) will wrap. It then issues one
-// final request to ensure things still work properly.
-func TestSequenceWrap(t *testing.T) {
-	n := (1 << 16) + 10
-	for i := 0; i < n; i++ {
-		_, err := InternAtom(X, false, 5, "RANDO").Reply()
-		if err != nil {
-			t.Fatalf("InternAtom: %s", err)
-		}
-	}
-	TestProperty(t)
-}
-
-// TestProperty tests whether a random value can be set and read.
-func TestProperty(t *testing.T) {
-	propName := randString(20) // whatevs
-	writeVal := randString(20)
-	readVal, err := changeAndGetProp(propName, writeVal)
-	if err != nil {
-		t.Error(err)
-	}
-
-	if readVal != writeVal {
-		t.Errorf("The value written, '%s', is not the same as the "+
-			"value read '%s'.", writeVal, readVal)
-	}
-}
-
-// TestWindowEvents creates a window, maps it, listens for configure notify
-// events, issues a configure request, and checks for the appropriate
-// configure notify event.
-// This probably violates the notion of "test one thing and test it well,"
-// but testing X stuff is unique since it involves so much state.
-// Each request is checked to make sure there are no errors returned. If there
-// is an error, the test is failed.
-// You may see a window appear quickly and then disappear. Do not be alarmed :P
-// It's possible that this test will yield a false negative because we cannot
-// control our environment. That is, the window manager could override the
-// placement set. However, we set override redirect on the window, so the
-// window manager *shouldn't* touch our window if it is well-behaved.
-func TestWindowEvents(t *testing.T) {
-	// The geometry to set the window.
-	gx, gy, gw, gh := 200, 400, 1000, 300
-
-	wid, err := NewWindowId(X)
-	if err != nil {
-		t.Fatalf("NewId: %s", err)
-	}
-
-	screen := Setup(X).DefaultScreen(X) // alias
-	err = CreateWindowChecked(X, screen.RootDepth, wid, screen.Root,
-		0, 0, 500, 500, 0,
-		WindowClassInputOutput, screen.RootVisual,
-		CwBackPixel|CwOverrideRedirect, []uint32{0xffffffff, 1}).Check()
-	if err != nil {
-		t.Fatalf("CreateWindow: %s", err)
-	}
-
-	err = MapWindowChecked(X, wid).Check()
-	if err != nil {
-		t.Fatalf("MapWindow: %s", err)
-	}
-
-	// We don't listen in the CreateWindow request so that we don't get
-	// a MapNotify event.
-	err = ChangeWindowAttributesChecked(X, wid,
-		CwEventMask, []uint32{EventMaskStructureNotify}).Check()
-	if err != nil {
-		t.Fatalf("ChangeWindowAttributes: %s", err)
-	}
-
-	err = ConfigureWindowChecked(X, wid,
-		ConfigWindowX|ConfigWindowY|
-			ConfigWindowWidth|ConfigWindowHeight,
-		[]uint32{uint32(gx), uint32(gy), uint32(gw), uint32(gh)}).Check()
-	if err != nil {
-		t.Fatalf("ConfigureWindow: %s", err)
-	}
-
-	evOrErr := waitForEvent(t, 5)
-	switch event := evOrErr.ev.(type) {
-	case ConfigureNotifyEvent:
-		if event.X != int16(gx) {
-			t.Fatalf("x was set to %d but ConfigureNotify reports %d",
-				gx, event.X)
-		}
-		if event.Y != int16(gy) {
-			t.Fatalf("y was set to %d but ConfigureNotify reports %d",
-				gy, event.Y)
-		}
-		if event.Width != uint16(gw) {
-			t.Fatalf("width was set to %d but ConfigureNotify reports %d",
-				gw, event.Width)
-		}
-		if event.Height != uint16(gh) {
-			t.Fatalf("height was set to %d but ConfigureNotify reports %d",
-				gh, event.Height)
-		}
-	default:
-		t.Fatalf("Expected a ConfigureNotifyEvent but got %T instead.", event)
-	}
-
-	// Okay, clean up!
-	err = ChangeWindowAttributesChecked(X, wid,
-		CwEventMask, []uint32{0}).Check()
-	if err != nil {
-		t.Fatalf("ChangeWindowAttributes: %s", err)
-	}
-
-	err = DestroyWindowChecked(X, wid).Check()
-	if err != nil {
-		t.Fatalf("DestroyWindow: %s", err)
-	}
-}
-
-// Calls GetFontPath function, Issue #12
-func TestGetFontPath(t *testing.T) {
-	fontPathReply, err := GetFontPath(X).Reply()
-	if err != nil {
-		t.Fatalf("GetFontPath: %v", err)
-	}
-	_ = fontPathReply
-}
-
-func TestListFonts(t *testing.T) {
-	listFontsReply, err := ListFonts(X, 10, 1, "*").Reply()
-	if err != nil {
-		t.Fatalf("ListFonts: %v", err)
-	}
-	_ = listFontsReply
-}
-
-/******************************************************************************/
-// Benchmarks
-/******************************************************************************/
-
-// BenchmarkInternAtomsGood shows how many requests with replies
-// *should* be sent and gathered from the server. Namely, send as many
-// requests as you can at once, then go back and gather up all the replies.
-// More importantly, this approach can exploit parallelism when
-// GOMAXPROCS > 1.
-// Run with `go test -run 'nomatch' -bench '.*' -cpu 1,2,6` if you have
-// multiple cores to see the improvement that parallelism brings.
-func BenchmarkInternAtomsGood(b *testing.B) {
-	b.StopTimer()
-	names := seqNames(b.N)
-
-	b.StartTimer()
-	cookies := make([]InternAtomCookie, b.N)
-	for i := 0; i < b.N; i++ {
-		cookies[i] = InternAtom(X, false, uint16(len(names[i])), names[i])
-	}
-	for _, cookie := range cookies {
-		cookie.Reply()
-	}
-}
-
-// BenchmarkInternAtomsBad shows how *not* to issue a lot of requests with
-// replies. Namely, each subsequent request isn't issued *until* the last
-// reply is made. This implies a round trip to the X server for every
-// iteration.
-func BenchmarkInternAtomsPoor(b *testing.B) {
-	b.StopTimer()
-	names := seqNames(b.N)
-
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		InternAtom(X, false, uint16(len(names[i])), names[i]).Reply()
-	}
-}
-
-/******************************************************************************/
-// Helper functions
-/******************************************************************************/
-
-// changeAndGetProp sets property 'prop' with value 'val'.
-// It then gets the value of that property and returns it.
-// (It's used to check that the 'val' going in is the same 'val' going out.)
-// It tests both requests with and without replies (GetProperty and
-// ChangeProperty respectively.)
-func changeAndGetProp(prop, val string) (string, error) {
-	setup := Setup(X)
-	root := setup.DefaultScreen(X).Root
-
-	propAtom, err := InternAtom(X, false, uint16(len(prop)), prop).Reply()
-	if err != nil {
-		return "", fmt.Errorf("InternAtom: %s", err)
-	}
-
-	typName := "UTF8_STRING"
-	typAtom, err := InternAtom(X, false, uint16(len(typName)), typName).Reply()
-	if err != nil {
-		return "", fmt.Errorf("InternAtom: %s", err)
-	}
-
-	err = ChangePropertyChecked(X, PropModeReplace, root, propAtom.Atom,
-		typAtom.Atom, 8, uint32(len(val)), []byte(val)).Check()
-	if err != nil {
-		return "", fmt.Errorf("ChangeProperty: %s", err)
-	}
-
-	reply, err := GetProperty(X, false, root, propAtom.Atom,
-		GetPropertyTypeAny, 0, (1<<32)-1).Reply()
-	if err != nil {
-		return "", fmt.Errorf("GetProperty: %s", err)
-	}
-	if reply.Format != 8 {
-		return "", fmt.Errorf("Property reply format is %d but it should be 8.",
-			reply.Format)
-	}
-
-	return string(reply.Value), nil
-}
-
-// verifyMapWindowError takes an error that is returned with an invalid
-// MapWindow request with a window Id of 0 and makes sure the error is the
-// right type and contains the correct values.
-func verifyMapWindowError(t *testing.T, err error) {
-	switch e := err.(type) {
-	case WindowError:
-		if e.BadValue != 0 {
-			t.Fatalf("WindowError should report a bad value of 0 but "+
-				"it reports %d instead.", e.BadValue)
-		}
-		if e.MajorOpcode != 8 {
-			t.Fatalf("WindowError should report a major opcode of 8 "+
-				"(which is a MapWindow request), but it reports %d instead.",
-				e.MajorOpcode)
-		}
-	default:
-		t.Fatalf("Expected a WindowError but got %T instead.", e)
-	}
-}
-
-// randString generates a random string of length n.
-func randString(n int) string {
-	byts := make([]byte, n)
-	for i := 0; i < n; i++ {
-		rando := rand.Intn(53)
-		switch {
-		case rando <= 25:
-			byts[i] = byte(65 + rando)
-		case rando <= 51:
-			byts[i] = byte(97 + rando - 26)
-		default:
-			byts[i] = ' '
-		}
-	}
-	return string(byts)
-}
-
-// seqNames creates a slice of NAME0, NAME1, ..., NAMEN.
-func seqNames(n int) []string {
-	names := make([]string, n)
-	for i := range names {
-		names[i] = fmt.Sprintf("NAME%d", i)
-	}
-	return names
-}
-
-// evErr represents a value that is either an event or an error.
-type evErr struct {
-	ev  xgb.Event
-	err xgb.Error
-}
-
-// channel used to pass evErrs.
-var evOrErrChan = make(chan evErr, 0)
-
-// grabEvents is a goroutine that reads events off the wire.
-// We used this instead of WaitForEvent directly in our tests so that
-// we can timeout and fail a test.
-func grabEvents() {
-	for {
-		ev, err := X.WaitForEvent()
-		evOrErrChan <- evErr{ev, err}
-	}
-}
-
-// waitForEvent asks the evOrErrChan channel for an event.
-// If it doesn't get an event in 'n' seconds, the current test is failed.
-func waitForEvent(t *testing.T, n int) evErr {
-	var evOrErr evErr
-
-	select {
-	case evOrErr = <-evOrErrChan:
-	case <-time.After(time.Second * 5):
-		t.Fatalf("After waiting 5 seconds for an event or an error, " +
-			"we have timed out.")
-	}
-
-	return evOrErr
-}
