// Package xv is the X client API for the XVideo extension.
package xv

// This file is automatically generated from xv.xml. Edit at your peril!

import (
	"github.com/BurntSushi/xgb"

	"github.com/BurntSushi/xgb/shm"
	"github.com/BurntSushi/xgb/xproto"
)

// Init must be called before using the XVideo extension.
func Init(c *xgb.Conn) error {
	reply, err := xproto.QueryExtension(c, 6, "XVideo").Reply()
	switch {
	case err != nil:
		return err
	case !reply.Present:
		return xgb.Errorf("No extension named XVideo could be found on on the server.")
	}

	c.ExtLock.Lock()
	c.Extensions["XVideo"] = reply.MajorOpcode
	c.ExtLock.Unlock()
	for evNum, fun := range xgb.NewExtEventFuncs["XVideo"] {
		xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun
	}
	for errNum, fun := range xgb.NewExtErrorFuncs["XVideo"] {
		xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun
	}
	return nil
}

func init() {
	xgb.NewExtEventFuncs["XVideo"] = make(map[int]xgb.NewEventFun)
	xgb.NewExtErrorFuncs["XVideo"] = make(map[int]xgb.NewErrorFun)
}

type AdaptorInfo struct {
	BaseId     Port
	NameSize   uint16
	NumPorts   uint16
	NumFormats uint16
	Type       byte
	// padding: 1 bytes
	Name string // size: xgb.Pad((int(NameSize) * 1))
	// padding: 0 bytes
	Formats []Format // size: xgb.Pad((int(NumFormats) * 8))
}

// AdaptorInfoRead reads a byte slice into a AdaptorInfo value.
func AdaptorInfoRead(buf []byte, v *AdaptorInfo) int {
	b := 0

	v.BaseId = Port(xgb.Get32(buf[b:]))
	b += 4

	v.NameSize = xgb.Get16(buf[b:])
	b += 2

	v.NumPorts = xgb.Get16(buf[b:])
	b += 2

	v.NumFormats = xgb.Get16(buf[b:])
	b += 2

	v.Type = buf[b]
	b += 1

	b += 1 // padding

	{
		byteString := make([]byte, v.NameSize)
		copy(byteString[:v.NameSize], buf[b:])
		v.Name = string(byteString)
		b += int(v.NameSize)
	}

	b += 0 // padding

	v.Formats = make([]Format, v.NumFormats)
	b += FormatReadList(buf[b:], v.Formats)

	return b
}

// AdaptorInfoReadList reads a byte slice into a list of AdaptorInfo values.
func AdaptorInfoReadList(buf []byte, dest []AdaptorInfo) int {
	b := 0
	for i := 0; i < len(dest); i++ {
		dest[i] = AdaptorInfo{}
		b += AdaptorInfoRead(buf[b:], &dest[i])
	}
	return xgb.Pad(b)
}

// Bytes writes a AdaptorInfo value to a byte slice.
func (v AdaptorInfo) Bytes() []byte {
	buf := make([]byte, (((12 + xgb.Pad((int(v.NameSize) * 1))) + 0) + xgb.Pad((int(v.NumFormats) * 8))))
	b := 0

	xgb.Put32(buf[b:], uint32(v.BaseId))
	b += 4

	xgb.Put16(buf[b:], v.NameSize)
	b += 2

	xgb.Put16(buf[b:], v.NumPorts)
	b += 2

	xgb.Put16(buf[b:], v.NumFormats)
	b += 2

	buf[b] = v.Type
	b += 1

	b += 1 // padding

	copy(buf[b:], v.Name[:v.NameSize])
	b += int(v.NameSize)

	b += 0 // padding

	b += FormatListBytes(buf[b:], v.Formats)

	return buf[:b]
}

// AdaptorInfoListBytes writes a list of AdaptorInfo values to a byte slice.
func AdaptorInfoListBytes(buf []byte, list []AdaptorInfo) int {
	b := 0
	var structBytes []byte
	for _, item := range list {
		structBytes = item.Bytes()
		copy(buf[b:], structBytes)
		b += len(structBytes)
	}
	return xgb.Pad(b)
}

// AdaptorInfoListSize computes the size (bytes) of a list of AdaptorInfo values.
func AdaptorInfoListSize(list []AdaptorInfo) int {
	size := 0
	for _, item := range list {
		size += (((12 + xgb.Pad((int(item.NameSize) * 1))) + 0) + xgb.Pad((int(item.NumFormats) * 8)))
	}
	return size
}

const (
	AttributeFlagGettable = 1
	AttributeFlagSettable = 2
)

type AttributeInfo struct {
	Flags uint32
	Min   int32
	Max   int32
	Size  uint32
	Name  string // size: xgb.Pad((int(Size) * 1))
}

// AttributeInfoRead reads a byte slice into a AttributeInfo value.
func AttributeInfoRead(buf []byte, v *AttributeInfo) int {
	b := 0

	v.Flags = xgb.Get32(buf[b:])
	b += 4

	v.Min = int32(xgb.Get32(buf[b:]))
	b += 4

	v.Max = int32(xgb.Get32(buf[b:]))
	b += 4

	v.Size = xgb.Get32(buf[b:])
	b += 4

	{
		byteString := make([]byte, v.Size)
		copy(byteString[:v.Size], buf[b:])
		v.Name = string(byteString)
		b += int(v.Size)
	}

	return b
}

// AttributeInfoReadList reads a byte slice into a list of AttributeInfo values.
func AttributeInfoReadList(buf []byte, dest []AttributeInfo) int {
	b := 0
	for i := 0; i < len(dest); i++ {
		dest[i] = AttributeInfo{}
		b += AttributeInfoRead(buf[b:], &dest[i])
	}
	return xgb.Pad(b)
}

// Bytes writes a AttributeInfo value to a byte slice.
func (v AttributeInfo) Bytes() []byte {
	buf := make([]byte, (16 + xgb.Pad((int(v.Size) * 1))))
	b := 0

	xgb.Put32(buf[b:], v.Flags)
	b += 4

	xgb.Put32(buf[b:], uint32(v.Min))
	b += 4

	xgb.Put32(buf[b:], uint32(v.Max))
	b += 4

	xgb.Put32(buf[b:], v.Size)
	b += 4

	copy(buf[b:], v.Name[:v.Size])
	b += int(v.Size)

	return buf[:b]
}

// AttributeInfoListBytes writes a list of AttributeInfo values to a byte slice.
func AttributeInfoListBytes(buf []byte, list []AttributeInfo) int {
	b := 0
	var structBytes []byte
	for _, item := range list {
		structBytes = item.Bytes()
		copy(buf[b:], structBytes)
		b += len(structBytes)
	}
	return xgb.Pad(b)
}

// AttributeInfoListSize computes the size (bytes) of a list of AttributeInfo values.
func AttributeInfoListSize(list []AttributeInfo) int {
	size := 0
	for _, item := range list {
		size += (16 + xgb.Pad((int(item.Size) * 1)))
	}
	return size
}

// BadBadControl is the error number for a BadBadControl.
const BadBadControl = 2

type BadControlError struct {
	Sequence uint16
	NiceName string
}

