diff options
| -rw-r--r-- | nexgb/randr/randr.go | 339 | ||||
| -rw-r--r-- | nexgb/res/res.go | 12 | ||||
| -rw-r--r-- | nexgb/xproto/xproto.go | 14 | 
3 files changed, 356 insertions, 9 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 diff --git a/nexgb/res/res.go b/nexgb/res/res.go index 6b1a807..6e686b6 100644 --- a/nexgb/res/res.go +++ b/nexgb/res/res.go @@ -157,7 +157,7 @@ func ClientIdSpecListBytes(buf []byte, list []ClientIdSpec) int {  type ClientIdValue struct {  	Spec   ClientIdSpec  	Length uint32 -	Value  []uint32 // size: xgb.Pad((int(Length) * 4)) +	Value  []uint32 // size: xgb.Pad(((int(Length) / 4) * 4))  }  // ClientIdValueRead reads a byte slice into a ClientIdValue value. @@ -170,8 +170,8 @@ func ClientIdValueRead(buf []byte, v *ClientIdValue) int {  	v.Length = xgb.Get32(buf[b:])  	b += 4 -	v.Value = make([]uint32, v.Length) -	for i := 0; i < int(v.Length); i++ { +	v.Value = make([]uint32, (int(v.Length) / 4)) +	for i := 0; i < int((int(v.Length) / 4)); i++ {  		v.Value[i] = xgb.Get32(buf[b:])  		b += 4  	} @@ -191,7 +191,7 @@ func ClientIdValueReadList(buf []byte, dest []ClientIdValue) int {  // Bytes writes a ClientIdValue value to a byte slice.  func (v ClientIdValue) Bytes() []byte { -	buf := make([]byte, (12 + xgb.Pad((int(v.Length) * 4)))) +	buf := make([]byte, (12 + xgb.Pad(((int(v.Length) / 4) * 4))))  	b := 0  	{ @@ -203,7 +203,7 @@ func (v ClientIdValue) Bytes() []byte {  	xgb.Put32(buf[b:], v.Length)  	b += 4 -	for i := 0; i < int(v.Length); i++ { +	for i := 0; i < int((int(v.Length) / 4)); i++ {  		xgb.Put32(buf[b:], v.Value[i])  		b += 4  	} @@ -227,7 +227,7 @@ func ClientIdValueListBytes(buf []byte, list []ClientIdValue) int {  func ClientIdValueListSize(list []ClientIdValue) int {  	size := 0  	for _, item := range list { -		size += (12 + xgb.Pad((int(item.Length) * 4))) +		size += (12 + xgb.Pad(((int(item.Length) / 4) * 4)))  	}  	return size  } diff --git a/nexgb/xproto/xproto.go b/nexgb/xproto/xproto.go index 82f893d..fc3bfe0 100644 --- a/nexgb/xproto/xproto.go +++ b/nexgb/xproto/xproto.go @@ -5882,7 +5882,9 @@ type SetupRequest struct {  	AuthorizationProtocolDataLen uint16  	// padding: 2 bytes  	AuthorizationProtocolName string // size: xgb.Pad((int(AuthorizationProtocolNameLen) * 1)) +	// alignment gap to multiple of 4  	AuthorizationProtocolData string // size: xgb.Pad((int(AuthorizationProtocolDataLen) * 1)) +	// alignment gap to multiple of 4  }  // SetupRequestRead reads a byte slice into a SetupRequest value. @@ -5915,6 +5917,8 @@ func SetupRequestRead(buf []byte, v *SetupRequest) int {  		b += int(v.AuthorizationProtocolNameLen)  	} +	b = (b + 3) & ^3 // alignment gap +  	{  		byteString := make([]byte, v.AuthorizationProtocolDataLen)  		copy(byteString[:v.AuthorizationProtocolDataLen], buf[b:]) @@ -5922,6 +5926,8 @@ func SetupRequestRead(buf []byte, v *SetupRequest) int {  		b += int(v.AuthorizationProtocolDataLen)  	} +	b = (b + 3) & ^3 // alignment gap +  	return b  } @@ -5937,7 +5943,7 @@ func SetupRequestReadList(buf []byte, dest []SetupRequest) int {  // Bytes writes a SetupRequest value to a byte slice.  func (v SetupRequest) Bytes() []byte { -	buf := make([]byte, ((12 + xgb.Pad((int(v.AuthorizationProtocolNameLen) * 1))) + xgb.Pad((int(v.AuthorizationProtocolDataLen) * 1)))) +	buf := make([]byte, ((((12 + xgb.Pad((int(v.AuthorizationProtocolNameLen) * 1))) + 4) + xgb.Pad((int(v.AuthorizationProtocolDataLen) * 1))) + 4))  	b := 0  	buf[b] = v.ByteOrder @@ -5962,9 +5968,13 @@ func (v SetupRequest) Bytes() []byte {  	copy(buf[b:], v.AuthorizationProtocolName[:v.AuthorizationProtocolNameLen])  	b += int(v.AuthorizationProtocolNameLen) +	b = (b + 3) & ^3 // alignment gap +  	copy(buf[b:], v.AuthorizationProtocolData[:v.AuthorizationProtocolDataLen])  	b += int(v.AuthorizationProtocolDataLen) +	b = (b + 3) & ^3 // alignment gap +  	return buf[:b]  } @@ -5984,7 +5994,7 @@ func SetupRequestListBytes(buf []byte, list []SetupRequest) int {  func SetupRequestListSize(list []SetupRequest) int {  	size := 0  	for _, item := range list { -		size += ((12 + xgb.Pad((int(item.AuthorizationProtocolNameLen) * 1))) + xgb.Pad((int(item.AuthorizationProtocolDataLen) * 1))) +		size += ((((12 + xgb.Pad((int(item.AuthorizationProtocolNameLen) * 1))) + 4) + xgb.Pad((int(item.AuthorizationProtocolDataLen) * 1))) + 4)  	}  	return size  } | 
