aboutsummaryrefslogtreecommitdiff
path: root/nexgb/randr/randr.go
diff options
context:
space:
mode:
Diffstat (limited to 'nexgb/randr/randr.go')
-rw-r--r--nexgb/randr/randr.go339
1 files changed, 338 insertions, 1 deletions
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