// BadControlErrorNew constructs a BadControlError value that implements xgb.Error from a byte slice.
func BadControlErrorNew(buf []byte) xgb.Error {
	v := BadControlError{}
	v.NiceName = "BadControl"

	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 BadBadControl error.
// This is mostly used internally.
func (err BadControlError) SequenceId() uint16 {
	return err.Sequence
}

// BadId returns the 'BadValue' number if one exists for the BadBadControl error. If no bad value exists, 0 is returned.
func (err BadControlError) BadId() uint32 {
	return 0
}

// Error returns a rudimentary string representation of the BadBadControl error.

func (err BadControlError) Error() string {
	fieldVals := make([]string, 0, 0)
	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
	return "BadBadControl {" + xgb.StringsJoin(fieldVals, ", ") + "}"
}

func init() {
	xgb.NewExtErrorFuncs["XVideo"][2] = BadControlErrorNew
}

// BadBadEncoding is the error number for a BadBadEncoding.
const BadBadEncoding = 1

type BadEncodingError struct {
	Sequence uint16
	NiceName string
}

// BadEncodingErrorNew constructs a BadEncodingError value that implements xgb.Error from a byte slice.
func BadEncodingErrorNew(buf []byte) xgb.Error {
	v := BadEncodingError{}
	v.NiceName = "BadEncoding"

	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 BadBadEncoding error.
// This is mostly used internally.
func (err BadEncodingError) SequenceId() uint16 {
	return err.Sequence
}

// BadId returns the 'BadValue' number if one exists for the BadBadEncoding error. If no bad value exists, 0 is returned.
func (err BadEncodingError) BadId() uint32 {
	return 0
}

// Error returns a rudimentary string representation of the BadBadEncoding error.

func (err BadEncodingError) Error() string {
	fieldVals := make([]string, 0, 0)
	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
	return "BadBadEncoding {" + xgb.StringsJoin(fieldVals, ", ") + "}"
}

func init() {
	xgb.NewExtErrorFuncs["XVideo"][1] = BadEncodingErrorNew
}

// BadBadPort is the error number for a BadBadPort.
const BadBadPort = 0

type BadPortError struct {
	Sequence uint16
	NiceName string
}

// BadPortErrorNew constructs a BadPortError value that implements xgb.Error from a byte slice.
func BadPortErrorNew(buf []byte) xgb.Error {
	v := BadPortError{}
	v.NiceName = "BadPort"

	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 BadBadPort error.
// This is mostly used internally.
func (err BadPortError) SequenceId() uint16 {
	return err.Sequence
}

// BadId returns the 'BadValue' number if one exists for the BadBadPort error. If no bad value exists, 0 is returned.
func (err BadPortError) BadId() uint32 {
	return 0
}

// Error returns a rudimentary string representation of the BadBadPort error.

func (err BadPortError) Error() string {
	fieldVals := make([]string, 0, 0)
	fieldVals = append(fieldVals, "NiceName: "+err.NiceName)
	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", err.Sequence))
	return "BadBadPort {" + xgb.StringsJoin(fieldVals, ", ") + "}"
}

func init() {
	xgb.NewExtErrorFuncs["XVideo"][0] = BadPortErrorNew
}

type Encoding uint32

func NewEncodingId(c *xgb.Conn) (Encoding, error) {
	id, err := c.NewId()
	if err != nil {
		return 0, err
	}
	return Encoding(id), nil
}

type EncodingInfo struct {
	Encoding Encoding
	NameSize uint16
	Width    uint16
	Height   uint16
	// padding: 2 bytes
	Rate Rational
	Name string // size: xgb.Pad((int(NameSize) * 1))
}

// EncodingInfoRead reads a byte slice into a EncodingInfo value.
func EncodingInfoRead(buf []byte, v *EncodingInfo) int {
	b := 0

	v.Encoding = Encoding(xgb.Get32(buf[b:]))
	b += 4

	v.NameSize = xgb.Get16(buf[b:])
	b += 2

	v.Width = xgb.Get16(buf[b:])
	b += 2

	v.Height = xgb.Get16(buf[b:])
	b += 2

	b += 2 // padding

	v.Rate = Rational{}
	b += RationalRead(buf[b:], &v.Rate)

	{
		byteString := make([]byte, v.NameSize)
		copy(byteString[:v.NameSize], buf[b:])
		v.Name = string(byteString)
		b += int(v.NameSize)
	}

	return b
}

// EncodingInfoReadList reads a byte slice into a list of EncodingInfo values.
func EncodingInfoReadList(buf []byte, dest []EncodingInfo) int {
	b := 0
	for i := 0; i < len(dest); i++ {
		dest[i] = EncodingInfo{}
		b += EncodingInfoRead(buf[b:], &dest[i])
	}
	return xgb.Pad(b)
}

// Bytes writes a EncodingInfo value to a byte slice.
func (v EncodingInfo) Bytes() []byte {
	buf := make([]byte, (20 + xgb.Pad((int(v.NameSize) * 1))))
	b := 0

	xgb.Put32(buf[b:], uint32(v.Encoding))
	b += 4

	xgb.Put16(buf[b:], v.NameSize)
	b += 2

	xgb.Put16(buf[b:], v.Width)
	b += 2

	xgb.Put16(buf[b:], v.Height)
	b += 2

	b += 2 // padding

	{
		structBytes := v.Rate.Bytes()
		copy(buf[b:], structBytes)
		b += len(structBytes)
	}

	copy(buf[b:], v.Name[:v.NameSize])
	b += int(v.NameSize)

	return buf[:b]
}

// EncodingInfoListBytes writes a list of EncodingInfo values to a byte slice.
func EncodingInfoListBytes(buf []byte, list []EncodingInfo) int {
	b := 0
	var structBytes []byte
	for _, item := range list {
		structBytes = item.Bytes()
		copy(buf[b:], structBytes)
		b += len(structBytes)
	}
	return xgb.Pad(b)
}

// EncodingInfoListSize computes the size (bytes) of a list of EncodingInfo values.
func EncodingInfoListSize(list []EncodingInfo) int {
	size := 0
	for _, item := range list {
		size += (20 + xgb.Pad((int(item.NameSize) * 1)))
	}
	return size
}

type Format struct {
	Visual xproto.Visualid
	Depth  byte
	// padding: 3 bytes
}

// FormatRead reads a byte slice into a Format value.
func FormatRead(buf []byte, v *Format) int {
	b := 0

	v.Visual = xproto.Visualid(xgb.Get32(buf[b:]))
	b += 4

	v.Depth = buf[b]
	b += 1

	b += 3 // 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

	xgb.Put32(buf[b:], uint32(v.Visual))
	b += 4

	buf[b] = v.Depth
	b += 1

	b += 3 // 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)
}

const (
	GrabPortStatusSuccess        = 0
	GrabPortStatusBadExtension   = 1
	GrabPortStatusAlreadyGrabbed = 2
	GrabPortStatusInvalidTime    = 3
	GrabPortStatusBadReply       = 4
	GrabPortStatusBadAlloc       = 5
)

type Image struct {
	Id        uint32
	Width     uint16
	Height    uint16
	DataSize  uint32
	NumPlanes uint32
	Pitches   []uint32 // size: xgb.Pad((int(NumPlanes) * 4))
	// alignment gap to multiple of 4
	Offsets []uint32 // size: xgb.Pad((int(NumPlanes) * 4))
	Data    []byte   // size: xgb.Pad((int(DataSize) * 1))
}

// ImageRead reads a byte slice into a Image value.
func ImageRead(buf []byte, v *Image) int {
	b := 0

	v.Id = xgb.Get32(buf[b:])
	b += 4

	v.Width = xgb.Get16(buf[b:])
	b += 2

	v.Height = xgb.Get16(buf[b:])
	b += 2

	v.DataSize = xgb.Get32(buf[b:])
	b += 4

	v.NumPlanes = xgb.Get32(buf[b:])
	b += 4

	v.Pitches = make([]uint32, v.NumPlanes)
	for i := 0; i < int(v.NumPlanes); i++ {
		v.Pitches[i] = xgb.Get32(buf[b:])
		b += 4
	}

	b = (b + 3) & ^3 // alignment gap

	v.Offsets = make([]uint32, v.NumPlanes)
	for i := 0; i < int(v.NumPlanes); i++ {
		v.Offsets[i] = xgb.Get32(buf[b:])
		b += 4
	}

	v.Data = make([]byte, v.DataSize)
	copy(v.Data[:v.DataSize], buf[b:])
	b += int(v.DataSize)

	return b
}

// ImageReadList reads a byte slice into a list of Image values.
func ImageReadList(buf []byte, dest []Image) int {
	b := 0
	for i := 0; i < len(dest); i++ {
		dest[i] = Image{}
		b += ImageRead(buf[b:], &dest[i])
	}
	return xgb.Pad(b)
}

// Bytes writes a Image value to a byte slice.
func (v Image) Bytes() []byte {
	buf := make([]byte, ((((16 + xgb.Pad((int(v.NumPlanes) * 4))) + 4) + xgb.Pad((int(v.NumPlanes) * 4))) + xgb.Pad((int(v.DataSize) * 1))))
	b := 0

	xgb.Put32(buf[b:], v.Id)
	b += 4

	xgb.Put16(buf[b:], v.Width)
	b += 2

	xgb.Put16(buf[b:], v.Height)
	b += 2

	xgb.Put32(buf[b:], v.DataSize)
	b += 4

	xgb.Put32(buf[b:], v.NumPlanes)
	b += 4

	for i := 0; i < int(v.NumPlanes); i++ {
		xgb.Put32(buf[b:], v.Pitches[i])
		b += 4
	}

	b = (b + 3) & ^3 // alignment gap

	for i := 0; i < int(v.NumPlanes); i++ {
		xgb.Put32(buf[b:], v.Offsets[i])
		b += 4
	}

	copy(buf[b:], v.Data[:v.DataSize])
	b += int(v.DataSize)

	return buf[:b]
}

// ImageListBytes writes a list of Image values to a byte slice.
func ImageListBytes(buf []byte, list []Image) int {
	b := 0
	var structBytes []byte
	for _, item := range list {
		structBytes = item.Bytes()
		copy(buf[b:], structBytes)
		b += len(structBytes)
	}
	return xgb.Pad(b)
}

// ImageListSize computes the size (bytes) of a list of Image values.
func ImageListSize(list []Image) int {
	size := 0
	for _, item := range list {
		size += ((((16 + xgb.Pad((int(item.NumPlanes) * 4))) + 4) + xgb.Pad((int(item.NumPlanes) * 4))) + xgb.Pad((int(item.DataSize) * 1)))
	}
	return size
}

type ImageFormatInfo struct {
	Id        uint32
	Type      byte
	ByteOrder byte
	// padding: 2 bytes
	Guid      []byte // size: 16
	Bpp       byte
	NumPlanes byte
	// padding: 2 bytes
	Depth byte
	// padding: 3 bytes
	RedMask   uint32
	GreenMask uint32
	BlueMask  uint32
	Format    byte
	// padding: 3 bytes
	YSampleBits    uint32
	USampleBits    uint32
	VSampleBits    uint32
	VhorzYPeriod   uint32
	VhorzUPeriod   uint32
	VhorzVPeriod   uint32
	VvertYPeriod   uint32
	VvertUPeriod   uint32
	VvertVPeriod   uint32
	VcompOrder     []byte // size: 32
	VscanlineOrder byte
	// padding: 11 bytes
}

// ImageFormatInfoRead reads a byte slice into a ImageFormatInfo value.
func ImageFormatInfoRead(buf []byte, v *ImageFormatInfo) int {
	b := 0

	v.Id = xgb.Get32(buf[b:])
	b += 4

	v.Type = buf[b]
	b += 1

	v.ByteOrder = buf[b]
	b += 1

	b += 2 // padding

	v.Guid = make([]byte, 16)
	copy(v.Guid[:16], buf[b:])
	b += int(16)

	v.Bpp = buf[b]
	b += 1

	v.NumPlanes = buf[b]
	b += 1

	b += 2 // padding

	v.Depth = buf[b]
	b += 1

	b += 3 // 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

	v.Format = buf[b]
	b += 1

	b += 3 // padding

	v.YSampleBits = xgb.Get32(buf[b:])
	b += 4

	v.USampleBits = xgb.Get32(buf[b:])
	b += 4

	v.VSampleBits = xgb.Get32(buf[b:])
	b += 4

	v.VhorzYPeriod = xgb.Get32(buf[b:])
	b += 4

	v.VhorzUPeriod = xgb.Get32(buf[b:])
	b += 4

	v.VhorzVPeriod = xgb.Get32(buf[b:])
	b += 4

	v.VvertYPeriod = xgb.Get32(buf[b:])
	b += 4

	v.VvertUPeriod = xgb.Get32(buf[b:])
	b += 4

	v.VvertVPeriod = xgb.Get32(buf[b:])
	b += 4

	v.VcompOrder = make([]byte, 32)
	copy(v.VcompOrder[:32], buf[b:])
	b += int(32)

	v.VscanlineOrder = buf[b]
	b += 1

	b += 11 // padding

	return b
}

// ImageFormatInfoReadList reads a byte slice into a list of ImageFormatInfo values.
func ImageFormatInfoReadList(buf []byte, dest []ImageFormatInfo) int {
	b := 0
	for i := 0; i < len(dest); i++ {
		dest[i] = ImageFormatInfo{}
		b += ImageFormatInfoRead(buf[b:], &dest[i])
	}
	return xgb.Pad(b)
}

// Bytes writes a ImageFormatInfo value to a byte slice.
func (v ImageFormatInfo) Bytes() []byte {
	buf := make([]byte, 128)
	b := 0

	xgb.Put32(buf[b:], v.Id)
	b += 4

	buf[b] = v.Type
	b += 1

	buf[b] = v.ByteOrder
	b += 1

	b += 2 // padding

	copy(buf[b:], v.Guid[:16])
	b += int(16)

	buf[b] = v.Bpp
	b += 1

	buf[b] = v.NumPlanes
	b += 1

	b += 2 // padding

	buf[b] = v.Depth
	b += 1

	b += 3 // padding

	xgb.Put32(buf[b:], v.RedMask)
	b += 4

	xgb.Put32(buf[b:], v.GreenMask)
	b += 4

	xgb.Put32(buf[b:], v.BlueMask)
	b += 4

	buf[b] = v.Format
	b += 1

	b += 3 // padding

	xgb.Put32(buf[b:], v.YSampleBits)
	b += 4

	xgb.Put32(buf[b:], v.USampleBits)
	b += 4

	xgb.Put32(buf[b:], v.VSampleBits)
	b += 4

	xgb.Put32(buf[b:], v.VhorzYPeriod)
	b += 4

	xgb.Put32(buf[b:], v.VhorzUPeriod)
	b += 4

	xgb.Put32(buf[b:], v.VhorzVPeriod)
	b += 4

	xgb.Put32(buf[b:], v.VvertYPeriod)
	b += 4

	xgb.Put32(buf[b:], v.VvertUPeriod)
	b += 4

	xgb.Put32(buf[b:], v.VvertVPeriod)
	b += 4

	copy(buf[b:], v.VcompOrder[:32])
	b += int(32)

	buf[b] = v.VscanlineOrder
	b += 1

	b += 11 // padding

	return buf[:b]
}

// ImageFormatInfoListBytes writes a list of ImageFormatInfo values to a byte slice.
func ImageFormatInfoListBytes(buf []byte, list []ImageFormatInfo) int {
	b := 0
	var structBytes []byte
	for _, item := range list {
		structBytes = item.Bytes()
		copy(buf[b:], structBytes)
		b += len(structBytes)
	}
	return xgb.Pad(b)
}

// ImageFormatInfoListSize computes the size (bytes) of a list of ImageFormatInfo values.
func ImageFormatInfoListSize(list []ImageFormatInfo) int {
	size := 0
	for _ = range list {
		size += 128
	}
	return size
}

const (
	ImageFormatInfoFormatPacked = 0
	ImageFormatInfoFormatPlanar = 1
)

const (
	ImageFormatInfoTypeRgb = 0
	ImageFormatInfoTypeYuv = 1
)

type Port uint32

func NewPortId(c *xgb.Conn) (Port, error) {
	id, err := c.NewId()
	if err != nil {
		return 0, err
	}
	return Port(id), nil
}

// PortNotify is the event number for a PortNotifyEvent.
const PortNotify = 1

type PortNotifyEvent struct {
	Sequence uint16
	// padding: 1 bytes
	Time      xproto.Timestamp
	Port      Port
	Attribute xproto.Atom
	Value     int32
}

// PortNotifyEventNew constructs a PortNotifyEvent value that implements xgb.Event from a byte slice.
func PortNotifyEventNew(buf []byte) xgb.Event {
	v := PortNotifyEvent{}
	b := 1 // don't read event number

	b += 1 // padding

	v.Sequence = xgb.Get16(buf[b:])
	b += 2

	v.Time = xproto.Timestamp(xgb.Get32(buf[b:]))
	b += 4

	v.Port = Port(xgb.Get32(buf[b:]))
	b += 4

	v.Attribute = xproto.Atom(xgb.Get32(buf[b:]))
	b += 4

	v.Value = int32(xgb.Get32(buf[b:]))
	b += 4

	return v
}

// Bytes writes a PortNotifyEvent value to a byte slice.
func (v PortNotifyEvent) Bytes() []byte {
	buf := make([]byte, 32)
	b := 0

	// write event number
	buf[b] = 1
	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.Port))
	b += 4

	xgb.Put32(buf[b:], uint32(v.Attribute))
	b += 4

	xgb.Put32(buf[b:], uint32(v.Value))
	b += 4

	return buf
}

// SequenceId returns the sequence id attached to the PortNotify event.
// Events without a sequence number (KeymapNotify) return 0.
// This is mostly used internally.
func (v PortNotifyEvent) SequenceId() uint16 {
	return v.Sequence
}

// String is a rudimentary string representation of PortNotifyEvent.
func (v PortNotifyEvent) String() string {
	fieldVals := make([]string, 0, 5)
	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
	fieldVals = append(fieldVals, xgb.Sprintf("Port: %d", v.Port))
	fieldVals = append(fieldVals, xgb.Sprintf("Attribute: %d", v.Attribute))
	fieldVals = append(fieldVals, xgb.Sprintf("Value: %d", v.Value))
	return "PortNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
}

func init() {
	xgb.NewExtEventFuncs["XVideo"][1] = PortNotifyEventNew
}

type Rational struct {
	Numerator   int32
	Denominator int32
}

// RationalRead reads a byte slice into a Rational value.
func RationalRead(buf []byte, v *Rational) int {
	b := 0

	v.Numerator = int32(xgb.Get32(buf[b:]))
	b += 4

	v.Denominator = int32(xgb.Get32(buf[b:]))
	b += 4

	return b
}

// RationalReadList reads a byte slice into a list of Rational values.
func RationalReadList(buf []byte, dest []Rational) int {
	b := 0
	for i := 0; i < len(dest); i++ {
		dest[i] = Rational{}
		b += RationalRead(buf[b:], &dest[i])
	}
	return xgb.Pad(b)
}

// Bytes writes a Rational value to a byte slice.
func (v Rational) Bytes() []byte {
	buf := make([]byte, 8)
	b := 0

	xgb.Put32(buf[b:], uint32(v.Numerator))
	b += 4

	xgb.Put32(buf[b:], uint32(v.Denominator))
	b += 4

	return buf[:b]
}

// RationalListBytes writes a list of Rational values to a byte slice.
func RationalListBytes(buf []byte, list []Rational) 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 (
	ScanlineOrderTopToBottom = 0
	ScanlineOrderBottomToTop = 1
)

const (
	TypeInputMask  = 1
	TypeOutputMask = 2
	TypeVideoMask  = 4
	TypeStillMask  = 8
	TypeImageMask  = 16
)

// VideoNotify is the event number for a VideoNotifyEvent.
const VideoNotify = 0

type VideoNotifyEvent struct {
	Sequence uint16
	Reason   byte
	Time     xproto.Timestamp
	Drawable xproto.Drawable
	Port     Port
}

// VideoNotifyEventNew constructs a VideoNotifyEvent value that implements xgb.Event from a byte slice.
func VideoNotifyEventNew(buf []byte) xgb.Event {
	v := VideoNotifyEvent{}
	b := 1 // don't read event number

	v.Reason = buf[b]
	b += 1

	v.Sequence = xgb.Get16(buf[b:])
	b += 2

	v.Time = xproto.Timestamp(xgb.Get32(buf[b:]))
	b += 4

	v.Drawable = xproto.Drawable(xgb.Get32(buf[b:]))
	b += 4

	v.Port = Port(xgb.Get32(buf[b:]))
	b += 4

	return v
}

// Bytes writes a VideoNotifyEvent value to a byte slice.
func (v VideoNotifyEvent) Bytes() []byte {
	buf := make([]byte, 32)
	b := 0

	// write event number
	buf[b] = 0
	b += 1

	buf[b] = v.Reason
	b += 1

	b += 2 // skip sequence number

	xgb.Put32(buf[b:], uint32(v.Time))
	b += 4

	xgb.Put32(buf[b:], uint32(v.Drawable))
	b += 4

	xgb.Put32(buf[b:], uint32(v.Port))
	b += 4

	return buf
}

// SequenceId returns the sequence id attached to the VideoNotify event.
// Events without a sequence number (KeymapNotify) return 0.
// This is mostly used internally.
func (v VideoNotifyEvent) SequenceId() uint16 {
	return v.Sequence
}

// String is a rudimentary string representation of VideoNotifyEvent.
func (v VideoNotifyEvent) String() string {
	fieldVals := make([]string, 0, 4)
	fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence))
	fieldVals = append(fieldVals, xgb.Sprintf("Reason: %d", v.Reason))
	fieldVals = append(fieldVals, xgb.Sprintf("Time: %d", v.Time))
	fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable))
	fieldVals = append(fieldVals, xgb.Sprintf("Port: %d", v.Port))
	return "VideoNotify {" + xgb.StringsJoin(fieldVals, ", ") + "}"
}

