diff options
Diffstat (limited to 'nexgb/randr')
| -rw-r--r-- | nexgb/randr/randr.go | 339 | 
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 | 
