From 139c50b7488ee2277be7d9b0eee8d807af628932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Sun, 30 Sep 2018 16:46:08 +0200 Subject: nexgb: update to xcb-proto 1.13 --- nexgb/randr/randr.go | 339 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 338 insertions(+), 1 deletion(-) (limited to 'nexgb/randr/randr.go') diff --git a/nexgb/randr/randr.go b/nexgb/randr/randr.go index 9570434..99cf4f0 100644 --- a/nexgb/randr/randr.go +++ b/nexgb/randr/randr.go @@ -12,7 +12,7 @@ import ( const ( MajorVersion = 1 - MinorVersion = 5 + MinorVersion = 6 ) // Init must be called before using the RANDR extension. @@ -350,6 +350,89 @@ func CrtcChangeListBytes(buf []byte, list []CrtcChange) int { return xgb.Pad(b) } +type Lease uint32 + +func NewLeaseId(c *xgb.Conn) (Lease, error) { + id, err := c.NewId() + if err != nil { + return 0, err + } + return Lease(id), nil +} + +type LeaseNotify struct { + Timestamp xproto.Timestamp + Window xproto.Window + Lease Lease + Created byte + // padding: 15 bytes +} + +// LeaseNotifyRead reads a byte slice into a LeaseNotify value. +func LeaseNotifyRead(buf []byte, v *LeaseNotify) int { + b := 0 + + v.Timestamp = xproto.Timestamp(xgb.Get32(buf[b:])) + b += 4 + + v.Window = xproto.Window(xgb.Get32(buf[b:])) + b += 4 + + v.Lease = Lease(xgb.Get32(buf[b:])) + b += 4 + + v.Created = buf[b] + b += 1 + + b += 15 // padding + + return b +} + +// LeaseNotifyReadList reads a byte slice into a list of LeaseNotify values. +func LeaseNotifyReadList(buf []byte, dest []LeaseNotify) int { + b := 0 + for i := 0; i < len(dest); i++ { + dest[i] = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &dest[i]) + } + return xgb.Pad(b) +} + +// Bytes writes a LeaseNotify value to a byte slice. +func (v LeaseNotify) Bytes() []byte { + buf := make([]byte, 28) + b := 0 + + xgb.Put32(buf[b:], uint32(v.Timestamp)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Window)) + b += 4 + + xgb.Put32(buf[b:], uint32(v.Lease)) + b += 4 + + buf[b] = v.Created + b += 1 + + b += 15 // padding + + return buf[:b] +} + +// LeaseNotifyListBytes writes a list of LeaseNotify values to a byte slice. +func LeaseNotifyListBytes(buf []byte, list []LeaseNotify) int { + b := 0 + var structBytes []byte + for _, item := range list { + structBytes = item.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + return xgb.Pad(b) +} + type Mode uint32 func NewModeId(c *xgb.Conn) (Mode, error) { @@ -662,6 +745,7 @@ const ( NotifyProviderChange = 3 NotifyProviderProperty = 4 NotifyResourceChange = 5 + NotifyLease = 6 ) // Notify is the event number for a NotifyEvent. @@ -742,6 +826,7 @@ func init() { // NotifyDataUnionPcNew(Pc ProviderChange) NotifyDataUnion // NotifyDataUnionPpNew(Pp ProviderProperty) NotifyDataUnion // NotifyDataUnionRcNew(Rc ResourceChange) NotifyDataUnion +// NotifyDataUnionLcNew(Lc LeaseNotify) NotifyDataUnion type NotifyDataUnion struct { Cc CrtcChange Oc OutputChange @@ -749,6 +834,7 @@ type NotifyDataUnion struct { Pc ProviderChange Pp ProviderProperty Rc ResourceChange + Lc LeaseNotify } // NotifyDataUnionCcNew constructs a new NotifyDataUnion union type with the Cc field. @@ -791,6 +877,10 @@ func NotifyDataUnionCcNew(Cc CrtcChange) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -834,6 +924,10 @@ func NotifyDataUnionOcNew(Oc OutputChange) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -877,6 +971,10 @@ func NotifyDataUnionOpNew(Op OutputProperty) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -920,6 +1018,10 @@ func NotifyDataUnionPcNew(Pc ProviderChange) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -963,6 +1065,10 @@ func NotifyDataUnionPpNew(Pp ProviderProperty) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -1006,6 +1112,57 @@ func NotifyDataUnionRcNew(Rc ResourceChange) NotifyDataUnion { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + + return v +} + +// NotifyDataUnionLcNew constructs a new NotifyDataUnion union type with the Lc field. +func NotifyDataUnionLcNew(Lc LeaseNotify) NotifyDataUnion { + var b int + buf := make([]byte, 28) + + { + structBytes := Lc.Bytes() + copy(buf[b:], structBytes) + b += len(structBytes) + } + + // Create the Union type + v := NotifyDataUnion{} + + // Now copy buf into all fields + + b = 0 // always read the same bytes + v.Cc = CrtcChange{} + b += CrtcChangeRead(buf[b:], &v.Cc) + + b = 0 // always read the same bytes + v.Oc = OutputChange{} + b += OutputChangeRead(buf[b:], &v.Oc) + + b = 0 // always read the same bytes + v.Op = OutputProperty{} + b += OutputPropertyRead(buf[b:], &v.Op) + + b = 0 // always read the same bytes + v.Pc = ProviderChange{} + b += ProviderChangeRead(buf[b:], &v.Pc) + + b = 0 // always read the same bytes + v.Pp = ProviderProperty{} + b += ProviderPropertyRead(buf[b:], &v.Pp) + + b = 0 // always read the same bytes + v.Rc = ResourceChange{} + b += ResourceChangeRead(buf[b:], &v.Rc) + + b = 0 // always read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return v } @@ -1037,6 +1194,10 @@ func NotifyDataUnionRead(buf []byte, v *NotifyDataUnion) int { v.Rc = ResourceChange{} b += ResourceChangeRead(buf[b:], &v.Rc) + b = 0 // re-read the same bytes + v.Lc = LeaseNotify{} + b += LeaseNotifyRead(buf[b:], &v.Lc) + return 28 } @@ -1085,6 +1246,7 @@ const ( NotifyMaskProviderChange = 16 NotifyMaskProviderProperty = 32 NotifyMaskResourceChange = 64 + NotifyMaskLease = 128 ) type Output uint32 @@ -2214,6 +2376,118 @@ func configureProviderPropertyRequest(c *xgb.Conn, Provider Provider, Property x return buf } +// CreateLeaseCookie is a cookie used only for CreateLease requests. +type CreateLeaseCookie struct { + *xgb.Cookie +} + +// CreateLease sends a checked request. +// If an error occurs, it will be returned with the reply by calling CreateLeaseCookie.Reply. +func CreateLease(c *xgb.Conn, Window xproto.Window, Lid Lease, NumCrtcs, NumOutputs uint16, Crtcs []Crtc, Outputs []Output) CreateLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'CreateLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, true) + c.NewRequest(createLeaseRequest(c, Window, Lid, NumCrtcs, NumOutputs, Crtcs, Outputs), cookie) + return CreateLeaseCookie{cookie} +} + +// CreateLeaseUnchecked sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func CreateLeaseUnchecked(c *xgb.Conn, Window xproto.Window, Lid Lease, NumCrtcs, NumOutputs uint16, Crtcs []Crtc, Outputs []Output) CreateLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'CreateLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, true) + c.NewRequest(createLeaseRequest(c, Window, Lid, NumCrtcs, NumOutputs, Crtcs, Outputs), cookie) + return CreateLeaseCookie{cookie} +} + +// CreateLeaseReply represents the data returned from a CreateLease request. +type CreateLeaseReply struct { + Sequence uint16 // sequence number of the request for this reply + Length uint32 // number of bytes in this reply + Nfd byte + // padding: 24 bytes +} + +// Reply blocks and returns the reply data for a CreateLease request. +func (cook CreateLeaseCookie) Reply() (*CreateLeaseReply, error) { + buf, err := cook.Cookie.Reply() + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return createLeaseReply(buf), nil +} + +// createLeaseReply reads a byte slice into a CreateLeaseReply value. +func createLeaseReply(buf []byte) *CreateLeaseReply { + v := new(CreateLeaseReply) + b := 1 // skip reply determinant + + v.Nfd = buf[b] + b += 1 + + v.Sequence = xgb.Get16(buf[b:]) + b += 2 + + v.Length = xgb.Get32(buf[b:]) // 4-byte units + b += 4 + + b += 24 // padding + + return v +} + +// createLeaseRequest writes a CreateLease request to a byte slice for transfer. +func createLeaseRequest(c *xgb.Conn, Window xproto.Window, Lid Lease, NumCrtcs, NumOutputs uint16, Crtcs []Crtc, Outputs []Output) []byte { + size := xgb.Pad(((16 + xgb.Pad((int(NumCrtcs) * 4))) + xgb.Pad((int(NumOutputs) * 4)))) + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 45 // 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:], uint32(Lid)) + b += 4 + + xgb.Put16(buf[b:], NumCrtcs) + b += 2 + + xgb.Put16(buf[b:], NumOutputs) + b += 2 + + for i := 0; i < int(NumCrtcs); i++ { + xgb.Put32(buf[b:], uint32(Crtcs[i])) + b += 4 + } + + for i := 0; i < int(NumOutputs); i++ { + xgb.Put32(buf[b:], uint32(Outputs[i])) + b += 4 + } + + return buf +} + // CreateModeCookie is a cookie used only for CreateMode requests. type CreateModeCookie struct { *xgb.Cookie @@ -2631,6 +2905,69 @@ func destroyModeRequest(c *xgb.Conn, Mode Mode) []byte { return buf } +// FreeLeaseCookie is a cookie used only for FreeLease requests. +type FreeLeaseCookie struct { + *xgb.Cookie +} + +// FreeLease sends an unchecked request. +// If an error occurs, it can only be retrieved using xgb.WaitForEvent or xgb.PollForEvent. +func FreeLease(c *xgb.Conn, Lid Lease, Terminate byte) FreeLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'FreeLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(false, false) + c.NewRequest(freeLeaseRequest(c, Lid, Terminate), cookie) + return FreeLeaseCookie{cookie} +} + +// FreeLeaseChecked sends a checked request. +// If an error occurs, it can be retrieved using FreeLeaseCookie.Check. +func FreeLeaseChecked(c *xgb.Conn, Lid Lease, Terminate byte) FreeLeaseCookie { + c.ExtLock.RLock() + defer c.ExtLock.RUnlock() + if _, ok := c.Extensions["RANDR"]; !ok { + panic("Cannot issue request 'FreeLease' using the uninitialized extension 'RANDR'. randr.Init(connObj) must be called first.") + } + cookie := c.NewCookie(true, false) + c.NewRequest(freeLeaseRequest(c, Lid, Terminate), cookie) + return FreeLeaseCookie{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 FreeLeaseCookie) Check() error { + return cook.Cookie.Check() +} + +// freeLeaseRequest writes a FreeLease request to a byte slice for transfer. +func freeLeaseRequest(c *xgb.Conn, Lid Lease, Terminate byte) []byte { + size := 12 + b := 0 + buf := make([]byte, size) + + c.ExtLock.RLock() + buf[b] = c.Extensions["RANDR"] + c.ExtLock.RUnlock() + b += 1 + + buf[b] = 46 // 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(Lid)) + b += 4 + + buf[b] = Terminate + b += 1 + + return buf +} + // GetCrtcGammaCookie is a cookie used only for GetCrtcGamma requests. type GetCrtcGammaCookie struct { *xgb.Cookie -- cgit v1.2.3