func init() {
	xgb.NewExtEventFuncs["XVideo"][0] = VideoNotifyEventNew
}

const (
	VideoNotifyReasonStarted   = 0
	VideoNotifyReasonStopped   = 1
	VideoNotifyReasonBusy      = 2
	VideoNotifyReasonPreempted = 3
	VideoNotifyReasonHardError = 4
)

// 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'

// GetPortAttributeCookie is a cookie used only for GetPortAttribute requests.
type GetPortAttributeCookie struct {
	*xgb.Cookie
}

// GetPortAttribute sends a checked request.
// If an error occurs, it will be returned with the reply by calling GetPortAttributeCookie.Reply()
func GetPortAttribute(c *xgb.Conn, Port Port, Attribute xproto.Atom) GetPortAttributeCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'GetPortAttribute' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, true)
	c.NewRequest(getPortAttributeRequest(c, Port, Attribute), cookie)
	return GetPortAttributeCookie{cookie}
}

// GetPortAttributeUnchecked sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func GetPortAttributeUnchecked(c *xgb.Conn, Port Port, Attribute xproto.Atom) GetPortAttributeCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'GetPortAttribute' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, true)
	c.NewRequest(getPortAttributeRequest(c, Port, Attribute), cookie)
	return GetPortAttributeCookie{cookie}
}

