diff options
author | Přemysl Janouch <p@janouch.name> | 2018-09-08 16:54:17 +0200 |
---|---|---|
committer | Přemysl Janouch <p@janouch.name> | 2018-09-08 16:54:17 +0200 |
commit | 3173202cc1e08762c6e156a8fffd23269a5ddb2b (patch) | |
tree | 95c4a06f8384d41b15e9c22afac0a387de79dc51 /nexgb/dri2 | |
parent | 632b3ae494d45755525644fe5d04475c95aae364 (diff) | |
parent | 3906399e7c2a40fbaf355de572cf50a314083f64 (diff) | |
download | haven-3173202cc1e08762c6e156a8fffd23269a5ddb2b.tar.gz haven-3173202cc1e08762c6e156a8fffd23269a5ddb2b.tar.xz haven-3173202cc1e08762c6e156a8fffd23269a5ddb2b.zip |
Merge aarzilli/xgb, branch xcb1.12 as nexgb
History has been linearized and rewritten to stay under the new
subdirectory. I want to make changes incompatible to BurntSushi/xgb.
The history begs for being thrown away entirely because of its quality
and because it doesn't cover the Google period but it is still useful
for copyright tracking.
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 +} |