diff options
Diffstat (limited to 'nexgb/dri2')
-rw-r--r-- | nexgb/dri2/dri2.go | 1821 |
1 files changed, 1821 insertions, 0 deletions
diff --git a/nexgb/dri2/dri2.go b/nexgb/dri2/dri2.go new file mode 100644 index 0000000..820cf2b --- /dev/null +++ b/nexgb/dri2/dri2.go @@ -0,0 +1,1821 @@ +// Package dri2 is the X client API for the DRI2 extension. +package dri2 + +// This file is automatically generated from dri2.xml. Edit at your peril! + +import ( + "github.com/BurntSushi/xgb" + + "github.com/BurntSushi/xgb/xproto" +) + +// Init must be called before using the DRI2 extension. +func Init(c *xgb.Conn) error { + reply, err := xproto.QueryExtension(c, 4, "DRI2").Reply() + switch { + case err != nil: + return err + case !reply.Present: + return xgb.Errorf("No extension named DRI2 could be found on on the server.") + } + + c.ExtLock.Lock() + c.Extensions["DRI2"] = reply.MajorOpcode + c.ExtLock.Unlock() + for evNum, fun := range xgb.NewExtEventFuncs["DRI2"] { + xgb.NewEventFuncs[int(reply.FirstEvent)+evNum] = fun + } + for errNum, fun := range xgb.NewExtErrorFuncs["DRI2"] { + xgb.NewErrorFuncs[int(reply.FirstError)+errNum] = fun + } + return nil +} + +func init() { + xgb.NewExtEventFuncs["DRI2"] = make(map[int]xgb.NewEventFun) + xgb.NewExtErrorFuncs["DRI2"] = make(map[int]xgb.NewErrorFun) +} + +type AttachFormat struct { + Attachment uint32 + Format uint32 +} + +// AttachFormatRead reads a byte slice into a AttachFormat value. +func AttachFormatRead(buf []byte, v *AttachFormat) int { + b := 0 + + v.Attachment = xgb.Get32(buf[b:]) + b += 4 + + v.Format = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// AttachFormatReadList reads a byte slice into a list of AttachFormat values. +func AttachFormatReadList(buf []byte, dest []AttachFormat) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = AttachFormat{} + b += AttachFormatRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a AttachFormat value to a byte slice. +func (v AttachFormat) Bytes() []byte { + buf := make([]byte, 8) + b := 0 + + xgb.Put32(buf[b:], v.Attachment) + b += 4 + + xgb.Put32(buf[b:], v.Format) + b += 4 + + return buf[:b] +} + +// AttachFormatListBytes writes a list of AttachFormat values to a byte slice. +func AttachFormatListBytes(buf []byte, list []AttachFormat) 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 ( + AttachmentBufferFrontLeft = 0 + AttachmentBufferBackLeft = 1 + AttachmentBufferFrontRight = 2 + AttachmentBufferBackRight = 3 + AttachmentBufferDepth = 4 + AttachmentBufferStencil = 5 + AttachmentBufferAccum = 6 + AttachmentBufferFakeFrontLeft = 7 + AttachmentBufferFakeFrontRight = 8 + AttachmentBufferDepthStencil = 9 + AttachmentBufferHiz = 10 +) + +// BufferSwapComplete is the event number for a BufferSwapCompleteEvent. +const BufferSwapComplete = 0 + +type BufferSwapCompleteEvent struct { + Sequence uint16 + // padding: 1 bytes + EventType uint16 + // padding: 2 bytes + Drawable xproto.Drawable + UstHi uint32 + UstLo uint32 + MscHi uint32 + MscLo uint32 + Sbc uint32 +} + +// BufferSwapCompleteEventNew constructs a BufferSwapCompleteEvent value that implements xgb.Event from a byte slice. +func BufferSwapCompleteEventNew(buf []byte) xgb.Event { + v := BufferSwapCompleteEvent{} + b := 1 // don't read event number + + b += 1 // padding + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.EventType = xgb.Get16(buf[b:]) + b += 2 + + b += 2 // padding + + v.Drawable = xproto.Drawable(xgb.Get32(buf[b:])) + b += 4 + + v.UstHi = xgb.Get32(buf[b:]) + b += 4 + + v.UstLo = xgb.Get32(buf[b:]) + b += 4 + + v.MscHi = xgb.Get32(buf[b:]) + b += 4 + + v.MscLo = xgb.Get32(buf[b:]) + b += 4 + + v.Sbc = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Bytes writes a BufferSwapCompleteEvent value to a byte slice. +func (v BufferSwapCompleteEvent) 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.Put16(buf[b:], v.EventType) + b += 2 + + b += 2 // padding + + xgb.Put32(buf[b:], uint32(v.Drawable)) + b += 4 + + xgb.Put32(buf[b:], v.UstHi) + b += 4 + + xgb.Put32(buf[b:], v.UstLo) + b += 4 + + xgb.Put32(buf[b:], v.MscHi) + b += 4 + + xgb.Put32(buf[b:], v.MscLo) + b += 4 + + xgb.Put32(buf[b:], v.Sbc) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the BufferSwapComplete event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v BufferSwapCompleteEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of BufferSwapCompleteEvent. +func (v BufferSwapCompleteEvent) String() string { + fieldVals := make([]string, 0, 9) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("EventType: %d", v.EventType)) + fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable)) + fieldVals = append(fieldVals, xgb.Sprintf("UstHi: %d", v.UstHi)) + fieldVals = append(fieldVals, xgb.Sprintf("UstLo: %d", v.UstLo)) + fieldVals = append(fieldVals, xgb.Sprintf("MscHi: %d", v.MscHi)) + fieldVals = append(fieldVals, xgb.Sprintf("MscLo: %d", v.MscLo)) + fieldVals = append(fieldVals, xgb.Sprintf("Sbc: %d", v.Sbc)) + return "BufferSwapComplete {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["DRI2"][0] = BufferSwapCompleteEventNew +} + +type DRI2Buffer struct { + Attachment uint32 + Name uint32 + Pitch uint32 + Cpp uint32 + Flags uint32 +} + +// DRI2BufferRead reads a byte slice into a DRI2Buffer value. +func DRI2BufferRead(buf []byte, v *DRI2Buffer) int { + b := 0 + + v.Attachment = xgb.Get32(buf[b:]) + b += 4 + + v.Name = xgb.Get32(buf[b:]) + b += 4 + + v.Pitch = xgb.Get32(buf[b:]) + b += 4 + + v.Cpp = xgb.Get32(buf[b:]) + b += 4 + + v.Flags = xgb.Get32(buf[b:]) + b += 4 + + return b +} + +// DRI2BufferReadList reads a byte slice into a list of DRI2Buffer values. +func DRI2BufferReadList(buf []byte, dest []DRI2Buffer) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = DRI2Buffer{} + b += DRI2BufferRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a DRI2Buffer value to a byte slice. +func (v DRI2Buffer) Bytes() []byte { + buf := make([]byte, 20) + b := 0 + + xgb.Put32(buf[b:], v.Attachment) + b += 4 + + xgb.Put32(buf[b:], v.Name) + b += 4 + + xgb.Put32(buf[b:], v.Pitch) + b += 4 + + xgb.Put32(buf[b:], v.Cpp) + b += 4 + + xgb.Put32(buf[b:], v.Flags) + b += 4 + + return buf[:b] +} + +// DRI2BufferListBytes writes a list of DRI2Buffer values to a byte slice. +func DRI2BufferListBytes(buf []byte, list []DRI2Buffer) 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 ( + DriverTypeDri = 0 + DriverTypeVdpau = 1 +) + +const ( + EventTypeExchangeComplete = 1 + EventTypeBlitComplete = 2 + EventTypeFlipComplete = 3 +) + +// InvalidateBuffers is the event number for a InvalidateBuffersEvent. +const InvalidateBuffers = 1 + +type InvalidateBuffersEvent struct { + Sequence uint16 + // padding: 1 bytes + Drawable xproto.Drawable +} + +// InvalidateBuffersEventNew constructs a InvalidateBuffersEvent value that implements xgb.Event from a byte slice. +func InvalidateBuffersEventNew(buf []byte) xgb.Event { + v := InvalidateBuffersEvent{} + 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 + + return v +} + +// Bytes writes a InvalidateBuffersEvent value to a byte slice. +func (v InvalidateBuffersEvent) 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.Drawable)) + b += 4 + + return buf +} + +// SequenceId returns the sequence id attached to the InvalidateBuffers event. +// Events without a sequence number (KeymapNotify) return 0. +// This is mostly used internally. +func (v InvalidateBuffersEvent) SequenceId() uint16 { + return v.Sequence +} + +// String is a rudimentary string representation of InvalidateBuffersEvent. +func (v InvalidateBuffersEvent) String() string { + fieldVals := make([]string, 0, 2) + fieldVals = append(fieldVals, xgb.Sprintf("Sequence: %d", v.Sequence)) + fieldVals = append(fieldVals, xgb.Sprintf("Drawable: %d", v.Drawable)) + return "InvalidateBuffers {" + xgb.StringsJoin(fieldVals, ", ") + "}" +} + +func init() { + xgb.NewExtEventFuncs["DRI2"][1] = InvalidateBuffersEventNew +} + +// 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' + +// AuthenticateCookie is a cookie used only for Authenticate requests. +type AuthenticateCookie struct { + *xgb.Cookie +} + +// Authenticate sends a checked request. +// If an error occurs, it will be returned with the reply by calling AuthenticateCookie.Reply() +func Authenticate(c *xgb.Conn, Window xproto.Window, Magic uint32) AuthenticateCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'Authenticate' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(authenticateRequest(c, Window, Magic), cookie) + return AuthenticateCookie{cookie} +} + +// AuthenticateUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func AuthenticateUnchecked(c *xgb.Conn, Window xproto.Window, Magic uint32) AuthenticateCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'Authenticate' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(authenticateRequest(c, Window, Magic), cookie) + return AuthenticateCookie{cookie} +} + +// AuthenticateReply represents the data returned from a Authenticate request. +type AuthenticateReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Authenticated uint32 +} + +// Reply blocks and returns the reply data for a Authenticate request. +func (cook AuthenticateCookie) Reply() (*AuthenticateReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return authenticateReply(buf), nil +} + +// authenticateReply reads a byte slice into a AuthenticateReply value. +func authenticateReply(buf []byte) *AuthenticateReply { + v := new(AuthenticateReply) + 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.Authenticated = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for Authenticate +// authenticateRequest writes a Authenticate request to a byte slice. +func authenticateRequest(c *xgb.Conn, Window xproto.Window, Magic uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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(Window)) + b += 4 + + xgb.Put32(buf[b:], Magic) + b += 4 + + return buf +} + +// ConnectCookie is a cookie used only for Connect requests. +type ConnectCookie struct { + *xgb.Cookie +} + +// Connect sends a checked request. +// If an error occurs, it will be returned with the reply by calling ConnectCookie.Reply() +func Connect(c *xgb.Conn, Window xproto.Window, DriverType uint32) ConnectCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'Connect' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(connectRequest(c, Window, DriverType), cookie) + return ConnectCookie{cookie} +} + +// ConnectUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func ConnectUnchecked(c *xgb.Conn, Window xproto.Window, DriverType uint32) ConnectCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'Connect' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(connectRequest(c, Window, DriverType), cookie) + return ConnectCookie{cookie} +} + +// ConnectReply represents the data returned from a Connect request. +type ConnectReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + DriverNameLength uint32 + DeviceNameLength uint32 + // padding: 16 bytes + DriverName string // size: xgb.Pad((int(DriverNameLength) * 1)) + AlignmentPad []byte // size: xgb.Pad(((((int(DriverNameLength) + 3) & -4) - int(DriverNameLength)) * 1)) + DeviceName string // size: xgb.Pad((int(DeviceNameLength) * 1)) +} + +// Reply blocks and returns the reply data for a Connect request. +func (cook ConnectCookie) Reply() (*ConnectReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return connectReply(buf), nil +} + +// connectReply reads a byte slice into a ConnectReply value. +func connectReply(buf []byte) *ConnectReply { + v := new(ConnectReply) + 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.DriverNameLength = xgb.Get32(buf[b:]) + b += 4 + + v.DeviceNameLength = xgb.Get32(buf[b:]) + b += 4 + + b += 16 // padding + + { + byteString := make([]byte, v.DriverNameLength) + copy(byteString[:v.DriverNameLength], buf[b:]) + v.DriverName = string(byteString) + b += int(v.DriverNameLength) + } + + v.AlignmentPad = make([]byte, (((int(v.DriverNameLength) + 3) & -4) - int(v.DriverNameLength))) + copy(v.AlignmentPad[:(((int(v.DriverNameLength)+3)&-4)-int(v.DriverNameLength))], buf[b:]) + b += int((((int(v.DriverNameLength) + 3) & -4) - int(v.DriverNameLength))) + + { + byteString := make([]byte, v.DeviceNameLength) + copy(byteString[:v.DeviceNameLength], buf[b:]) + v.DeviceName = string(byteString) + b += int(v.DeviceNameLength) + } + + return v +} + +// Write request to wire for Connect +// connectRequest writes a Connect request to a byte slice. +func connectRequest(c *xgb.Conn, Window xproto.Window, DriverType uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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 + + xgb.Put32(buf[b:], DriverType) + b += 4 + + return buf +} + +// CopyRegionCookie is a cookie used only for CopyRegion requests. +type CopyRegionCookie struct { + *xgb.Cookie +} + +// CopyRegion sends a checked request. +// If an error occurs, it will be returned with the reply by calling CopyRegionCookie.Reply() +func CopyRegion(c *xgb.Conn, Drawable xproto.Drawable, Region uint32, Dest uint32, Src uint32) CopyRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'CopyRegion' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(copyRegionRequest(c, Drawable, Region, Dest, Src), cookie) + return CopyRegionCookie{cookie} +} + +// CopyRegionUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CopyRegionUnchecked(c *xgb.Conn, Drawable xproto.Drawable, Region uint32, Dest uint32, Src uint32) CopyRegionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'CopyRegion' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(copyRegionRequest(c, Drawable, Region, Dest, Src), cookie) + return CopyRegionCookie{cookie} +} + +// CopyRegionReply represents the data returned from a CopyRegion request. +type CopyRegionReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes +} + +// Reply blocks and returns the reply data for a CopyRegion request. +func (cook CopyRegionCookie) Reply() (*CopyRegionReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return copyRegionReply(buf), nil +} + +// copyRegionReply reads a byte slice into a CopyRegionReply value. +func copyRegionReply(buf []byte) *CopyRegionReply { + v := new(CopyRegionReply) + 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 + + return v +} + +// Write request to wire for CopyRegion +// copyRegionRequest writes a CopyRegion request to a byte slice. +func copyRegionRequest(c *xgb.Conn, Drawable xproto.Drawable, Region uint32, Dest uint32, Src uint32) []byte { + size := 20 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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(Drawable)) + b += 4 + + xgb.Put32(buf[b:], Region) + b += 4 + + xgb.Put32(buf[b:], Dest) + b += 4 + + xgb.Put32(buf[b:], Src) + b += 4 + + return buf +} + +// CreateDrawableCookie is a cookie used only for CreateDrawable requests. +type CreateDrawableCookie struct { + *xgb.Cookie +} + +// CreateDrawable sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateDrawable(c *xgb.Conn, Drawable xproto.Drawable) CreateDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'CreateDrawable' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(createDrawableRequest(c, Drawable), cookie) + return CreateDrawableCookie{cookie} +} + +// CreateDrawableChecked sends a checked request. +// If an error occurs, it can be retrieved using CreateDrawableCookie.Check() +func CreateDrawableChecked(c *xgb.Conn, Drawable xproto.Drawable) CreateDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'CreateDrawable' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(createDrawableRequest(c, Drawable), cookie) + return CreateDrawableCookie{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 CreateDrawableCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for CreateDrawable +// createDrawableRequest writes a CreateDrawable request to a byte slice. +func createDrawableRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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(Drawable)) + b += 4 + + return buf +} + +// DestroyDrawableCookie is a cookie used only for DestroyDrawable requests. +type DestroyDrawableCookie struct { + *xgb.Cookie +} + +// DestroyDrawable sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func DestroyDrawable(c *xgb.Conn, Drawable xproto.Drawable) DestroyDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'DestroyDrawable' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(destroyDrawableRequest(c, Drawable), cookie) + return DestroyDrawableCookie{cookie} +} + +// DestroyDrawableChecked sends a checked request. +// If an error occurs, it can be retrieved using DestroyDrawableCookie.Check() +func DestroyDrawableChecked(c *xgb.Conn, Drawable xproto.Drawable) DestroyDrawableCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'DestroyDrawable' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(destroyDrawableRequest(c, Drawable), cookie) + return DestroyDrawableCookie{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 DestroyDrawableCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for DestroyDrawable +// destroyDrawableRequest writes a DestroyDrawable request to a byte slice. +func destroyDrawableRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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(Drawable)) + b += 4 + + return buf +} + +// GetBuffersCookie is a cookie used only for GetBuffers requests. +type GetBuffersCookie struct { + *xgb.Cookie +} + +// GetBuffers sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetBuffersCookie.Reply() +func GetBuffers(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []uint32) GetBuffersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetBuffers' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getBuffersRequest(c, Drawable, Count, Attachments), cookie) + return GetBuffersCookie{cookie} +} + +// GetBuffersUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetBuffersUnchecked(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []uint32) GetBuffersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetBuffers' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getBuffersRequest(c, Drawable, Count, Attachments), cookie) + return GetBuffersCookie{cookie} +} + +// GetBuffersReply represents the data returned from a GetBuffers request. +type GetBuffersReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Width uint32 + Height uint32 + Count uint32 + // padding: 12 bytes + Buffers []DRI2Buffer // size: xgb.Pad((int(Count) * 20)) +} + +// Reply blocks and returns the reply data for a GetBuffers request. +func (cook GetBuffersCookie) Reply() (*GetBuffersReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getBuffersReply(buf), nil +} + +// getBuffersReply reads a byte slice into a GetBuffersReply value. +func getBuffersReply(buf []byte) *GetBuffersReply { + v := new(GetBuffersReply) + 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.Get32(buf[b:]) + b += 4 + + v.Height = xgb.Get32(buf[b:]) + b += 4 + + v.Count = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Buffers = make([]DRI2Buffer, v.Count) + b += DRI2BufferReadList(buf[b:], v.Buffers) + + return v +} + +// Write request to wire for GetBuffers +// getBuffersRequest writes a GetBuffers request to a byte slice. +func getBuffersRequest(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []uint32) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Attachments) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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(Drawable)) + b += 4 + + xgb.Put32(buf[b:], Count) + b += 4 + + for i := 0; i < int(len(Attachments)); i++ { + xgb.Put32(buf[b:], Attachments[i]) + b += 4 + } + + return buf +} + +// GetBuffersWithFormatCookie is a cookie used only for GetBuffersWithFormat requests. +type GetBuffersWithFormatCookie struct { + *xgb.Cookie +} + +// GetBuffersWithFormat sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetBuffersWithFormatCookie.Reply() +func GetBuffersWithFormat(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []AttachFormat) GetBuffersWithFormatCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetBuffersWithFormat' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getBuffersWithFormatRequest(c, Drawable, Count, Attachments), cookie) + return GetBuffersWithFormatCookie{cookie} +} + +// GetBuffersWithFormatUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetBuffersWithFormatUnchecked(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []AttachFormat) GetBuffersWithFormatCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetBuffersWithFormat' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getBuffersWithFormatRequest(c, Drawable, Count, Attachments), cookie) + return GetBuffersWithFormatCookie{cookie} +} + +// GetBuffersWithFormatReply represents the data returned from a GetBuffersWithFormat request. +type GetBuffersWithFormatReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + Width uint32 + Height uint32 + Count uint32 + // padding: 12 bytes + Buffers []DRI2Buffer // size: xgb.Pad((int(Count) * 20)) +} + +// Reply blocks and returns the reply data for a GetBuffersWithFormat request. +func (cook GetBuffersWithFormatCookie) Reply() (*GetBuffersWithFormatReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getBuffersWithFormatReply(buf), nil +} + +// getBuffersWithFormatReply reads a byte slice into a GetBuffersWithFormatReply value. +func getBuffersWithFormatReply(buf []byte) *GetBuffersWithFormatReply { + v := new(GetBuffersWithFormatReply) + 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.Get32(buf[b:]) + b += 4 + + v.Height = xgb.Get32(buf[b:]) + b += 4 + + v.Count = xgb.Get32(buf[b:]) + b += 4 + + b += 12 // padding + + v.Buffers = make([]DRI2Buffer, v.Count) + b += DRI2BufferReadList(buf[b:], v.Buffers) + + return v +} + +// Write request to wire for GetBuffersWithFormat +// getBuffersWithFormatRequest writes a GetBuffersWithFormat request to a byte slice. +func getBuffersWithFormatRequest(c *xgb.Conn, Drawable xproto.Drawable, Count uint32, Attachments []AttachFormat) []byte { + size := xgb.Pad((12 + xgb.Pad((len(Attachments) * 8)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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(Drawable)) + b += 4 + + xgb.Put32(buf[b:], Count) + b += 4 + + b += AttachFormatListBytes(buf[b:], Attachments) + + return buf +} + +// GetMSCCookie is a cookie used only for GetMSC requests. +type GetMSCCookie struct { + *xgb.Cookie +} + +// GetMSC sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetMSCCookie.Reply() +func GetMSC(c *xgb.Conn, Drawable xproto.Drawable) GetMSCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetMSC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getMSCRequest(c, Drawable), cookie) + return GetMSCCookie{cookie} +} + +// GetMSCUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetMSCUnchecked(c *xgb.Conn, Drawable xproto.Drawable) GetMSCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetMSC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getMSCRequest(c, Drawable), cookie) + return GetMSCCookie{cookie} +} + +// GetMSCReply represents the data returned from a GetMSC request. +type GetMSCReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + UstHi uint32 + UstLo uint32 + MscHi uint32 + MscLo uint32 + SbcHi uint32 + SbcLo uint32 +} + +// Reply blocks and returns the reply data for a GetMSC request. +func (cook GetMSCCookie) Reply() (*GetMSCReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getMSCReply(buf), nil +} + +// getMSCReply reads a byte slice into a GetMSCReply value. +func getMSCReply(buf []byte) *GetMSCReply { + v := new(GetMSCReply) + 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.UstHi = xgb.Get32(buf[b:]) + b += 4 + + v.UstLo = xgb.Get32(buf[b:]) + b += 4 + + v.MscHi = xgb.Get32(buf[b:]) + b += 4 + + v.MscLo = xgb.Get32(buf[b:]) + b += 4 + + v.SbcHi = xgb.Get32(buf[b:]) + b += 4 + + v.SbcLo = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for GetMSC +// getMSCRequest writes a GetMSC request to a byte slice. +func getMSCRequest(c *xgb.Conn, Drawable xproto.Drawable) []byte { + size := 8 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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(Drawable)) + b += 4 + + return buf +} + +// GetParamCookie is a cookie used only for GetParam requests. +type GetParamCookie struct { + *xgb.Cookie +} + +// GetParam sends a checked request. +// If an error occurs, it will be returned with the reply by calling GetParamCookie.Reply() +func GetParam(c *xgb.Conn, Drawable xproto.Drawable, Param uint32) GetParamCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetParam' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(getParamRequest(c, Drawable, Param), cookie) + return GetParamCookie{cookie} +} + +// GetParamUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func GetParamUnchecked(c *xgb.Conn, Drawable xproto.Drawable, Param uint32) GetParamCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'GetParam' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(getParamRequest(c, Drawable, Param), cookie) + return GetParamCookie{cookie} +} + +// GetParamReply represents the data returned from a GetParam request. +type GetParamReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + IsParamRecognized bool + ValueHi uint32 + ValueLo uint32 +} + +// Reply blocks and returns the reply data for a GetParam request. +func (cook GetParamCookie) Reply() (*GetParamReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return getParamReply(buf), nil +} + +// getParamReply reads a byte slice into a GetParamReply value. +func getParamReply(buf []byte) *GetParamReply { + v := new(GetParamReply) + b := 1 // skip reply determinant + + if buf[b] == 1 { + v.IsParamRecognized = true + } else { + v.IsParamRecognized = false + } + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + v.ValueHi = xgb.Get32(buf[b:]) + b += 4 + + v.ValueLo = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for GetParam +// getParamRequest writes a GetParam request to a byte slice. +func getParamRequest(c *xgb.Conn, Drawable xproto.Drawable, Param uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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(Drawable)) + b += 4 + + xgb.Put32(buf[b:], Param) + 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, MajorVersion uint32, MinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(queryVersionRequest(c, MajorVersion, MinorVersion), 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, MajorVersion uint32, MinorVersion uint32) QueryVersionCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'QueryVersion' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(queryVersionRequest(c, MajorVersion, MinorVersion), 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 +} + +// 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 + + return v +} + +// Write request to wire for QueryVersion +// queryVersionRequest writes a QueryVersion request to a byte slice. +func queryVersionRequest(c *xgb.Conn, MajorVersion uint32, MinorVersion uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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 + + xgb.Put32(buf[b:], MajorVersion) + b += 4 + + xgb.Put32(buf[b:], MinorVersion) + b += 4 + + return buf +} + +// SwapBuffersCookie is a cookie used only for SwapBuffers requests. +type SwapBuffersCookie struct { + *xgb.Cookie +} + +// SwapBuffers sends a checked request. +// If an error occurs, it will be returned with the reply by calling SwapBuffersCookie.Reply() +func SwapBuffers(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) SwapBuffersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'SwapBuffers' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(swapBuffersRequest(c, Drawable, TargetMscHi, TargetMscLo, DivisorHi, DivisorLo, RemainderHi, RemainderLo), cookie) + return SwapBuffersCookie{cookie} +} + +// SwapBuffersUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SwapBuffersUnchecked(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) SwapBuffersCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'SwapBuffers' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(swapBuffersRequest(c, Drawable, TargetMscHi, TargetMscLo, DivisorHi, DivisorLo, RemainderHi, RemainderLo), cookie) + return SwapBuffersCookie{cookie} +} + +// SwapBuffersReply represents the data returned from a SwapBuffers request. +type SwapBuffersReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + SwapHi uint32 + SwapLo uint32 +} + +// Reply blocks and returns the reply data for a SwapBuffers request. +func (cook SwapBuffersCookie) Reply() (*SwapBuffersReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return swapBuffersReply(buf), nil +} + +// swapBuffersReply reads a byte slice into a SwapBuffersReply value. +func swapBuffersReply(buf []byte) *SwapBuffersReply { + v := new(SwapBuffersReply) + 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.SwapHi = xgb.Get32(buf[b:]) + b += 4 + + v.SwapLo = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for SwapBuffers +// swapBuffersRequest writes a SwapBuffers request to a byte slice. +func swapBuffersRequest(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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(Drawable)) + b += 4 + + xgb.Put32(buf[b:], TargetMscHi) + b += 4 + + xgb.Put32(buf[b:], TargetMscLo) + b += 4 + + xgb.Put32(buf[b:], DivisorHi) + b += 4 + + xgb.Put32(buf[b:], DivisorLo) + b += 4 + + xgb.Put32(buf[b:], RemainderHi) + b += 4 + + xgb.Put32(buf[b:], RemainderLo) + b += 4 + + return buf +} + +// SwapIntervalCookie is a cookie used only for SwapInterval requests. +type SwapIntervalCookie struct { + *xgb.Cookie +} + +// SwapInterval sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func SwapInterval(c *xgb.Conn, Drawable xproto.Drawable, Interval uint32) SwapIntervalCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'SwapInterval' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(swapIntervalRequest(c, Drawable, Interval), cookie) + return SwapIntervalCookie{cookie} +} + +// SwapIntervalChecked sends a checked request. +// If an error occurs, it can be retrieved using SwapIntervalCookie.Check() +func SwapIntervalChecked(c *xgb.Conn, Drawable xproto.Drawable, Interval uint32) SwapIntervalCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'SwapInterval' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(swapIntervalRequest(c, Drawable, Interval), cookie) + return SwapIntervalCookie{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 SwapIntervalCookie) Check() error { + return cook.Cookie.Check() +} + +// Write request to wire for SwapInterval +// swapIntervalRequest writes a SwapInterval request to a byte slice. +func swapIntervalRequest(c *xgb.Conn, Drawable xproto.Drawable, Interval uint32) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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(Drawable)) + b += 4 + + xgb.Put32(buf[b:], Interval) + b += 4 + + return buf +} + +// WaitMSCCookie is a cookie used only for WaitMSC requests. +type WaitMSCCookie struct { + *xgb.Cookie +} + +// WaitMSC sends a checked request. +// If an error occurs, it will be returned with the reply by calling WaitMSCCookie.Reply() +func WaitMSC(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) WaitMSCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'WaitMSC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(waitMSCRequest(c, Drawable, TargetMscHi, TargetMscLo, DivisorHi, DivisorLo, RemainderHi, RemainderLo), cookie) + return WaitMSCCookie{cookie} +} + +// WaitMSCUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func WaitMSCUnchecked(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) WaitMSCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'WaitMSC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(waitMSCRequest(c, Drawable, TargetMscHi, TargetMscLo, DivisorHi, DivisorLo, RemainderHi, RemainderLo), cookie) + return WaitMSCCookie{cookie} +} + +// WaitMSCReply represents the data returned from a WaitMSC request. +type WaitMSCReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + UstHi uint32 + UstLo uint32 + MscHi uint32 + MscLo uint32 + SbcHi uint32 + SbcLo uint32 +} + +// Reply blocks and returns the reply data for a WaitMSC request. +func (cook WaitMSCCookie) Reply() (*WaitMSCReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return waitMSCReply(buf), nil +} + +// waitMSCReply reads a byte slice into a WaitMSCReply value. +func waitMSCReply(buf []byte) *WaitMSCReply { + v := new(WaitMSCReply) + 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.UstHi = xgb.Get32(buf[b:]) + b += 4 + + v.UstLo = xgb.Get32(buf[b:]) + b += 4 + + v.MscHi = xgb.Get32(buf[b:]) + b += 4 + + v.MscLo = xgb.Get32(buf[b:]) + b += 4 + + v.SbcHi = xgb.Get32(buf[b:]) + b += 4 + + v.SbcLo = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for WaitMSC +// waitMSCRequest writes a WaitMSC request to a byte slice. +func waitMSCRequest(c *xgb.Conn, Drawable xproto.Drawable, TargetMscHi uint32, TargetMscLo uint32, DivisorHi uint32, DivisorLo uint32, RemainderHi uint32, RemainderLo uint32) []byte { + size := 32 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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 + + xgb.Put32(buf[b:], TargetMscHi) + b += 4 + + xgb.Put32(buf[b:], TargetMscLo) + b += 4 + + xgb.Put32(buf[b:], DivisorHi) + b += 4 + + xgb.Put32(buf[b:], DivisorLo) + b += 4 + + xgb.Put32(buf[b:], RemainderHi) + b += 4 + + xgb.Put32(buf[b:], RemainderLo) + b += 4 + + return buf +} + +// WaitSBCCookie is a cookie used only for WaitSBC requests. +type WaitSBCCookie struct { + *xgb.Cookie +} + +// WaitSBC sends a checked request. +// If an error occurs, it will be returned with the reply by calling WaitSBCCookie.Reply() +func WaitSBC(c *xgb.Conn, Drawable xproto.Drawable, TargetSbcHi uint32, TargetSbcLo uint32) WaitSBCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'WaitSBC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(waitSBCRequest(c, Drawable, TargetSbcHi, TargetSbcLo), cookie) + return WaitSBCCookie{cookie} +} + +// WaitSBCUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func WaitSBCUnchecked(c *xgb.Conn, Drawable xproto.Drawable, TargetSbcHi uint32, TargetSbcLo uint32) WaitSBCCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["DRI2"]; !ok { + panic("Cannot issue request 'WaitSBC' using the uninitialized extension 'DRI2'. dri2.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(waitSBCRequest(c, Drawable, TargetSbcHi, TargetSbcLo), cookie) + return WaitSBCCookie{cookie} +} + +// WaitSBCReply represents the data returned from a WaitSBC request. +type WaitSBCReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + // padding: 1 bytes + UstHi uint32 + UstLo uint32 + MscHi uint32 + MscLo uint32 + SbcHi uint32 + SbcLo uint32 +} + +// Reply blocks and returns the reply data for a WaitSBC request. +func (cook WaitSBCCookie) Reply() (*WaitSBCReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return waitSBCReply(buf), nil +} + +// waitSBCReply reads a byte slice into a WaitSBCReply value. +func waitSBCReply(buf []byte) *WaitSBCReply { + v := new(WaitSBCReply) + 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.UstHi = xgb.Get32(buf[b:]) + b += 4 + + v.UstLo = xgb.Get32(buf[b:]) + b += 4 + + v.MscHi = xgb.Get32(buf[b:]) + b += 4 + + v.MscLo = xgb.Get32(buf[b:]) + b += 4 + + v.SbcHi = xgb.Get32(buf[b:]) + b += 4 + + v.SbcLo = xgb.Get32(buf[b:]) + b += 4 + + return v +} + +// Write request to wire for WaitSBC +// waitSBCRequest writes a WaitSBC request to a byte slice. +func waitSBCRequest(c *xgb.Conn, Drawable xproto.Drawable, TargetSbcHi uint32, TargetSbcLo uint32) []byte { + size := 16 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["DRI2"] + 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(Drawable)) + b += 4 + + xgb.Put32(buf[b:], TargetSbcHi) + b += 4 + + xgb.Put32(buf[b:], TargetSbcLo) + b += 4 + + return buf +} |