// GetPortAttributeReply represents the data returned from a GetPortAttribute request.
type GetPortAttributeReply struct {
	Sequence uint16 // sequence number of the request for this reply
	Length   uint32 // number of bytes in this reply
	// padding: 1 bytes
	Value int32
}

// Reply blocks and returns the reply data for a GetPortAttribute request.
func (cook GetPortAttributeCookie) Reply() (*GetPortAttributeReply, error) {
	buf, err := cook.Cookie.Reply()
	if err != nil {
		return nil, err
	}
	if buf == nil {
		return nil, nil
	}
	return getPortAttributeReply(buf), nil
}

// getPortAttributeReply reads a byte slice into a GetPortAttributeReply value.
func getPortAttributeReply(buf []byte) *GetPortAttributeReply {
	v := new(GetPortAttributeReply)
	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.Value = int32(xgb.Get32(buf[b:]))
	b += 4

	return v
}

// Write request to wire for GetPortAttribute
// getPortAttributeRequest writes a GetPortAttribute request to a byte slice.
func getPortAttributeRequest(c *xgb.Conn, Port Port, Attribute xproto.Atom) []byte {
	size := 12
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	b += 1

	buf[b] = 14 // 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(Port))
	b += 4

	xgb.Put32(buf[b:], uint32(Attribute))
	b += 4

	return buf
}

// GetStillCookie is a cookie used only for GetStill requests.
type GetStillCookie struct {
	*xgb.Cookie
}

// GetStill sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func GetStill(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) GetStillCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'GetStill' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, false)
	c.NewRequest(getStillRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie)
	return GetStillCookie{cookie}
}

// GetStillChecked sends a checked request.
// If an error occurs, it can be retrieved using GetStillCookie.Check()
func GetStillChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) GetStillCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'GetStill' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, false)
	c.NewRequest(getStillRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie)
	return GetStillCookie{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 GetStillCookie) Check() error {
	return cook.Cookie.Check()
}

// Write request to wire for GetStill
// getStillRequest writes a GetStill request to a byte slice.
func getStillRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) []byte {
	size := 32
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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

	xgb.Put32(buf[b:], uint32(Port))
	b += 4

	xgb.Put32(buf[b:], uint32(Drawable))
	b += 4

	xgb.Put32(buf[b:], uint32(Gc))
	b += 4

	xgb.Put16(buf[b:], uint16(VidX))
	b += 2

	xgb.Put16(buf[b:], uint16(VidY))
	b += 2

	xgb.Put16(buf[b:], VidW)
	b += 2

	xgb.Put16(buf[b:], VidH)
	b += 2

	xgb.Put16(buf[b:], uint16(DrwX))
	b += 2

	xgb.Put16(buf[b:], uint16(DrwY))
	b += 2

	xgb.Put16(buf[b:], DrwW)
	b += 2

	xgb.Put16(buf[b:], DrwH)
	b += 2

	return buf
}

// GetVideoCookie is a cookie used only for GetVideo requests.
type GetVideoCookie struct {
	*xgb.Cookie
}

// GetVideo sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func GetVideo(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) GetVideoCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'GetVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, false)
	c.NewRequest(getVideoRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie)
	return GetVideoCookie{cookie}
}

// GetVideoChecked sends a checked request.
// If an error occurs, it can be retrieved using GetVideoCookie.Check()
func GetVideoChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) GetVideoCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'GetVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, false)
	c.NewRequest(getVideoRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie)
	return GetVideoCookie{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 GetVideoCookie) Check() error {
	return cook.Cookie.Check()
}

// Write request to wire for GetVideo
// getVideoRequest writes a GetVideo request to a byte slice.
func getVideoRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) []byte {
	size := 32
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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(Port))
	b += 4

	xgb.Put32(buf[b:], uint32(Drawable))
	b += 4

	xgb.Put32(buf[b:], uint32(Gc))
	b += 4

	xgb.Put16(buf[b:], uint16(VidX))
	b += 2

	xgb.Put16(buf[b:], uint16(VidY))
	b += 2

	xgb.Put16(buf[b:], VidW)
	b += 2

	xgb.Put16(buf[b:], VidH)
	b += 2

	xgb.Put16(buf[b:], uint16(DrwX))
	b += 2

	xgb.Put16(buf[b:], uint16(DrwY))
	b += 2

	xgb.Put16(buf[b:], DrwW)
	b += 2

	xgb.Put16(buf[b:], DrwH)
	b += 2

	return buf
}

// GrabPortCookie is a cookie used only for GrabPort requests.
type GrabPortCookie struct {
	*xgb.Cookie
}

// GrabPort sends a checked request.
// If an error occurs, it will be returned with the reply by calling GrabPortCookie.Reply()
func GrabPort(c *xgb.Conn, Port Port, Time xproto.Timestamp) GrabPortCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'GrabPort' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, true)
	c.NewRequest(grabPortRequest(c, Port, Time), cookie)
	return GrabPortCookie{cookie}
}

// GrabPortUnchecked sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func GrabPortUnchecked(c *xgb.Conn, Port Port, Time xproto.Timestamp) GrabPortCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'GrabPort' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, true)
	c.NewRequest(grabPortRequest(c, Port, Time), cookie)
	return GrabPortCookie{cookie}
}

// GrabPortReply represents the data returned from a GrabPort request.
type GrabPortReply struct {
	Sequence uint16 // sequence number of the request for this reply
	Length   uint32 // number of bytes in this reply
	Result   byte
}

// Reply blocks and returns the reply data for a GrabPort request.
func (cook GrabPortCookie) Reply() (*GrabPortReply, error) {
	buf, err := cook.Cookie.Reply()
	if err != nil {
		return nil, err
	}
	if buf == nil {
		return nil, nil
	}
	return grabPortReply(buf), nil
}

// grabPortReply reads a byte slice into a GrabPortReply value.
func grabPortReply(buf []byte) *GrabPortReply {
	v := new(GrabPortReply)
	b := 1 // skip reply determinant

	v.Result = 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 GrabPort
// grabPortRequest writes a GrabPort request to a byte slice.
func grabPortRequest(c *xgb.Conn, Port Port, Time xproto.Timestamp) []byte {
	size := 12
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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(Port))
	b += 4

	xgb.Put32(buf[b:], uint32(Time))
	b += 4

	return buf
}

// ListImageFormatsCookie is a cookie used only for ListImageFormats requests.
type ListImageFormatsCookie struct {
	*xgb.Cookie
}

// ListImageFormats sends a checked request.
// If an error occurs, it will be returned with the reply by calling ListImageFormatsCookie.Reply()
func ListImageFormats(c *xgb.Conn, Port Port) ListImageFormatsCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'ListImageFormats' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, true)
	c.NewRequest(listImageFormatsRequest(c, Port), cookie)
	return ListImageFormatsCookie{cookie}
}

// ListImageFormatsUnchecked sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func ListImageFormatsUnchecked(c *xgb.Conn, Port Port) ListImageFormatsCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'ListImageFormats' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, true)
	c.NewRequest(listImageFormatsRequest(c, Port), cookie)
	return ListImageFormatsCookie{cookie}
}

// ListImageFormatsReply represents the data returned from a ListImageFormats request.
type ListImageFormatsReply struct {
	Sequence uint16 // sequence number of the request for this reply
	Length   uint32 // number of bytes in this reply
	// padding: 1 bytes
	NumFormats uint32
	// padding: 20 bytes
	Format []ImageFormatInfo // size: ImageFormatInfoListSize(Format)
}

// Reply blocks and returns the reply data for a ListImageFormats request.
func (cook ListImageFormatsCookie) Reply() (*ListImageFormatsReply, error) {
	buf, err := cook.Cookie.Reply()
	if err != nil {
		return nil, err
	}
	if buf == nil {
		return nil, nil
	}
	return listImageFormatsReply(buf), nil
}

// listImageFormatsReply reads a byte slice into a ListImageFormatsReply value.
func listImageFormatsReply(buf []byte) *ListImageFormatsReply {
	v := new(ListImageFormatsReply)
	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

	b += 20 // padding

	v.Format = make([]ImageFormatInfo, v.NumFormats)
	b += ImageFormatInfoReadList(buf[b:], v.Format)

	return v
}

// Write request to wire for ListImageFormats
// listImageFormatsRequest writes a ListImageFormats request to a byte slice.
func listImageFormatsRequest(c *xgb.Conn, Port Port) []byte {
	size := 8
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	b += 1

	buf[b] = 16 // 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(Port))
	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, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Id uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, Data []byte) PutImageCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'PutImage' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, false)
	c.NewRequest(putImageRequest(c, Port, Drawable, Gc, Id, SrcX, SrcY, SrcW, SrcH, DrwX, DrwY, DrwW, DrwH, Width, Height, 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, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Id uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, Data []byte) PutImageCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'PutImage' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, false)
	c.NewRequest(putImageRequest(c, Port, Drawable, Gc, Id, SrcX, SrcY, SrcW, SrcH, DrwX, DrwY, DrwW, DrwH, Width, Height, 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, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Id uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, Data []byte) []byte {
	size := xgb.Pad((40 + xgb.Pad((len(Data) * 1))))
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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(Port))
	b += 4

	xgb.Put32(buf[b:], uint32(Drawable))
	b += 4

	xgb.Put32(buf[b:], uint32(Gc))
	b += 4

	xgb.Put32(buf[b:], Id)
	b += 4

	xgb.Put16(buf[b:], uint16(SrcX))
	b += 2

	xgb.Put16(buf[b:], uint16(SrcY))
	b += 2

	xgb.Put16(buf[b:], SrcW)
	b += 2

	xgb.Put16(buf[b:], SrcH)
	b += 2

	xgb.Put16(buf[b:], uint16(DrwX))
	b += 2

	xgb.Put16(buf[b:], uint16(DrwY))
	b += 2

	xgb.Put16(buf[b:], DrwW)
	b += 2

	xgb.Put16(buf[b:], DrwH)
	b += 2

	xgb.Put16(buf[b:], Width)
	b += 2

	xgb.Put16(buf[b:], Height)
	b += 2

	copy(buf[b:], Data[:len(Data)])
	b += int(len(Data))

	return buf
}

// PutStillCookie is a cookie used only for PutStill requests.
type PutStillCookie struct {
	*xgb.Cookie
}

// PutStill sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func PutStill(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) PutStillCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'PutStill' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, false)
	c.NewRequest(putStillRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie)
	return PutStillCookie{cookie}
}

// PutStillChecked sends a checked request.
// If an error occurs, it can be retrieved using PutStillCookie.Check()
func PutStillChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) PutStillCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'PutStill' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, false)
	c.NewRequest(putStillRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie)
	return PutStillCookie{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 PutStillCookie) Check() error {
	return cook.Cookie.Check()
}

// Write request to wire for PutStill
// putStillRequest writes a PutStill request to a byte slice.
func putStillRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) []byte {
	size := 32
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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(Port))
	b += 4

	xgb.Put32(buf[b:], uint32(Drawable))
	b += 4

	xgb.Put32(buf[b:], uint32(Gc))
	b += 4

	xgb.Put16(buf[b:], uint16(VidX))
	b += 2

	xgb.Put16(buf[b:], uint16(VidY))
	b += 2

	xgb.Put16(buf[b:], VidW)
	b += 2

	xgb.Put16(buf[b:], VidH)
	b += 2

	xgb.Put16(buf[b:], uint16(DrwX))
	b += 2

	xgb.Put16(buf[b:], uint16(DrwY))
	b += 2

	xgb.Put16(buf[b:], DrwW)
	b += 2

	xgb.Put16(buf[b:], DrwH)
	b += 2

	return buf
}

// PutVideoCookie is a cookie used only for PutVideo requests.
type PutVideoCookie struct {
	*xgb.Cookie
}

// PutVideo sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func PutVideo(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) PutVideoCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'PutVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, false)
	c.NewRequest(putVideoRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie)
	return PutVideoCookie{cookie}
}

// PutVideoChecked sends a checked request.
// If an error occurs, it can be retrieved using PutVideoCookie.Check()
func PutVideoChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) PutVideoCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'PutVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, false)
	c.NewRequest(putVideoRequest(c, Port, Drawable, Gc, VidX, VidY, VidW, VidH, DrwX, DrwY, DrwW, DrwH), cookie)
	return PutVideoCookie{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 PutVideoCookie) Check() error {
	return cook.Cookie.Check()
}

// Write request to wire for PutVideo
// putVideoRequest writes a PutVideo request to a byte slice.
func putVideoRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, VidX int16, VidY int16, VidW uint16, VidH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16) []byte {
	size := 32
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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(Port))
	b += 4

	xgb.Put32(buf[b:], uint32(Drawable))
	b += 4

	xgb.Put32(buf[b:], uint32(Gc))
	b += 4

	xgb.Put16(buf[b:], uint16(VidX))
	b += 2

	xgb.Put16(buf[b:], uint16(VidY))
	b += 2

	xgb.Put16(buf[b:], VidW)
	b += 2

	xgb.Put16(buf[b:], VidH)
	b += 2

	xgb.Put16(buf[b:], uint16(DrwX))
	b += 2

	xgb.Put16(buf[b:], uint16(DrwY))
	b += 2

	xgb.Put16(buf[b:], DrwW)
	b += 2

	xgb.Put16(buf[b:], DrwH)
	b += 2

	return buf
}

// QueryAdaptorsCookie is a cookie used only for QueryAdaptors requests.
type QueryAdaptorsCookie struct {
	*xgb.Cookie
}

// QueryAdaptors sends a checked request.
// If an error occurs, it will be returned with the reply by calling QueryAdaptorsCookie.Reply()
func QueryAdaptors(c *xgb.Conn, Window xproto.Window) QueryAdaptorsCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryAdaptors' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, true)
	c.NewRequest(queryAdaptorsRequest(c, Window), cookie)
	return QueryAdaptorsCookie{cookie}
}

// QueryAdaptorsUnchecked sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func QueryAdaptorsUnchecked(c *xgb.Conn, Window xproto.Window) QueryAdaptorsCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryAdaptors' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, true)
	c.NewRequest(queryAdaptorsRequest(c, Window), cookie)
	return QueryAdaptorsCookie{cookie}
}

// QueryAdaptorsReply represents the data returned from a QueryAdaptors request.
type QueryAdaptorsReply struct {
	Sequence uint16 // sequence number of the request for this reply
	Length   uint32 // number of bytes in this reply
	// padding: 1 bytes
	NumAdaptors uint16
	// padding: 22 bytes
	Info []AdaptorInfo // size: AdaptorInfoListSize(Info)
}

// Reply blocks and returns the reply data for a QueryAdaptors request.
func (cook QueryAdaptorsCookie) Reply() (*QueryAdaptorsReply, error) {
	buf, err := cook.Cookie.Reply()
	if err != nil {
		return nil, err
	}
	if buf == nil {
		return nil, nil
	}
	return queryAdaptorsReply(buf), nil
}

// queryAdaptorsReply reads a byte slice into a QueryAdaptorsReply value.
func queryAdaptorsReply(buf []byte) *QueryAdaptorsReply {
	v := new(QueryAdaptorsReply)
	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.NumAdaptors = xgb.Get16(buf[b:])
	b += 2

	b += 22 // padding

	v.Info = make([]AdaptorInfo, v.NumAdaptors)
	b += AdaptorInfoReadList(buf[b:], v.Info)

	return v
}

// Write request to wire for QueryAdaptors
// queryAdaptorsRequest writes a QueryAdaptors request to a byte slice.
func queryAdaptorsRequest(c *xgb.Conn, Window xproto.Window) []byte {
	size := 8
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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(Window))
	b += 4

	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, Port Port, VidW uint16, VidH uint16, DrwW uint16, DrwH uint16, Motion bool) QueryBestSizeCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryBestSize' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, true)
	c.NewRequest(queryBestSizeRequest(c, Port, VidW, VidH, DrwW, DrwH, Motion), 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, Port Port, VidW uint16, VidH uint16, DrwW uint16, DrwH uint16, Motion bool) QueryBestSizeCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryBestSize' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, true)
	c.NewRequest(queryBestSizeRequest(c, Port, VidW, VidH, DrwW, DrwH, Motion), 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
	ActualWidth  uint16
	ActualHeight 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.ActualWidth = xgb.Get16(buf[b:])
	b += 2

	v.ActualHeight = 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, Port Port, VidW uint16, VidH uint16, DrwW uint16, DrwH uint16, Motion bool) []byte {
	size := 20
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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

	xgb.Put32(buf[b:], uint32(Port))
	b += 4

	xgb.Put16(buf[b:], VidW)
	b += 2

	xgb.Put16(buf[b:], VidH)
	b += 2

	xgb.Put16(buf[b:], DrwW)
	b += 2

	xgb.Put16(buf[b:], DrwH)
	b += 2

	if Motion {
		buf[b] = 1
	} else {
		buf[b] = 0
	}
	b += 1

	b += 3 // padding

	return buf
}

// QueryEncodingsCookie is a cookie used only for QueryEncodings requests.
type QueryEncodingsCookie struct {
	*xgb.Cookie
}

// QueryEncodings sends a checked request.
// If an error occurs, it will be returned with the reply by calling QueryEncodingsCookie.Reply()
func QueryEncodings(c *xgb.Conn, Port Port) QueryEncodingsCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryEncodings' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, true)
	c.NewRequest(queryEncodingsRequest(c, Port), cookie)
	return QueryEncodingsCookie{cookie}
}

// QueryEncodingsUnchecked sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func QueryEncodingsUnchecked(c *xgb.Conn, Port Port) QueryEncodingsCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryEncodings' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, true)
	c.NewRequest(queryEncodingsRequest(c, Port), cookie)
	return QueryEncodingsCookie{cookie}
}

// QueryEncodingsReply represents the data returned from a QueryEncodings request.
type QueryEncodingsReply struct {
	Sequence uint16 // sequence number of the request for this reply
	Length   uint32 // number of bytes in this reply
	// padding: 1 bytes
	NumEncodings uint16
	// padding: 22 bytes
	Info []EncodingInfo // size: EncodingInfoListSize(Info)
}

// Reply blocks and returns the reply data for a QueryEncodings request.
func (cook QueryEncodingsCookie) Reply() (*QueryEncodingsReply, error) {
	buf, err := cook.Cookie.Reply()
	if err != nil {
		return nil, err
	}
	if buf == nil {
		return nil, nil
	}
	return queryEncodingsReply(buf), nil
}

// queryEncodingsReply reads a byte slice into a QueryEncodingsReply value.
func queryEncodingsReply(buf []byte) *QueryEncodingsReply {
	v := new(QueryEncodingsReply)
	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.NumEncodings = xgb.Get16(buf[b:])
	b += 2

	b += 22 // padding

	v.Info = make([]EncodingInfo, v.NumEncodings)
	b += EncodingInfoReadList(buf[b:], v.Info)

	return v
}

// Write request to wire for QueryEncodings
// queryEncodingsRequest writes a QueryEncodings request to a byte slice.
func queryEncodingsRequest(c *xgb.Conn, Port Port) []byte {
	size := 8
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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(Port))
	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) QueryExtensionCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryExtension' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, true)
	c.NewRequest(queryExtensionRequest(c), 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) QueryExtensionCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryExtension' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, true)
	c.NewRequest(queryExtensionRequest(c), 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
	Major uint16
	Minor uint16
}

// 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

	v.Major = xgb.Get16(buf[b:])
	b += 2

	v.Minor = xgb.Get16(buf[b:])
	b += 2

	return v
}

// Write request to wire for QueryExtension
// queryExtensionRequest writes a QueryExtension request to a byte slice.
func queryExtensionRequest(c *xgb.Conn) []byte {
	size := 4
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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
}

// QueryImageAttributesCookie is a cookie used only for QueryImageAttributes requests.
type QueryImageAttributesCookie struct {
	*xgb.Cookie
}

// QueryImageAttributes sends a checked request.
// If an error occurs, it will be returned with the reply by calling QueryImageAttributesCookie.Reply()
func QueryImageAttributes(c *xgb.Conn, Port Port, Id uint32, Width uint16, Height uint16) QueryImageAttributesCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryImageAttributes' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, true)
	c.NewRequest(queryImageAttributesRequest(c, Port, Id, Width, Height), cookie)
	return QueryImageAttributesCookie{cookie}
}

// QueryImageAttributesUnchecked sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func QueryImageAttributesUnchecked(c *xgb.Conn, Port Port, Id uint32, Width uint16, Height uint16) QueryImageAttributesCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryImageAttributes' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, true)
	c.NewRequest(queryImageAttributesRequest(c, Port, Id, Width, Height), cookie)
	return QueryImageAttributesCookie{cookie}
}

// QueryImageAttributesReply represents the data returned from a QueryImageAttributes request.
type QueryImageAttributesReply struct {
	Sequence uint16 // sequence number of the request for this reply
	Length   uint32 // number of bytes in this reply
	// padding: 1 bytes
	NumPlanes uint32
	DataSize  uint32
	Width     uint16
	Height    uint16
	// padding: 12 bytes
	Pitches []uint32 // size: xgb.Pad((int(NumPlanes) * 4))
	// alignment gap to multiple of 4
	Offsets []uint32 // size: xgb.Pad((int(NumPlanes) * 4))
}

// Reply blocks and returns the reply data for a QueryImageAttributes request.
func (cook QueryImageAttributesCookie) Reply() (*QueryImageAttributesReply, error) {
	buf, err := cook.Cookie.Reply()
	if err != nil {
		return nil, err
	}
	if buf == nil {
		return nil, nil
	}
	return queryImageAttributesReply(buf), nil
}

// queryImageAttributesReply reads a byte slice into a QueryImageAttributesReply value.
func queryImageAttributesReply(buf []byte) *QueryImageAttributesReply {
	v := new(QueryImageAttributesReply)
	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.NumPlanes = xgb.Get32(buf[b:])
	b += 4

	v.DataSize = xgb.Get32(buf[b:])
	b += 4

	v.Width = xgb.Get16(buf[b:])
	b += 2

	v.Height = xgb.Get16(buf[b:])
	b += 2

	b += 12 // padding

	v.Pitches = make([]uint32, v.NumPlanes)
	for i := 0; i < int(v.NumPlanes); i++ {
		v.Pitches[i] = xgb.Get32(buf[b:])
		b += 4
	}

	b = (b + 3) & ^3 // alignment gap

	v.Offsets = make([]uint32, v.NumPlanes)
	for i := 0; i < int(v.NumPlanes); i++ {
		v.Offsets[i] = xgb.Get32(buf[b:])
		b += 4
	}

	return v
}

// Write request to wire for QueryImageAttributes
// queryImageAttributesRequest writes a QueryImageAttributes request to a byte slice.
func queryImageAttributesRequest(c *xgb.Conn, Port Port, Id uint32, Width uint16, Height uint16) []byte {
	size := 16
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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(Port))
	b += 4

	xgb.Put32(buf[b:], Id)
	b += 4

	xgb.Put16(buf[b:], Width)
	b += 2

	xgb.Put16(buf[b:], Height)
	b += 2

	return buf
}

// QueryPortAttributesCookie is a cookie used only for QueryPortAttributes requests.
type QueryPortAttributesCookie struct {
	*xgb.Cookie
}

// QueryPortAttributes sends a checked request.
// If an error occurs, it will be returned with the reply by calling QueryPortAttributesCookie.Reply()
func QueryPortAttributes(c *xgb.Conn, Port Port) QueryPortAttributesCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryPortAttributes' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, true)
	c.NewRequest(queryPortAttributesRequest(c, Port), cookie)
	return QueryPortAttributesCookie{cookie}
}

// QueryPortAttributesUnchecked sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func QueryPortAttributesUnchecked(c *xgb.Conn, Port Port) QueryPortAttributesCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'QueryPortAttributes' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, true)
	c.NewRequest(queryPortAttributesRequest(c, Port), cookie)
	return QueryPortAttributesCookie{cookie}
}

// QueryPortAttributesReply represents the data returned from a QueryPortAttributes request.
type QueryPortAttributesReply struct {
	Sequence uint16 // sequence number of the request for this reply
	Length   uint32 // number of bytes in this reply
	// padding: 1 bytes
	NumAttributes uint32
	TextSize      uint32
	// padding: 16 bytes
	Attributes []AttributeInfo // size: AttributeInfoListSize(Attributes)
}

// Reply blocks and returns the reply data for a QueryPortAttributes request.
func (cook QueryPortAttributesCookie) Reply() (*QueryPortAttributesReply, error) {
	buf, err := cook.Cookie.Reply()
	if err != nil {
		return nil, err
	}
	if buf == nil {
		return nil, nil
	}
	return queryPortAttributesReply(buf), nil
}

// queryPortAttributesReply reads a byte slice into a QueryPortAttributesReply value.
func queryPortAttributesReply(buf []byte) *QueryPortAttributesReply {
	v := new(QueryPortAttributesReply)
	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.NumAttributes = xgb.Get32(buf[b:])
	b += 4

	v.TextSize = xgb.Get32(buf[b:])
	b += 4

	b += 16 // padding

	v.Attributes = make([]AttributeInfo, v.NumAttributes)
	b += AttributeInfoReadList(buf[b:], v.Attributes)

	return v
}

// Write request to wire for QueryPortAttributes
// queryPortAttributesRequest writes a QueryPortAttributes request to a byte slice.
func queryPortAttributesRequest(c *xgb.Conn, Port Port) []byte {
	size := 8
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	b += 1

	buf[b] = 15 // 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(Port))
	b += 4

	return buf
}

// SelectPortNotifyCookie is a cookie used only for SelectPortNotify requests.
type SelectPortNotifyCookie struct {
	*xgb.Cookie
}

// SelectPortNotify sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func SelectPortNotify(c *xgb.Conn, Port Port, Onoff bool) SelectPortNotifyCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'SelectPortNotify' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, false)
	c.NewRequest(selectPortNotifyRequest(c, Port, Onoff), cookie)
	return SelectPortNotifyCookie{cookie}
}

// SelectPortNotifyChecked sends a checked request.
// If an error occurs, it can be retrieved using SelectPortNotifyCookie.Check()
func SelectPortNotifyChecked(c *xgb.Conn, Port Port, Onoff bool) SelectPortNotifyCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'SelectPortNotify' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, false)
	c.NewRequest(selectPortNotifyRequest(c, Port, Onoff), cookie)
	return SelectPortNotifyCookie{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 SelectPortNotifyCookie) Check() error {
	return cook.Cookie.Check()
}

// Write request to wire for SelectPortNotify
// selectPortNotifyRequest writes a SelectPortNotify request to a byte slice.
func selectPortNotifyRequest(c *xgb.Conn, Port Port, Onoff bool) []byte {
	size := 12
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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

	xgb.Put32(buf[b:], uint32(Port))
	b += 4

	if Onoff {
		buf[b] = 1
	} else {
		buf[b] = 0
	}
	b += 1

	b += 3 // padding

	return buf
}

// SelectVideoNotifyCookie is a cookie used only for SelectVideoNotify requests.
type SelectVideoNotifyCookie struct {
	*xgb.Cookie
}

// SelectVideoNotify sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func SelectVideoNotify(c *xgb.Conn, Drawable xproto.Drawable, Onoff bool) SelectVideoNotifyCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'SelectVideoNotify' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, false)
	c.NewRequest(selectVideoNotifyRequest(c, Drawable, Onoff), cookie)
	return SelectVideoNotifyCookie{cookie}
}

// SelectVideoNotifyChecked sends a checked request.
// If an error occurs, it can be retrieved using SelectVideoNotifyCookie.Check()
func SelectVideoNotifyChecked(c *xgb.Conn, Drawable xproto.Drawable, Onoff bool) SelectVideoNotifyCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'SelectVideoNotify' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, false)
	c.NewRequest(selectVideoNotifyRequest(c, Drawable, Onoff), cookie)
	return SelectVideoNotifyCookie{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 SelectVideoNotifyCookie) Check() error {
	return cook.Cookie.Check()
}

// Write request to wire for SelectVideoNotify
// selectVideoNotifyRequest writes a SelectVideoNotify request to a byte slice.
func selectVideoNotifyRequest(c *xgb.Conn, Drawable xproto.Drawable, Onoff bool) []byte {
	size := 12
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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

	xgb.Put32(buf[b:], uint32(Drawable))
	b += 4

	if Onoff {
		buf[b] = 1
	} else {
		buf[b] = 0
	}
	b += 1

	b += 3 // padding

	return buf
}

// SetPortAttributeCookie is a cookie used only for SetPortAttribute requests.
type SetPortAttributeCookie struct {
	*xgb.Cookie
}

// SetPortAttribute sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func SetPortAttribute(c *xgb.Conn, Port Port, Attribute xproto.Atom, Value int32) SetPortAttributeCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'SetPortAttribute' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, false)
	c.NewRequest(setPortAttributeRequest(c, Port, Attribute, Value), cookie)
	return SetPortAttributeCookie{cookie}
}

// SetPortAttributeChecked sends a checked request.
// If an error occurs, it can be retrieved using SetPortAttributeCookie.Check()
func SetPortAttributeChecked(c *xgb.Conn, Port Port, Attribute xproto.Atom, Value int32) SetPortAttributeCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'SetPortAttribute' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, false)
	c.NewRequest(setPortAttributeRequest(c, Port, Attribute, Value), cookie)
	return SetPortAttributeCookie{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 SetPortAttributeCookie) Check() error {
	return cook.Cookie.Check()
}

// Write request to wire for SetPortAttribute
// setPortAttributeRequest writes a SetPortAttribute request to a byte slice.
func setPortAttributeRequest(c *xgb.Conn, Port Port, Attribute xproto.Atom, Value int32) []byte {
	size := 16
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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

	xgb.Put32(buf[b:], uint32(Port))
	b += 4

	xgb.Put32(buf[b:], uint32(Attribute))
	b += 4

	xgb.Put32(buf[b:], uint32(Value))
	b += 4

	return buf
}

// ShmPutImageCookie is a cookie used only for ShmPutImage requests.
type ShmPutImageCookie struct {
	*xgb.Cookie
}

// ShmPutImage sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func ShmPutImage(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Shmseg shm.Seg, Id uint32, Offset uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, SendEvent byte) ShmPutImageCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'ShmPutImage' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, false)
	c.NewRequest(shmPutImageRequest(c, Port, Drawable, Gc, Shmseg, Id, Offset, SrcX, SrcY, SrcW, SrcH, DrwX, DrwY, DrwW, DrwH, Width, Height, SendEvent), cookie)
	return ShmPutImageCookie{cookie}
}

// ShmPutImageChecked sends a checked request.
// If an error occurs, it can be retrieved using ShmPutImageCookie.Check()
func ShmPutImageChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Shmseg shm.Seg, Id uint32, Offset uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, SendEvent byte) ShmPutImageCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'ShmPutImage' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, false)
	c.NewRequest(shmPutImageRequest(c, Port, Drawable, Gc, Shmseg, Id, Offset, SrcX, SrcY, SrcW, SrcH, DrwX, DrwY, DrwW, DrwH, Width, Height, SendEvent), cookie)
	return ShmPutImageCookie{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 ShmPutImageCookie) Check() error {
	return cook.Cookie.Check()
}

// Write request to wire for ShmPutImage
// shmPutImageRequest writes a ShmPutImage request to a byte slice.
func shmPutImageRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable, Gc xproto.Gcontext, Shmseg shm.Seg, Id uint32, Offset uint32, SrcX int16, SrcY int16, SrcW uint16, SrcH uint16, DrwX int16, DrwY int16, DrwW uint16, DrwH uint16, Width uint16, Height uint16, SendEvent byte) []byte {
	size := 52
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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(Port))
	b += 4

	xgb.Put32(buf[b:], uint32(Drawable))
	b += 4

	xgb.Put32(buf[b:], uint32(Gc))
	b += 4

	xgb.Put32(buf[b:], uint32(Shmseg))
	b += 4

	xgb.Put32(buf[b:], Id)
	b += 4

	xgb.Put32(buf[b:], Offset)
	b += 4

	xgb.Put16(buf[b:], uint16(SrcX))
	b += 2

	xgb.Put16(buf[b:], uint16(SrcY))
	b += 2

	xgb.Put16(buf[b:], SrcW)
	b += 2

	xgb.Put16(buf[b:], SrcH)
	b += 2

	xgb.Put16(buf[b:], uint16(DrwX))
	b += 2

	xgb.Put16(buf[b:], uint16(DrwY))
	b += 2

	xgb.Put16(buf[b:], DrwW)
	b += 2

	xgb.Put16(buf[b:], DrwH)
	b += 2

	xgb.Put16(buf[b:], Width)
	b += 2

	xgb.Put16(buf[b:], Height)
	b += 2

	buf[b] = SendEvent
	b += 1

	b += 3 // padding

	return buf
}

// StopVideoCookie is a cookie used only for StopVideo requests.
type StopVideoCookie struct {
	*xgb.Cookie
}

// StopVideo sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func StopVideo(c *xgb.Conn, Port Port, Drawable xproto.Drawable) StopVideoCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'StopVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, false)
	c.NewRequest(stopVideoRequest(c, Port, Drawable), cookie)
	return StopVideoCookie{cookie}
}

// StopVideoChecked sends a checked request.
// If an error occurs, it can be retrieved using StopVideoCookie.Check()
func StopVideoChecked(c *xgb.Conn, Port Port, Drawable xproto.Drawable) StopVideoCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'StopVideo' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, false)
	c.NewRequest(stopVideoRequest(c, Port, Drawable), cookie)
	return StopVideoCookie{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 StopVideoCookie) Check() error {
	return cook.Cookie.Check()
}

// Write request to wire for StopVideo
// stopVideoRequest writes a StopVideo request to a byte slice.
func stopVideoRequest(c *xgb.Conn, Port Port, Drawable xproto.Drawable) []byte {
	size := 12
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	b += 1

	buf[b] = 9 // 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(Port))
	b += 4

	xgb.Put32(buf[b:], uint32(Drawable))
	b += 4

	return buf
}

// UngrabPortCookie is a cookie used only for UngrabPort requests.
type UngrabPortCookie struct {
	*xgb.Cookie
}

// UngrabPort sends an unchecked request.
// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent.
func UngrabPort(c *xgb.Conn, Port Port, Time xproto.Timestamp) UngrabPortCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'UngrabPort' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(false, false)
	c.NewRequest(ungrabPortRequest(c, Port, Time), cookie)
	return UngrabPortCookie{cookie}
}

// UngrabPortChecked sends a checked request.
// If an error occurs, it can be retrieved using UngrabPortCookie.Check()
func UngrabPortChecked(c *xgb.Conn, Port Port, Time xproto.Timestamp) UngrabPortCookie {
	c.ExtLock.RLock()
	defer c.ExtLock.RUnlock()
	if _, ok := c.Extensions["XVideo"]; !ok {
		panic("Cannot issue request 'UngrabPort' using the uninitialized extension 'XVideo'. xv.Init(connObj) must be called first.")
	}
	cookie := c.NewCookie(true, false)
	c.NewRequest(ungrabPortRequest(c, Port, Time), cookie)
	return UngrabPortCookie{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 UngrabPortCookie) Check() error {
	return cook.Cookie.Check()
}

// Write request to wire for UngrabPort
// ungrabPortRequest writes a UngrabPort request to a byte slice.
func ungrabPortRequest(c *xgb.Conn, Port Port, Time xproto.Timestamp) []byte {
	size := 12
	b := 0
	buf := make([]byte, size)

	c.ExtLock.RLock()
	buf[b] = c.Extensions["XVideo"]
	c.ExtLock.RUnlock()
	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(Port))
	b += 4

	xgb.Put32(buf[b:], uint32(Time))
	b += 4

	return buf
}
